diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 00000000..6fbade27
Binary files /dev/null and b/.DS_Store differ
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..6b1c410d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+# Created by PhpStorm.
+# User: mauricioschmitz
+# Date: 6/5/17
+# Time: 20:59
diff --git a/README.md b/README.md
index 8fb16649..e153cb0d 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,147 @@
+# Descrição do projeto
+Usei o framework Silex para desenvolver a api em conjunto com o ORM Eloquent.
+A api possui autenticação por chave de usuário chamada de `apikey`.
+
+Portanto o Header deve conter os seguintes parametros incluindo o `Content-type` devido a api aceitar apenas entradas e saídas em `json`
+
+```
+Authorization: 356a192b7913b04c54574d18c28d46e6395428ab
+Content-Type: application/json
+```
+
+##Banco de dados
+No banco de dados foi usado MySQL, e também foi implementado controle de versão da base atreavés do liquibase.
+Para fins de teste está disponível o script de criação da base na pasta `resources`.
+
+#ENDPOINTS
+###Lista de todos os recursos
+```
+GET /api/v1/messages
+```
+Resposta:
+```
+[
+ {
+ "id": 4,
+ "user_id": 1,
+ "title": "Title 2",
+ "body": "Body 2",
+ "image_url": "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_116x41dp.png",
+ "source": "Google",
+ "active": 1,
+ "created_at": "2017-07-05 17:38:30",
+ "updated_at": "2017-07-05 17:38:30",
+ "user": {
+ "id": 1,
+ "name": "User 1",
+ "email": "user1@user.com.br"
+ }
+ }
+]
+```
+
+###Criar recurso
+```
+POST /api/v1/message
+```
+Body
+```
+{
+ "title":"Title 2",
+ "body":"Body 2",
+ "image_url":"https:\/\/www.google.com\/images\/branding\/googlelogo\/1x\/googlelogo_color_116x41dp.png",
+ "source":"Google"
+}
+```
+Resposta
+```
+{
+ "title": "Title 2",
+ "body": "Body 2",
+ "image_url": "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_116x41dp.png",
+ "source": "Google",
+ "user_id": 1,
+ "updated_at": "2017-07-07 12:57:00",
+ "created_at": "2017-07-07 12:57:00",
+ "id": 5,
+ "user": {
+ "id": 1,
+ "name": "User 1",
+ "email": "user1@user.com.br"
+ }
+}
+```
+
+###Buscar recurso por id
+```
+GET /api/v1/message/{id}
+```
+
+Resposta
+```
+[
+ {
+ "id": 1,
+ "user_id": 1,
+ "title": "Title 2",
+ "body": "Body 2",
+ "image_url": "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_116x41dp.png",
+ "source": "Google",
+ "active": 1,
+ "created_at": "2017-07-05 17:38:30",
+ "updated_at": "2017-07-05 17:38:30",
+ "user": {
+ "id": 1,
+ "name": "User 1",
+ "email": "user1@user.com.br"
+ }
+ }
+]
+```
+
+###Editar recurso
+```
+PUT /api/v1/message
+```
+Body
+```
+{
+ "title":"Title 2",
+ "body":"Body 2",
+ "image_url":"https:\/\/www.google.com\/images\/branding\/googlelogo\/1x\/googlelogo_color_116x41dp.png",
+ "source":"Google"
+}
+```
+
+Resposta
+```
+{
+ "title": "Title 2",
+ "body": "Body 2",
+ "image_url": "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_116x41dp.png",
+ "source": "Google",
+ "user_id": 1,
+ "updated_at": "2017-07-07 12:57:00",
+ "created_at": "2017-07-07 12:57:00",
+ "id": 5,
+ "user": {
+ "id": 1,
+ "name": "User 1",
+ "email": "user1@user.com.br"
+ }
+}
+```
+
+###Remover recurso
+```
+DELETE /api/v1/message/{id}
+```
+
+ Resposta
+```
+{"success":"Deleted"}
+```
+
# A tarefa
Sua tarefa consiste em desenvolver uma API RESTful para manipular um determinado recurso. Deverá ser utilizado o framework Silex.
diff --git a/bootstrap.php b/bootstrap.php
new file mode 100755
index 00000000..4f9362e4
--- /dev/null
+++ b/bootstrap.php
@@ -0,0 +1,25 @@
+addConnection([
+ "driver" => $app['driver'],
+ "host" => $app['host'],
+ "database" => $app['database'],
+ "username" => $app['username'],
+ "password" => $app['password'],
+ "charset" => $app['charset'],
+ "collation" => $app['collation'],
+]);
+
+$capsule->bootEloquent();
+
+?>
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 00000000..3ebb8840
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,21 @@
+{
+ "name": "mauriciofastman/teste",
+ "description": "Teste para vaga programador PHP Serasa",
+ "license": "MIT",
+ "type": "project",
+ "require": {
+ "php": ">=5.5.9",
+ "silex/silex": "~2.0",
+ "illuminate/database": "5.2"
+ },
+ "autoload": {
+ "psr-0": { "App\\": "src/" },
+ "psr-4": {"App\\": "src/"}
+ },
+ "scripts": {
+ "run": [
+ "echo 'Started web server on http://localhost:8888'",
+ "php -S localhost:8888 -t web"
+ ]
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 00000000..c67d33f6
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,1084 @@
+{
+ "_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"
+ ],
+ "content-hash": "404e13cb18c0d4cbc1434e9b9a7aff68",
+ "packages": [
+ {
+ "name": "doctrine/inflector",
+ "version": "v1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/inflector.git",
+ "reference": "90b2128806bfde671b6952ab8bea493942c1fdae"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae",
+ "reference": "90b2128806bfde671b6952ab8bea493942c1fdae",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Doctrine\\Common\\Inflector\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "Common String Manipulations with regard to casing and singular/plural rules.",
+ "homepage": "http://www.doctrine-project.org",
+ "keywords": [
+ "inflection",
+ "pluralize",
+ "singularize",
+ "string"
+ ],
+ "time": "2015-11-06T14:35:42+00:00"
+ },
+ {
+ "name": "illuminate/container",
+ "version": "v5.2.45",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/container.git",
+ "reference": "5139cebc8293b6820b91aef6f4b4e18bde33c9b2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/container/zipball/5139cebc8293b6820b91aef6f4b4e18bde33c9b2",
+ "reference": "5139cebc8293b6820b91aef6f4b4e18bde33c9b2",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/contracts": "5.2.*",
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Container\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "The Illuminate Container package.",
+ "homepage": "http://laravel.com",
+ "time": "2016-08-01T13:49:14+00:00"
+ },
+ {
+ "name": "illuminate/contracts",
+ "version": "v5.2.45",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/contracts.git",
+ "reference": "22bde7b048a33c702d9737fc1446234fff9b1363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/contracts/zipball/22bde7b048a33c702d9737fc1446234fff9b1363",
+ "reference": "22bde7b048a33c702d9737fc1446234fff9b1363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Contracts\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "The Illuminate Contracts package.",
+ "homepage": "http://laravel.com",
+ "time": "2016-08-08T11:46:08+00:00"
+ },
+ {
+ "name": "illuminate/database",
+ "version": "v5.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/database.git",
+ "reference": "af0e0d1cb4e4abf18eae6400c4ed5685a69a9e41"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/database/zipball/af0e0d1cb4e4abf18eae6400c4ed5685a69a9e41",
+ "reference": "af0e0d1cb4e4abf18eae6400c4ed5685a69a9e41",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/container": "5.2.*",
+ "illuminate/contracts": "5.2.*",
+ "illuminate/support": "5.2.*",
+ "nesbot/carbon": "~1.20",
+ "php": ">=5.5.9"
+ },
+ "suggest": {
+ "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).",
+ "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).",
+ "illuminate/console": "Required to use the database commands (5.2.*).",
+ "illuminate/events": "Required to use the observers with Eloquent (5.2.*).",
+ "illuminate/filesystem": "Required to use the migrations (5.2.*).",
+ "illuminate/pagination": "Required to paginate the result set (5.2.*)."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Database\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylorotwell@gmail.com"
+ }
+ ],
+ "description": "The Illuminate Database package.",
+ "homepage": "http://laravel.com",
+ "keywords": [
+ "database",
+ "laravel",
+ "orm",
+ "sql"
+ ],
+ "time": "2015-12-20T16:11:11+00:00"
+ },
+ {
+ "name": "illuminate/support",
+ "version": "v5.2.45",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/support.git",
+ "reference": "510230ab62a7d85dc70203f4fdca6fb71a19e08a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/support/zipball/510230ab62a7d85dc70203f4fdca6fb71a19e08a",
+ "reference": "510230ab62a7d85dc70203f4fdca6fb71a19e08a",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/inflector": "~1.0",
+ "ext-mbstring": "*",
+ "illuminate/contracts": "5.2.*",
+ "paragonie/random_compat": "~1.4",
+ "php": ">=5.5.9"
+ },
+ "replace": {
+ "tightenco/collect": "self.version"
+ },
+ "suggest": {
+ "illuminate/filesystem": "Required to use the composer class (5.2.*).",
+ "jeremeamia/superclosure": "Required to be able to serialize closures (~2.2).",
+ "symfony/polyfill-php56": "Required to use the hash_equals function on PHP 5.5 (~1.0).",
+ "symfony/process": "Required to use the composer class (2.8.*|3.0.*).",
+ "symfony/var-dumper": "Improves the dd function (2.8.*|3.0.*)."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Support\\": ""
+ },
+ "files": [
+ "helpers.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "The Illuminate Support package.",
+ "homepage": "http://laravel.com",
+ "time": "2016-08-05T14:49:58+00:00"
+ },
+ {
+ "name": "nesbot/carbon",
+ "version": "1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/briannesbitt/Carbon.git",
+ "reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc",
+ "reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "symfony/translation": "~2.6 || ~3.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "~2",
+ "phpunit/phpunit": "~4.0 || ~5.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.23-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Carbon\\": "src/Carbon/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Brian Nesbitt",
+ "email": "brian@nesbot.com",
+ "homepage": "http://nesbot.com"
+ }
+ ],
+ "description": "A simple API extension for DateTime.",
+ "homepage": "http://carbon.nesbot.com",
+ "keywords": [
+ "date",
+ "datetime",
+ "time"
+ ],
+ "time": "2017-01-16T07:55:07+00:00"
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v1.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "965cdeb01fdcab7653253aa81d40441d261f1e66"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/965cdeb01fdcab7653253aa81d40441d261f1e66",
+ "reference": "965cdeb01fdcab7653253aa81d40441d261f1e66",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "lib/random.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "pseudorandom",
+ "random"
+ ],
+ "time": "2017-03-13T16:22:52+00:00"
+ },
+ {
+ "name": "pimple/pimple",
+ "version": "v3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/silexphp/Pimple.git",
+ "reference": "279b56046fb368deacf77e2f8f3bdcea45cc367a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/silexphp/Pimple/zipball/279b56046fb368deacf77e2f8f3bdcea45cc367a",
+ "reference": "279b56046fb368deacf77e2f8f3bdcea45cc367a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "psr/container": "^1.0"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^3.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.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": "2017-07-03T14:06:46+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "time": "2017-02-14T16:28:37+00:00"
+ },
+ {
+ "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-10T12:19:37+00:00"
+ },
+ {
+ "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-03T15:21:42+00:00"
+ },
+ {
+ "name": "symfony/debug",
+ "version": "v3.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/debug.git",
+ "reference": "bcfd02728d9b776e5c2195a4750c813fe440402f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/bcfd02728d9b776e5c2195a4750c813fe440402f",
+ "reference": "bcfd02728d9b776e5c2195a4750c813fe440402f",
+ "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-06T14:51:55+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v3.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "67535f1e3fd662bdc68d7ba317c93eecd973617e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/67535f1e3fd662bdc68d7ba317c93eecd973617e",
+ "reference": "67535f1e3fd662bdc68d7ba317c93eecd973617e",
+ "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-09T14:53:08+00:00"
+ },
+ {
+ "name": "symfony/http-foundation",
+ "version": "v3.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "f347a5f561b03db95ed666959db42bbbf429b7e5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f347a5f561b03db95ed666959db42bbbf429b7e5",
+ "reference": "f347a5f561b03db95ed666959db42bbbf429b7e5",
+ "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-24T09:29:48+00:00"
+ },
+ {
+ "name": "symfony/http-kernel",
+ "version": "v3.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-kernel.git",
+ "reference": "98e6c9197e2d4eb42a059eb69ef4168a6b3c4891"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/98e6c9197e2d4eb42a059eb69ef4168a6b3c4891",
+ "reference": "98e6c9197e2d4eb42a059eb69ef4168a6b3c4891",
+ "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-07-04T06:02:59+00:00"
+ },
+ {
+ "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-09T14:24:12+00:00"
+ },
+ {
+ "name": "symfony/routing",
+ "version": "v3.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "dc70bbd0ca7b19259f63cdacc8af370bc32a4728"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/dc70bbd0ca7b19259f63cdacc8af370bc32a4728",
+ "reference": "dc70bbd0ca7b19259f63cdacc8af370bc32a4728",
+ "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-24T09:29:48+00:00"
+ },
+ {
+ "name": "symfony/translation",
+ "version": "v3.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/translation.git",
+ "reference": "35dd5fb003c90e8bd4d8cabdf94bf9c96d06fdc3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/35dd5fb003c90e8bd4d8cabdf94bf9c96d06fdc3",
+ "reference": "35dd5fb003c90e8bd4d8cabdf94bf9c96d06fdc3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/config": "<2.8",
+ "symfony/yaml": "<3.3"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/intl": "^2.8.18|^3.2.5",
+ "symfony/yaml": "~3.3"
+ },
+ "suggest": {
+ "psr/log": "To use logging capability in translator",
+ "symfony/config": "",
+ "symfony/yaml": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Translation\\": ""
+ },
+ "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 Translation Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-06-24T16:45:30+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=5.5.9"
+ },
+ "platform-dev": []
+}
diff --git a/config/dev.php b/config/dev.php
new file mode 100644
index 00000000..383afa0e
--- /dev/null
+++ b/config/dev.php
@@ -0,0 +1,24 @@
+register(new MonologServiceProvider(), array(
+ 'monolog.logfile' => __DIR__.'/../var/logs/silex_dev.log',
+));
+
+$app->register(new WebProfilerServiceProvider(), array(
+ 'profiler.cache_dir' => __DIR__.'/../var/cache/profiler',
+));
diff --git a/config/production.php b/config/production.php
new file mode 100644
index 00000000..e3f433de
--- /dev/null
+++ b/config/production.php
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/liquibase/changelog/db.changelog-master.xml b/liquibase/changelog/db.changelog-master.xml
new file mode 100644
index 00000000..5ed30a09
--- /dev/null
+++ b/liquibase/changelog/db.changelog-master.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/liquibase/lib/mysql-connector-java-5.1.36.jar b/liquibase/lib/mysql-connector-java-5.1.36.jar
new file mode 100755
index 00000000..a839c3dd
Binary files /dev/null and b/liquibase/lib/mysql-connector-java-5.1.36.jar differ
diff --git a/liquibase/liquibase.bat b/liquibase/liquibase.bat
new file mode 100755
index 00000000..523443c2
--- /dev/null
+++ b/liquibase/liquibase.bat
@@ -0,0 +1,26 @@
+@echo off
+if "%OS%" == "Windows_NT" setlocal
+
+setlocal enabledelayedexpansion
+
+rem %~dp0 is expanded pathname of the current script under NT
+set LIQUIBASE_HOME="%~dp0"
+
+set CP=.
+for /R %LIQUIBASE_HOME% %%f in (liquibase*.jar) do set CP=!CP!;%%f
+for /R %LIQUIBASE_HOME%\lib %%f in (*.jar) do set CP=!CP!;%%f
+
+rem get command line args into a variable
+set CMD_LINE_ARGS=%1
+if ""%1""=="""" goto done
+shift
+:setup
+if ""%1""=="""" goto done
+set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
+shift
+goto setup
+:done
+
+IF NOT DEFINED JAVA_OPTS set JAVA_OPTS=
+
+java -cp "%CP%" %JAVA_OPTS% liquibase.integration.commandline.Main %CMD_LINE_ARGS%
diff --git a/liquibase/liquibase.jar b/liquibase/liquibase.jar
new file mode 100755
index 00000000..2910be08
Binary files /dev/null and b/liquibase/liquibase.jar differ
diff --git a/liquibase/liquibase.properties b/liquibase/liquibase.properties
new file mode 100755
index 00000000..4d5eb85e
--- /dev/null
+++ b/liquibase/liquibase.properties
@@ -0,0 +1,12 @@
+#liquibase.properties
+driver: com.mysql.jdbc.Driver
+classpath: lib/mysql-connector-java-5.1.36.jar
+changeLogFile: changelog/db.changelog-master.xml
+
+#Localhost
+url: jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=UTF-8
+username: localhost
+password: localhost
+defaultSchemaName: teste
+
+outputFile: script.sql
\ No newline at end of file
diff --git a/liquibase/script.sql b/liquibase/script.sql
new file mode 100644
index 00000000..f6ef4861
--- /dev/null
+++ b/liquibase/script.sql
@@ -0,0 +1,52 @@
+--
+-- Table structure for table `messages`
+--
+
+DROP TABLE IF EXISTS `messages`;
+CREATE TABLE `messages` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `user_id` int(10) unsigned NOT NULL,
+ `title` varchar(255) NOT NULL,
+ `body` text NOT NULL,
+ `image_url` varchar(255) DEFAULT NULL,
+ `source` varchar(255) DEFAULT NULL,
+ `active` tinyint(3) unsigned NOT NULL DEFAULT '1',
+ `created_at` timestamp NULL DEFAULT NULL,
+ `updated_at` timestamp NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `fk_message$use$user_id_idx` (`user_id`),
+ CONSTRAINT `fk_message$use$user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Dumping data for table `messages`
+--
+
+LOCK TABLES `messages` WRITE;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `users`
+--
+
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` varchar(255) NOT NULL,
+ `email` varchar(255) NOT NULL,
+ `password` varchar(255) NOT NULL,
+ `apikey` varchar(100) NOT NULL,
+ `active` tinyint(3) unsigned NOT NULL DEFAULT '1',
+ `created_at` timestamp NULL DEFAULT NULL,
+ `updated_at` timestamp NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `users_email_unique` (`email`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
+
+--
+-- Dumping data for table `users`
+--
+
+LOCK TABLES `users` WRITE;
+INSERT IGNORE INTO `users` VALUES (1,'User 1','user1@user.com.br','$2y$10$81JksrkLkrRSTEDoGlM.9uMrXgQT4eKmLdtytnUlJphqKfG6WZGOW','356a192b7913b04c54574d18c28d46e6395428ab',1,NULL,NULL),(2,'User 2','user2@user.com.br','$2y$10$81JksrkLkrRSTEDoGlM.9uMrXgQT4eKmLdtytnUlJphqKfG6WZGOW','da4b9237bacccdf19c0760cab7aec4a8359010b0',1,NULL,NULL),(3,'User 3','user3@user.com.br','$2y$10$81JksrkLkrRSTEDoGlM.9uMrXgQT4eKmLdtytnUlJphqKfG6WZGOW','77de68daecd823babbb58edb1c8e14d7106e83bb',1,NULL,NULL),(4,'User 4','user4@user.com.br','$2y$10$81JksrkLkrRSTEDoGlM.9uMrXgQT4eKmLdtytnUlJphqKfG6WZGOW','1b6453892473a467d07372d45eb05abc2031647a',1,NULL,NULL);
+UNLOCK TABLES;
diff --git a/resources/db.sql b/resources/db.sql
new file mode 100644
index 00000000..9f5064a3
--- /dev/null
+++ b/resources/db.sql
@@ -0,0 +1,52 @@
+--
+-- Table structure for table `messages`
+--
+
+DROP TABLE IF EXISTS `messages`;
+CREATE TABLE `messages` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `user_id` int(10) unsigned NOT NULL,
+ `title` varchar(255) NOT NULL,
+ `body` text NOT NULL,
+ `image_url` varchar(255) DEFAULT NULL,
+ `source` varchar(255) DEFAULT NULL,
+ `active` tinyint(3) unsigned NOT NULL DEFAULT ''1'',
+ `created_at` timestamp NULL DEFAULT NULL,
+ `updated_at` timestamp NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `fk_message$use$user_id_idx` (`user_id`),
+ CONSTRAINT `fk_message$use$user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Dumping data for table `messages`
+--
+
+LOCK TABLES `messages` WRITE;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `users`
+--
+
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` varchar(255) NOT NULL,
+ `email` varchar(255) NOT NULL,
+ `password` varchar(255) NOT NULL,
+ `apikey` varchar(100) NOT NULL,
+ `active` tinyint(3) unsigned NOT NULL DEFAULT ''1'',
+ `created_at` timestamp NULL DEFAULT NULL,
+ `updated_at` timestamp NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `users_email_unique` (`email`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
+
+--
+-- Dumping data for table `users`
+--
+
+LOCK TABLES `users` WRITE;
+INSERT IGNORE INTO `users` VALUES (1,''User 1'',''user1@user.com.br'',''$2y$10$81JksrkLkrRSTEDoGlM.9uMrXgQT4eKmLdtytnUlJphqKfG6WZGOW'',''356a192b7913b04c54574d18c28d46e6395428ab'',1,NULL,NULL),(2,''User 2'',''user2@user.com.br'',''$2y$10$81JksrkLkrRSTEDoGlM.9uMrXgQT4eKmLdtytnUlJphqKfG6WZGOW'',''da4b9237bacccdf19c0760cab7aec4a8359010b0'',1,NULL,NULL),(3,''User 3'',''user3@user.com.br'',''$2y$10$81JksrkLkrRSTEDoGlM.9uMrXgQT4eKmLdtytnUlJphqKfG6WZGOW'',''77de68daecd823babbb58edb1c8e14d7106e83bb'',1,NULL,NULL),(4,''User 4'',''user4@user.com.br'',''$2y$10$81JksrkLkrRSTEDoGlM.9uMrXgQT4eKmLdtytnUlJphqKfG6WZGOW'',''1b6453892473a467d07372d45eb05abc2031647a'',1,NULL,NULL);
+UNLOCK TABLES;
diff --git a/src/Middleware/Authentication.php b/src/Middleware/Authentication.php
new file mode 100755
index 00000000..cb7834e2
--- /dev/null
+++ b/src/Middleware/Authentication.php
@@ -0,0 +1,29 @@
+headers->get("Authorization");
+ $apikey = substr($auth, strpos($auth, ' '));
+ $apikey = trim($apikey);
+
+ $user = new User();
+ $check = $user->authenticate($apikey);
+ if(!$check){
+ $app->abort(401);
+ }
+ else $request->attributes->set('user_id',$check);
+
+ }
+}
+?>
\ No newline at end of file
diff --git a/src/Middleware/Logging.php b/src/Middleware/Logging.php
new file mode 100755
index 00000000..c875fdbc
--- /dev/null
+++ b/src/Middleware/Logging.php
@@ -0,0 +1,25 @@
+getMethod() . "--" . $request->getUri());
+}
+
+
+
+
+}
+
+
+
+
+?>
\ No newline at end of file
diff --git a/src/Models/Message.php b/src/Models/Message.php
new file mode 100755
index 00000000..5c20801f
--- /dev/null
+++ b/src/Models/Message.php
@@ -0,0 +1,29 @@
+belongsTo(User::class)->select(array('id', 'name', 'email'));
+ }
+}
+
+?>
+
+
diff --git a/src/Models/User.php b/src/Models/User.php
new file mode 100755
index 00000000..61101c55
--- /dev/null
+++ b/src/Models/User.php
@@ -0,0 +1,29 @@
+take(1)->get();
+
+
+ if(isset($user[0])){
+ $this->details = $user[0];
+ return $this->details->id;
+
+ }
+ return false;
+ }
+
+ public function message()
+ {
+ return $this->hasMany(Message::class);
+ }
+}
\ No newline at end of file
diff --git a/src/app.php b/src/app.php
new file mode 100644
index 00000000..f68f176a
--- /dev/null
+++ b/src/app.php
@@ -0,0 +1,16 @@
+register(new ServiceControllerServiceProvider());
+$app->register(new HttpFragmentServiceProvider());
+
+return $app;
diff --git a/src/controllers.php b/src/controllers.php
new file mode 100644
index 00000000..f002df11
--- /dev/null
+++ b/src/controllers.php
@@ -0,0 +1,106 @@
+before(function($request, $app) use ($app) {
+ //Verify if content type is json
+ if (strpos($request->headers->get('Content-Type'), 'application/json')!==0) {
+ return $app->json(array('error' => 'Invalid Header Content-Type'), 201);
+ }else{
+ $data = json_decode($request->getContent(), true);
+ $request->request->replace(is_array($data) ? $data : array());
+ }
+ //Log usage
+ AppLogging::log($request, $app);
+ //Authenticate
+ AppAuth::authenticate($request, $app);
+});
+
+//Group api routes
+$app->mount('/api/v1', function ($api) use ($app){
+ //List of messages from user request
+ $api->get('/messages', function (Request $request) use ($app) {
+ //find messages from authenticated user
+ $message = Message::where('user_id', $request->attributes->get('user_id'))->with('user')->get();
+ //return a json result
+ return $app->json($message, 201);
+ });
+
+ //Find one message by id
+ $api->get('/message/{id}', function (Request $request, $id) use ($app) {
+ //find message from authenticated user and request id
+ $message = Message::where('user_id', $request->attributes->get('user_id'))->where('id', $id)->with('user')->get();
+ //return a json result
+ return $app->json($message, 201);
+ });
+
+ //Create a message from user request
+ $api->post('/message', function (Request $request) use ($app) {
+ try{
+ $user = User::where('id', $request->attributes->get('user_id'))->first(['id', 'name', 'email']);
+ $message = new Message($request->request->all());
+ $message->user()->associate($user);
+ $message->save();
+ }catch (Exception $ex){
+ return $app->json(array('error' => 'Invalid data sent'), 201);
+ }
+ unset($message->user->password);
+ unset($message->user->apikey);
+ unset($message->user->active);
+ unset($message->user->updat);
+ return $app->json($message, 201);
+ });
+
+ //Update a message from user request
+ $api->put('/message', function (Request $request) use ($app) {
+ try{
+ $user = User::findOrNew($request->attributes->get('user_id'));
+ $message = Message::where('user_id', $request->attributes->get('user_id'))->where('id', $request->request->get('id'))->first();
+ if(!is_null($message)) {
+ $message->update($request->request->all());
+ }else{
+ return $app->json(array('error' => 'Message not found'), 201);
+ }
+ }catch (Exception $ex){
+ return $app->json(array('error' => 'Invalid data sent'), 201);
+ }
+ return $app->json($message, 201);
+ });
+
+ //Delete one message by id
+ $api->delete('/message/{id}', function (Request $request, $id) use ($app) {
+ //find message from authenticated user and request id
+ $message = Message::where('user_id', $request->attributes->get('user_id'))->where('id', $id)->first();
+ if(!is_null($message)){
+ $message->delete();
+ return $app->json(array('success' => 'Deleted'), 201);
+ }else{
+ return $app->json(array('error' => 'Message not found'), 201);
+ }
+
+ });
+});
+
+
+$app->error(function (\Exception $e, Request $request, $code) use ($app) {
+ if ($app['debug']) {
+ return;
+ }
+
+ return $app->json(array('error' => 'An error ocurred, please check the API documentation'), $code);
+});
diff --git a/var/cache/.gitignore b/var/cache/.gitignore
new file mode 100644
index 00000000..d6b7ef32
--- /dev/null
+++ b/var/cache/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/var/logs/.gitignore b/var/logs/.gitignore
new file mode 100644
index 00000000..d6b7ef32
--- /dev/null
+++ b/var/logs/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/vendor/autoload.php b/vendor/autoload.php
new file mode 100644
index 00000000..e604b0d4
--- /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;
+ private $missingClasses = array();
+ private $apcuPrefix;
+
+ 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;
+ }
+
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
+ /**
+ * 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)
+ {
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ return false;
+ }
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if (false === $file && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
+ // Remember that this class does not exist.
+ $this->missingClasses[$class] = true;
+ }
+
+ return $file;
+ }
+
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath.'\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ $length = $this->prefixLengthsPsr4[$first][$search];
+ 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;
+ }
+
+ return false;
+ }
+}
+
+/**
+ * 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..f27399a0
--- /dev/null
+++ b/vendor/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) 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',
+ '5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
+ '72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php',
+);
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
new file mode 100644
index 00000000..bde2d5b0
--- /dev/null
+++ b/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,12 @@
+ array($vendorDir . '/pimple/pimple/src'),
+ 'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib'),
+ 'App\\' => array($baseDir . '/src'),
+);
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
new file mode 100644
index 00000000..b7994a60
--- /dev/null
+++ b/vendor/composer/autoload_psr4.php
@@ -0,0 +1,25 @@
+ array($vendorDir . '/symfony/polyfill-mbstring'),
+ 'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
+ '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'),
+ 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
+ 'Illuminate\\Support\\' => array($vendorDir . '/illuminate/support'),
+ 'Illuminate\\Database\\' => array($vendorDir . '/illuminate/database'),
+ 'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'),
+ 'Illuminate\\Container\\' => array($vendorDir . '/illuminate/container'),
+ 'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'),
+ 'App\\' => array($baseDir . '/src'),
+);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
new file mode 100644
index 00000000..da95250c
--- /dev/null
+++ b/vendor/composer/autoload_real.php
@@ -0,0 +1,70 @@
+= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
+ if ($useStaticLoader) {
+ require_once __DIR__ . '/autoload_static.php';
+
+ call_user_func(\Composer\Autoload\ComposerStaticInit084732aa7bb44f94fa90c9daf4ed30fb::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\ComposerStaticInit084732aa7bb44f94fa90c9daf4ed30fb::$files;
+ } else {
+ $includeFiles = require __DIR__ . '/autoload_files.php';
+ }
+ foreach ($includeFiles as $fileIdentifier => $file) {
+ composerRequire084732aa7bb44f94fa90c9daf4ed30fb($fileIdentifier, $file);
+ }
+
+ return $loader;
+ }
+}
+
+function composerRequire084732aa7bb44f94fa90c9daf4ed30fb($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..e825b43b
--- /dev/null
+++ b/vendor/composer/autoload_static.php
@@ -0,0 +1,149 @@
+ __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
+ '5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
+ '72579e7bd17821bb1321b87411366eae' => __DIR__ . '/..' . '/illuminate/support/helpers.php',
+ );
+
+ public static $prefixLengthsPsr4 = array (
+ 'S' =>
+ array (
+ 'Symfony\\Polyfill\\Mbstring\\' => 26,
+ 'Symfony\\Component\\Translation\\' => 30,
+ '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,
+ 'Psr\\Container\\' => 14,
+ ),
+ 'I' =>
+ array (
+ 'Illuminate\\Support\\' => 19,
+ 'Illuminate\\Database\\' => 20,
+ 'Illuminate\\Contracts\\' => 21,
+ 'Illuminate\\Container\\' => 21,
+ ),
+ 'C' =>
+ array (
+ 'Carbon\\' => 7,
+ ),
+ 'A' =>
+ array (
+ 'App\\' => 4,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'Symfony\\Polyfill\\Mbstring\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
+ ),
+ 'Symfony\\Component\\Translation\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/translation',
+ ),
+ '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',
+ ),
+ 'Psr\\Container\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/psr/container/src',
+ ),
+ 'Illuminate\\Support\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/illuminate/support',
+ ),
+ 'Illuminate\\Database\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/illuminate/database',
+ ),
+ 'Illuminate\\Contracts\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/illuminate/contracts',
+ ),
+ 'Illuminate\\Container\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/illuminate/container',
+ ),
+ 'Carbon\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon',
+ ),
+ 'App\\' =>
+ array (
+ 0 => __DIR__ . '/../..' . '/src',
+ ),
+ );
+
+ public static $prefixesPsr0 = array (
+ 'P' =>
+ array (
+ 'Pimple' =>
+ array (
+ 0 => __DIR__ . '/..' . '/pimple/pimple/src',
+ ),
+ ),
+ 'D' =>
+ array (
+ 'Doctrine\\Common\\Inflector\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/doctrine/inflector/lib',
+ ),
+ ),
+ 'A' =>
+ array (
+ 'App\\' =>
+ array (
+ 0 => __DIR__ . '/../..' . '/src',
+ ),
+ ),
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInit084732aa7bb44f94fa90c9daf4ed30fb::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit084732aa7bb44f94fa90c9daf4ed30fb::$prefixDirsPsr4;
+ $loader->prefixesPsr0 = ComposerStaticInit084732aa7bb44f94fa90c9daf4ed30fb::$prefixesPsr0;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
new file mode 100644
index 00000000..cf47c33b
--- /dev/null
+++ b/vendor/composer/installed.json
@@ -0,0 +1,1102 @@
+[
+ {
+ "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-09T14:24:12+00:00",
+ "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/translation",
+ "version": "v3.3.3",
+ "version_normalized": "3.3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/translation.git",
+ "reference": "35dd5fb003c90e8bd4d8cabdf94bf9c96d06fdc3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/35dd5fb003c90e8bd4d8cabdf94bf9c96d06fdc3",
+ "reference": "35dd5fb003c90e8bd4d8cabdf94bf9c96d06fdc3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/config": "<2.8",
+ "symfony/yaml": "<3.3"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/intl": "^2.8.18|^3.2.5",
+ "symfony/yaml": "~3.3"
+ },
+ "suggest": {
+ "psr/log": "To use logging capability in translator",
+ "symfony/config": "",
+ "symfony/yaml": ""
+ },
+ "time": "2017-06-24T16:45:30+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Translation\\": ""
+ },
+ "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 Translation Component",
+ "homepage": "https://symfony.com"
+ },
+ {
+ "name": "nesbot/carbon",
+ "version": "1.22.1",
+ "version_normalized": "1.22.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/briannesbitt/Carbon.git",
+ "reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc",
+ "reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "symfony/translation": "~2.6 || ~3.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "~2",
+ "phpunit/phpunit": "~4.0 || ~5.0"
+ },
+ "time": "2017-01-16T07:55:07+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.23-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Carbon\\": "src/Carbon/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Brian Nesbitt",
+ "email": "brian@nesbot.com",
+ "homepage": "http://nesbot.com"
+ }
+ ],
+ "description": "A simple API extension for DateTime.",
+ "homepage": "http://carbon.nesbot.com",
+ "keywords": [
+ "date",
+ "datetime",
+ "time"
+ ]
+ },
+ {
+ "name": "doctrine/inflector",
+ "version": "v1.1.0",
+ "version_normalized": "1.1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/inflector.git",
+ "reference": "90b2128806bfde671b6952ab8bea493942c1fdae"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae",
+ "reference": "90b2128806bfde671b6952ab8bea493942c1fdae",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*"
+ },
+ "time": "2015-11-06T14:35:42+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Doctrine\\Common\\Inflector\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "Common String Manipulations with regard to casing and singular/plural rules.",
+ "homepage": "http://www.doctrine-project.org",
+ "keywords": [
+ "inflection",
+ "pluralize",
+ "singularize",
+ "string"
+ ]
+ },
+ {
+ "name": "illuminate/contracts",
+ "version": "v5.2.45",
+ "version_normalized": "5.2.45.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/contracts.git",
+ "reference": "22bde7b048a33c702d9737fc1446234fff9b1363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/contracts/zipball/22bde7b048a33c702d9737fc1446234fff9b1363",
+ "reference": "22bde7b048a33c702d9737fc1446234fff9b1363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "time": "2016-08-08T11:46:08+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Contracts\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "The Illuminate Contracts package.",
+ "homepage": "http://laravel.com"
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v1.4.2",
+ "version_normalized": "1.4.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "965cdeb01fdcab7653253aa81d40441d261f1e66"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/965cdeb01fdcab7653253aa81d40441d261f1e66",
+ "reference": "965cdeb01fdcab7653253aa81d40441d261f1e66",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "time": "2017-03-13T16:22:52+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "files": [
+ "lib/random.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "pseudorandom",
+ "random"
+ ]
+ },
+ {
+ "name": "illuminate/support",
+ "version": "v5.2.45",
+ "version_normalized": "5.2.45.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/support.git",
+ "reference": "510230ab62a7d85dc70203f4fdca6fb71a19e08a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/support/zipball/510230ab62a7d85dc70203f4fdca6fb71a19e08a",
+ "reference": "510230ab62a7d85dc70203f4fdca6fb71a19e08a",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/inflector": "~1.0",
+ "ext-mbstring": "*",
+ "illuminate/contracts": "5.2.*",
+ "paragonie/random_compat": "~1.4",
+ "php": ">=5.5.9"
+ },
+ "replace": {
+ "tightenco/collect": "self.version"
+ },
+ "suggest": {
+ "illuminate/filesystem": "Required to use the composer class (5.2.*).",
+ "jeremeamia/superclosure": "Required to be able to serialize closures (~2.2).",
+ "symfony/polyfill-php56": "Required to use the hash_equals function on PHP 5.5 (~1.0).",
+ "symfony/process": "Required to use the composer class (2.8.*|3.0.*).",
+ "symfony/var-dumper": "Improves the dd function (2.8.*|3.0.*)."
+ },
+ "time": "2016-08-05T14:49:58+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Support\\": ""
+ },
+ "files": [
+ "helpers.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "The Illuminate Support package.",
+ "homepage": "http://laravel.com"
+ },
+ {
+ "name": "illuminate/container",
+ "version": "v5.2.45",
+ "version_normalized": "5.2.45.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/container.git",
+ "reference": "5139cebc8293b6820b91aef6f4b4e18bde33c9b2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/container/zipball/5139cebc8293b6820b91aef6f4b4e18bde33c9b2",
+ "reference": "5139cebc8293b6820b91aef6f4b4e18bde33c9b2",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/contracts": "5.2.*",
+ "php": ">=5.5.9"
+ },
+ "time": "2016-08-01T13:49:14+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Container\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "The Illuminate Container package.",
+ "homepage": "http://laravel.com"
+ },
+ {
+ "name": "illuminate/database",
+ "version": "v5.2.0",
+ "version_normalized": "5.2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/database.git",
+ "reference": "af0e0d1cb4e4abf18eae6400c4ed5685a69a9e41"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/database/zipball/af0e0d1cb4e4abf18eae6400c4ed5685a69a9e41",
+ "reference": "af0e0d1cb4e4abf18eae6400c4ed5685a69a9e41",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/container": "5.2.*",
+ "illuminate/contracts": "5.2.*",
+ "illuminate/support": "5.2.*",
+ "nesbot/carbon": "~1.20",
+ "php": ">=5.5.9"
+ },
+ "suggest": {
+ "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).",
+ "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).",
+ "illuminate/console": "Required to use the database commands (5.2.*).",
+ "illuminate/events": "Required to use the observers with Eloquent (5.2.*).",
+ "illuminate/filesystem": "Required to use the migrations (5.2.*).",
+ "illuminate/pagination": "Required to paginate the result set (5.2.*)."
+ },
+ "time": "2015-12-20T16:11:11+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Database\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylorotwell@gmail.com"
+ }
+ ],
+ "description": "The Illuminate Database package.",
+ "homepage": "http://laravel.com",
+ "keywords": [
+ "database",
+ "laravel",
+ "orm",
+ "sql"
+ ]
+ },
+ {
+ "name": "symfony/routing",
+ "version": "v3.3.3",
+ "version_normalized": "3.3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "dc70bbd0ca7b19259f63cdacc8af370bc32a4728"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/dc70bbd0ca7b19259f63cdacc8af370bc32a4728",
+ "reference": "dc70bbd0ca7b19259f63cdacc8af370bc32a4728",
+ "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-24T09:29:48+00:00",
+ "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": "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-10T12:19:37+00:00",
+ "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.3",
+ "version_normalized": "3.3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/debug.git",
+ "reference": "bcfd02728d9b776e5c2195a4750c813fe440402f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/bcfd02728d9b776e5c2195a4750c813fe440402f",
+ "reference": "bcfd02728d9b776e5c2195a4750c813fe440402f",
+ "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-06T14:51:55+00:00",
+ "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-foundation",
+ "version": "v3.3.3",
+ "version_normalized": "3.3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "f347a5f561b03db95ed666959db42bbbf429b7e5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f347a5f561b03db95ed666959db42bbbf429b7e5",
+ "reference": "f347a5f561b03db95ed666959db42bbbf429b7e5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/polyfill-mbstring": "~1.1"
+ },
+ "require-dev": {
+ "symfony/expression-language": "~2.8|~3.0"
+ },
+ "time": "2017-06-24T09:29:48+00:00",
+ "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.3",
+ "version_normalized": "3.3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "67535f1e3fd662bdc68d7ba317c93eecd973617e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/67535f1e3fd662bdc68d7ba317c93eecd973617e",
+ "reference": "67535f1e3fd662bdc68d7ba317c93eecd973617e",
+ "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-09T14:53:08+00:00",
+ "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": "symfony/http-kernel",
+ "version": "v3.3.3",
+ "version_normalized": "3.3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-kernel.git",
+ "reference": "98e6c9197e2d4eb42a059eb69ef4168a6b3c4891"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/98e6c9197e2d4eb42a059eb69ef4168a6b3c4891",
+ "reference": "98e6c9197e2d4eb42a059eb69ef4168a6b3c4891",
+ "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-07-04T06:02:59+00:00",
+ "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": "psr/container",
+ "version": "1.0.0",
+ "version_normalized": "1.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "time": "2017-02-14T16:28:37+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ]
+ },
+ {
+ "name": "pimple/pimple",
+ "version": "v3.1.0",
+ "version_normalized": "3.1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/silexphp/Pimple.git",
+ "reference": "279b56046fb368deacf77e2f8f3bdcea45cc367a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/silexphp/Pimple/zipball/279b56046fb368deacf77e2f8f3bdcea45cc367a",
+ "reference": "279b56046fb368deacf77e2f8f3bdcea45cc367a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "psr/container": "^1.0"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^3.2"
+ },
+ "time": "2017-07-03T14:06:46+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.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-03T15:21:42+00:00",
+ "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/doctrine/inflector/.gitignore b/vendor/doctrine/inflector/.gitignore
new file mode 100644
index 00000000..f2cb7f83
--- /dev/null
+++ b/vendor/doctrine/inflector/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+composer.phar
+phpunit.xml
diff --git a/vendor/doctrine/inflector/.travis.yml b/vendor/doctrine/inflector/.travis.yml
new file mode 100644
index 00000000..9ec68f76
--- /dev/null
+++ b/vendor/doctrine/inflector/.travis.yml
@@ -0,0 +1,21 @@
+language: php
+
+sudo: false
+
+cache:
+ directory:
+ - $HOME/.composer/cache
+
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - hhvm
+
+install:
+ - composer install -n
+
+script:
+ - phpunit
diff --git a/vendor/doctrine/inflector/LICENSE b/vendor/doctrine/inflector/LICENSE
new file mode 100644
index 00000000..8c38cc1b
--- /dev/null
+++ b/vendor/doctrine/inflector/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2006-2015 Doctrine Project
+
+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/doctrine/inflector/README.md b/vendor/doctrine/inflector/README.md
new file mode 100644
index 00000000..acb55a01
--- /dev/null
+++ b/vendor/doctrine/inflector/README.md
@@ -0,0 +1,6 @@
+# Doctrine Inflector
+
+Doctrine Inflector is a small library that can perform string manipulations
+with regard to upper-/lowercase and singular/plural forms of words.
+
+[](https://travis-ci.org/doctrine/inflector)
diff --git a/vendor/doctrine/inflector/composer.json b/vendor/doctrine/inflector/composer.json
new file mode 100644
index 00000000..7e5b2efb
--- /dev/null
+++ b/vendor/doctrine/inflector/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "doctrine/inflector",
+ "type": "library",
+ "description": "Common String Manipulations with regard to casing and singular/plural rules.",
+ "keywords": ["string", "inflection", "singularize", "pluralize"],
+ "homepage": "http://www.doctrine-project.org",
+ "license": "MIT",
+ "authors": [
+ {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
+ {"name": "Roman Borschel", "email": "roman@code-factory.org"},
+ {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
+ {"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
+ {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
+ ],
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*"
+ },
+ "autoload": {
+ "psr-0": { "Doctrine\\Common\\Inflector\\": "lib/" }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ }
+}
diff --git a/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php b/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php
new file mode 100644
index 00000000..a53828ab
--- /dev/null
+++ b/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php
@@ -0,0 +1,482 @@
+.
+ */
+
+namespace Doctrine\Common\Inflector;
+
+/**
+ * Doctrine inflector has static methods for inflecting text.
+ *
+ * The methods in these classes are from several different sources collected
+ * across several different php projects and several different authors. The
+ * original author names and emails are not known.
+ *
+ * Pluralize & Singularize implementation are borrowed from CakePHP with some modifications.
+ *
+ * @link www.doctrine-project.org
+ * @since 1.0
+ * @author Konsta Vesterinen
+ * @author Jonathan H. Wage
+ */
+class Inflector
+{
+ /**
+ * Plural inflector rules.
+ *
+ * @var array
+ */
+ private static $plural = array(
+ 'rules' => array(
+ '/(s)tatus$/i' => '\1\2tatuses',
+ '/(quiz)$/i' => '\1zes',
+ '/^(ox)$/i' => '\1\2en',
+ '/([m|l])ouse$/i' => '\1ice',
+ '/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
+ '/(x|ch|ss|sh)$/i' => '\1es',
+ '/([^aeiouy]|qu)y$/i' => '\1ies',
+ '/(hive)$/i' => '\1s',
+ '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
+ '/sis$/i' => 'ses',
+ '/([ti])um$/i' => '\1a',
+ '/(p)erson$/i' => '\1eople',
+ '/(m)an$/i' => '\1en',
+ '/(c)hild$/i' => '\1hildren',
+ '/(f)oot$/i' => '\1eet',
+ '/(buffal|her|potat|tomat|volcan)o$/i' => '\1\2oes',
+ '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
+ '/us$/i' => 'uses',
+ '/(alias)$/i' => '\1es',
+ '/(analys|ax|cris|test|thes)is$/i' => '\1es',
+ '/s$/' => 's',
+ '/^$/' => '',
+ '/$/' => 's',
+ ),
+ 'uninflected' => array(
+ '.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'people', 'cookie'
+ ),
+ 'irregular' => array(
+ 'atlas' => 'atlases',
+ 'axe' => 'axes',
+ 'beef' => 'beefs',
+ 'brother' => 'brothers',
+ 'cafe' => 'cafes',
+ 'chateau' => 'chateaux',
+ 'child' => 'children',
+ 'cookie' => 'cookies',
+ 'corpus' => 'corpuses',
+ 'cow' => 'cows',
+ 'criterion' => 'criteria',
+ 'curriculum' => 'curricula',
+ 'demo' => 'demos',
+ 'domino' => 'dominoes',
+ 'echo' => 'echoes',
+ 'foot' => 'feet',
+ 'fungus' => 'fungi',
+ 'ganglion' => 'ganglions',
+ 'genie' => 'genies',
+ 'genus' => 'genera',
+ 'graffito' => 'graffiti',
+ 'hippopotamus' => 'hippopotami',
+ 'hoof' => 'hoofs',
+ 'human' => 'humans',
+ 'iris' => 'irises',
+ 'leaf' => 'leaves',
+ 'loaf' => 'loaves',
+ 'man' => 'men',
+ 'medium' => 'media',
+ 'memorandum' => 'memoranda',
+ 'money' => 'monies',
+ 'mongoose' => 'mongooses',
+ 'motto' => 'mottoes',
+ 'move' => 'moves',
+ 'mythos' => 'mythoi',
+ 'niche' => 'niches',
+ 'nucleus' => 'nuclei',
+ 'numen' => 'numina',
+ 'occiput' => 'occiputs',
+ 'octopus' => 'octopuses',
+ 'opus' => 'opuses',
+ 'ox' => 'oxen',
+ 'penis' => 'penises',
+ 'person' => 'people',
+ 'plateau' => 'plateaux',
+ 'runner-up' => 'runners-up',
+ 'sex' => 'sexes',
+ 'soliloquy' => 'soliloquies',
+ 'son-in-law' => 'sons-in-law',
+ 'syllabus' => 'syllabi',
+ 'testis' => 'testes',
+ 'thief' => 'thieves',
+ 'tooth' => 'teeth',
+ 'tornado' => 'tornadoes',
+ 'trilby' => 'trilbys',
+ 'turf' => 'turfs',
+ 'volcano' => 'volcanoes',
+ )
+ );
+
+ /**
+ * Singular inflector rules.
+ *
+ * @var array
+ */
+ private static $singular = array(
+ 'rules' => array(
+ '/(s)tatuses$/i' => '\1\2tatus',
+ '/^(.*)(menu)s$/i' => '\1\2',
+ '/(quiz)zes$/i' => '\\1',
+ '/(matr)ices$/i' => '\1ix',
+ '/(vert|ind)ices$/i' => '\1ex',
+ '/^(ox)en/i' => '\1',
+ '/(alias)(es)*$/i' => '\1',
+ '/(buffal|her|potat|tomat|volcan)oes$/i' => '\1o',
+ '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
+ '/([ftw]ax)es/i' => '\1',
+ '/(analys|ax|cris|test|thes)es$/i' => '\1is',
+ '/(shoe|slave)s$/i' => '\1',
+ '/(o)es$/i' => '\1',
+ '/ouses$/' => 'ouse',
+ '/([^a])uses$/' => '\1us',
+ '/([m|l])ice$/i' => '\1ouse',
+ '/(x|ch|ss|sh)es$/i' => '\1',
+ '/(m)ovies$/i' => '\1\2ovie',
+ '/(s)eries$/i' => '\1\2eries',
+ '/([^aeiouy]|qu)ies$/i' => '\1y',
+ '/([lr])ves$/i' => '\1f',
+ '/(tive)s$/i' => '\1',
+ '/(hive)s$/i' => '\1',
+ '/(drive)s$/i' => '\1',
+ '/([^fo])ves$/i' => '\1fe',
+ '/(^analy)ses$/i' => '\1sis',
+ '/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
+ '/([ti])a$/i' => '\1um',
+ '/(p)eople$/i' => '\1\2erson',
+ '/(m)en$/i' => '\1an',
+ '/(c)hildren$/i' => '\1\2hild',
+ '/(f)eet$/i' => '\1oot',
+ '/(n)ews$/i' => '\1\2ews',
+ '/eaus$/' => 'eau',
+ '/^(.*us)$/' => '\\1',
+ '/s$/i' => '',
+ ),
+ 'uninflected' => array(
+ '.*[nrlm]ese',
+ '.*deer',
+ '.*fish',
+ '.*measles',
+ '.*ois',
+ '.*pox',
+ '.*sheep',
+ '.*ss',
+ ),
+ 'irregular' => array(
+ 'criteria' => 'criterion',
+ 'curves' => 'curve',
+ 'emphases' => 'emphasis',
+ 'foes' => 'foe',
+ 'hoaxes' => 'hoax',
+ 'media' => 'medium',
+ 'neuroses' => 'neurosis',
+ 'waves' => 'wave',
+ 'oases' => 'oasis',
+ )
+ );
+
+ /**
+ * Words that should not be inflected.
+ *
+ * @var array
+ */
+ private static $uninflected = array(
+ 'Amoyese', 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus',
+ 'carp', 'chassis', 'clippers', 'cod', 'coitus', 'Congoese', 'contretemps', 'corps',
+ 'debris', 'diabetes', 'djinn', 'eland', 'elk', 'equipment', 'Faroese', 'flounder',
+ 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
+ 'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings',
+ 'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', '.*?media',
+ 'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese',
+ 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese',
+ 'proceedings', 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors',
+ 'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'staff', 'swine',
+ 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese', 'whiting',
+ 'wildebeest', 'Yengeese'
+ );
+
+ /**
+ * Method cache array.
+ *
+ * @var array
+ */
+ private static $cache = array();
+
+ /**
+ * The initial state of Inflector so reset() works.
+ *
+ * @var array
+ */
+ private static $initialState = array();
+
+ /**
+ * Converts a word into the format for a Doctrine table name. Converts 'ModelName' to 'model_name'.
+ *
+ * @param string $word The word to tableize.
+ *
+ * @return string The tableized word.
+ */
+ public static function tableize($word)
+ {
+ return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $word));
+ }
+
+ /**
+ * Converts a word into the format for a Doctrine class name. Converts 'table_name' to 'TableName'.
+ *
+ * @param string $word The word to classify.
+ *
+ * @return string The classified word.
+ */
+ public static function classify($word)
+ {
+ return str_replace(" ", "", ucwords(strtr($word, "_-", " ")));
+ }
+
+ /**
+ * Camelizes a word. This uses the classify() method and turns the first character to lowercase.
+ *
+ * @param string $word The word to camelize.
+ *
+ * @return string The camelized word.
+ */
+ public static function camelize($word)
+ {
+ return lcfirst(self::classify($word));
+ }
+
+ /**
+ * Uppercases words with configurable delimeters between words.
+ *
+ * Takes a string and capitalizes all of the words, like PHP's built-in
+ * ucwords function. This extends that behavior, however, by allowing the
+ * word delimeters to be configured, rather than only separating on
+ * whitespace.
+ *
+ * Here is an example:
+ *
+ *
+ *
+ *
+ * @param string $string The string to operate on.
+ * @param string $delimiters A list of word separators.
+ *
+ * @return string The string with all delimeter-separated words capitalized.
+ */
+ public static function ucwords($string, $delimiters = " \n\t\r\0\x0B-")
+ {
+ return preg_replace_callback(
+ '/[^' . preg_quote($delimiters, '/') . ']+/',
+ function($matches) {
+ return ucfirst($matches[0]);
+ },
+ $string
+ );
+ }
+
+ /**
+ * Clears Inflectors inflected value caches, and resets the inflection
+ * rules to the initial values.
+ *
+ * @return void
+ */
+ public static function reset()
+ {
+ if (empty(self::$initialState)) {
+ self::$initialState = get_class_vars('Inflector');
+
+ return;
+ }
+
+ foreach (self::$initialState as $key => $val) {
+ if ($key != 'initialState') {
+ self::${$key} = $val;
+ }
+ }
+ }
+
+ /**
+ * Adds custom inflection $rules, of either 'plural' or 'singular' $type.
+ *
+ * ### Usage:
+ *
+ * {{{
+ * Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables'));
+ * Inflector::rules('plural', array(
+ * 'rules' => array('/^(inflect)ors$/i' => '\1ables'),
+ * 'uninflected' => array('dontinflectme'),
+ * 'irregular' => array('red' => 'redlings')
+ * ));
+ * }}}
+ *
+ * @param string $type The type of inflection, either 'plural' or 'singular'
+ * @param array $rules An array of rules to be added.
+ * @param boolean $reset If true, will unset default inflections for all
+ * new rules that are being defined in $rules.
+ *
+ * @return void
+ */
+ public static function rules($type, $rules, $reset = false)
+ {
+ foreach ($rules as $rule => $pattern) {
+ if ( ! is_array($pattern)) {
+ continue;
+ }
+
+ if ($reset) {
+ self::${$type}[$rule] = $pattern;
+ } else {
+ self::${$type}[$rule] = ($rule === 'uninflected')
+ ? array_merge($pattern, self::${$type}[$rule])
+ : $pattern + self::${$type}[$rule];
+ }
+
+ unset($rules[$rule], self::${$type}['cache' . ucfirst($rule)]);
+
+ if (isset(self::${$type}['merged'][$rule])) {
+ unset(self::${$type}['merged'][$rule]);
+ }
+
+ if ($type === 'plural') {
+ self::$cache['pluralize'] = self::$cache['tableize'] = array();
+ } elseif ($type === 'singular') {
+ self::$cache['singularize'] = array();
+ }
+ }
+
+ self::${$type}['rules'] = $rules + self::${$type}['rules'];
+ }
+
+ /**
+ * Returns a word in plural form.
+ *
+ * @param string $word The word in singular form.
+ *
+ * @return string The word in plural form.
+ */
+ public static function pluralize($word)
+ {
+ if (isset(self::$cache['pluralize'][$word])) {
+ return self::$cache['pluralize'][$word];
+ }
+
+ if (!isset(self::$plural['merged']['irregular'])) {
+ self::$plural['merged']['irregular'] = self::$plural['irregular'];
+ }
+
+ if (!isset(self::$plural['merged']['uninflected'])) {
+ self::$plural['merged']['uninflected'] = array_merge(self::$plural['uninflected'], self::$uninflected);
+ }
+
+ if (!isset(self::$plural['cacheUninflected']) || !isset(self::$plural['cacheIrregular'])) {
+ self::$plural['cacheUninflected'] = '(?:' . implode('|', self::$plural['merged']['uninflected']) . ')';
+ self::$plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$plural['merged']['irregular'])) . ')';
+ }
+
+ if (preg_match('/(.*)\\b(' . self::$plural['cacheIrregular'] . ')$/i', $word, $regs)) {
+ self::$cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$plural['merged']['irregular'][strtolower($regs[2])], 1);
+
+ return self::$cache['pluralize'][$word];
+ }
+
+ if (preg_match('/^(' . self::$plural['cacheUninflected'] . ')$/i', $word, $regs)) {
+ self::$cache['pluralize'][$word] = $word;
+
+ return $word;
+ }
+
+ foreach (self::$plural['rules'] as $rule => $replacement) {
+ if (preg_match($rule, $word)) {
+ self::$cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
+
+ return self::$cache['pluralize'][$word];
+ }
+ }
+ }
+
+ /**
+ * Returns a word in singular form.
+ *
+ * @param string $word The word in plural form.
+ *
+ * @return string The word in singular form.
+ */
+ public static function singularize($word)
+ {
+ if (isset(self::$cache['singularize'][$word])) {
+ return self::$cache['singularize'][$word];
+ }
+
+ if (!isset(self::$singular['merged']['uninflected'])) {
+ self::$singular['merged']['uninflected'] = array_merge(
+ self::$singular['uninflected'],
+ self::$uninflected
+ );
+ }
+
+ if (!isset(self::$singular['merged']['irregular'])) {
+ self::$singular['merged']['irregular'] = array_merge(
+ self::$singular['irregular'],
+ array_flip(self::$plural['irregular'])
+ );
+ }
+
+ if (!isset(self::$singular['cacheUninflected']) || !isset(self::$singular['cacheIrregular'])) {
+ self::$singular['cacheUninflected'] = '(?:' . join('|', self::$singular['merged']['uninflected']) . ')';
+ self::$singular['cacheIrregular'] = '(?:' . join('|', array_keys(self::$singular['merged']['irregular'])) . ')';
+ }
+
+ if (preg_match('/(.*)\\b(' . self::$singular['cacheIrregular'] . ')$/i', $word, $regs)) {
+ self::$cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$singular['merged']['irregular'][strtolower($regs[2])], 1);
+
+ return self::$cache['singularize'][$word];
+ }
+
+ if (preg_match('/^(' . self::$singular['cacheUninflected'] . ')$/i', $word, $regs)) {
+ self::$cache['singularize'][$word] = $word;
+
+ return $word;
+ }
+
+ foreach (self::$singular['rules'] as $rule => $replacement) {
+ if (preg_match($rule, $word)) {
+ self::$cache['singularize'][$word] = preg_replace($rule, $replacement, $word);
+
+ return self::$cache['singularize'][$word];
+ }
+ }
+
+ self::$cache['singularize'][$word] = $word;
+
+ return $word;
+ }
+}
diff --git a/vendor/doctrine/inflector/phpunit.xml.dist b/vendor/doctrine/inflector/phpunit.xml.dist
new file mode 100644
index 00000000..ef07faa5
--- /dev/null
+++ b/vendor/doctrine/inflector/phpunit.xml.dist
@@ -0,0 +1,31 @@
+
+
+
+
+
+ ./tests/Doctrine/
+
+
+
+
+
+ ./lib/Doctrine/
+
+
+
+
+
+ performance
+
+
+
diff --git a/vendor/doctrine/inflector/tests/Doctrine/Tests/Common/Inflector/InflectorTest.php b/vendor/doctrine/inflector/tests/Doctrine/Tests/Common/Inflector/InflectorTest.php
new file mode 100644
index 00000000..4198d22c
--- /dev/null
+++ b/vendor/doctrine/inflector/tests/Doctrine/Tests/Common/Inflector/InflectorTest.php
@@ -0,0 +1,309 @@
+assertEquals(
+ $singular,
+ Inflector::singularize($plural),
+ "'$plural' should be singularized to '$singular'"
+ );
+ }
+
+ /**
+ * testInflectingPlurals method
+ *
+ * @dataProvider dataSampleWords
+ * @return void
+ */
+ public function testInflectingPlurals($singular, $plural)
+ {
+ $this->assertEquals(
+ $plural,
+ Inflector::pluralize($singular),
+ "'$singular' should be pluralized to '$plural'"
+ );
+ }
+
+ /**
+ * testCustomPluralRule method
+ *
+ * @return void
+ */
+ public function testCustomPluralRule()
+ {
+ Inflector::reset();
+ Inflector::rules('plural', array('/^(custom)$/i' => '\1izables'));
+
+ $this->assertEquals(Inflector::pluralize('custom'), 'customizables');
+
+ Inflector::rules('plural', array('uninflected' => array('uninflectable')));
+
+ $this->assertEquals(Inflector::pluralize('uninflectable'), 'uninflectable');
+
+ Inflector::rules('plural', array(
+ 'rules' => array('/^(alert)$/i' => '\1ables'),
+ 'uninflected' => array('noflect', 'abtuse'),
+ 'irregular' => array('amaze' => 'amazable', 'phone' => 'phonezes')
+ ));
+
+ $this->assertEquals(Inflector::pluralize('noflect'), 'noflect');
+ $this->assertEquals(Inflector::pluralize('abtuse'), 'abtuse');
+ $this->assertEquals(Inflector::pluralize('alert'), 'alertables');
+ $this->assertEquals(Inflector::pluralize('amaze'), 'amazable');
+ $this->assertEquals(Inflector::pluralize('phone'), 'phonezes');
+ }
+
+ /**
+ * testCustomSingularRule method
+ *
+ * @return void
+ */
+ public function testCustomSingularRule()
+ {
+ Inflector::reset();
+ Inflector::rules('singular', array('/(eple)r$/i' => '\1', '/(jente)r$/i' => '\1'));
+
+ $this->assertEquals(Inflector::singularize('epler'), 'eple');
+ $this->assertEquals(Inflector::singularize('jenter'), 'jente');
+
+ Inflector::rules('singular', array(
+ 'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'),
+ 'uninflected' => array('singulars'),
+ 'irregular' => array('spins' => 'spinor')
+ ));
+
+ $this->assertEquals(Inflector::singularize('inflectors'), 'inflecta');
+ $this->assertEquals(Inflector::singularize('contributors'), 'contributa');
+ $this->assertEquals(Inflector::singularize('spins'), 'spinor');
+ $this->assertEquals(Inflector::singularize('singulars'), 'singulars');
+ }
+
+ /**
+ * test that setting new rules clears the inflector caches.
+ *
+ * @return void
+ */
+ public function testRulesClearsCaches()
+ {
+ Inflector::reset();
+
+ $this->assertEquals(Inflector::singularize('Bananas'), 'Banana');
+ $this->assertEquals(Inflector::pluralize('Banana'), 'Bananas');
+
+ Inflector::rules('singular', array(
+ 'rules' => array('/(.*)nas$/i' => '\1zzz')
+ ));
+
+ $this->assertEquals('Banazzz', Inflector::singularize('Bananas'), 'Was inflected with old rules.');
+
+ Inflector::rules('plural', array(
+ 'rules' => array('/(.*)na$/i' => '\1zzz'),
+ 'irregular' => array('corpus' => 'corpora')
+ ));
+
+ $this->assertEquals(Inflector::pluralize('Banana'), 'Banazzz', 'Was inflected with old rules.');
+ $this->assertEquals(Inflector::pluralize('corpus'), 'corpora', 'Was inflected with old irregular form.');
+ }
+
+ /**
+ * Test resetting inflection rules.
+ *
+ * @return void
+ */
+ public function testCustomRuleWithReset()
+ {
+ Inflector::reset();
+
+ $uninflected = array('atlas', 'lapis', 'onibus', 'pires', 'virus', '.*x');
+ $pluralIrregular = array('as' => 'ases');
+
+ Inflector::rules('singular', array(
+ 'rules' => array('/^(.*)(a|e|o|u)is$/i' => '\1\2l'),
+ 'uninflected' => $uninflected,
+ ), true);
+
+ Inflector::rules('plural', array(
+ 'rules' => array(
+ '/^(.*)(a|e|o|u)l$/i' => '\1\2is',
+ ),
+ 'uninflected' => $uninflected,
+ 'irregular' => $pluralIrregular
+ ), true);
+
+ $this->assertEquals(Inflector::pluralize('Alcool'), 'Alcoois');
+ $this->assertEquals(Inflector::pluralize('Atlas'), 'Atlas');
+ $this->assertEquals(Inflector::singularize('Alcoois'), 'Alcool');
+ $this->assertEquals(Inflector::singularize('Atlas'), 'Atlas');
+ }
+
+ /**
+ * Test basic ucwords functionality.
+ *
+ * @return void
+ */
+ public function testUcwords()
+ {
+ $this->assertSame('Top-O-The-Morning To All_of_you!', Inflector::ucwords( 'top-o-the-morning to all_of_you!'));
+ }
+
+ /**
+ * Test ucwords functionality with custom delimeters.
+ *
+ * @return void
+ */
+ public function testUcwordsWithCustomDelimeters()
+ {
+ $this->assertSame('Top-O-The-Morning To All_Of_You!', Inflector::ucwords( 'top-o-the-morning to all_of_you!', '-_ '));
+ }
+}
+
diff --git a/vendor/doctrine/inflector/tests/Doctrine/Tests/DoctrineTestCase.php b/vendor/doctrine/inflector/tests/Doctrine/Tests/DoctrineTestCase.php
new file mode 100644
index 00000000..e8323d29
--- /dev/null
+++ b/vendor/doctrine/inflector/tests/Doctrine/Tests/DoctrineTestCase.php
@@ -0,0 +1,10 @@
+normalize($concrete);
+
+ return new ContextualBindingBuilder($this, $concrete);
+ }
+
+ /**
+ * Determine if the given abstract type has been bound.
+ *
+ * @param string $abstract
+ * @return bool
+ */
+ public function bound($abstract)
+ {
+ $abstract = $this->normalize($abstract);
+
+ return isset($this->bindings[$abstract]) || isset($this->instances[$abstract]) || $this->isAlias($abstract);
+ }
+
+ /**
+ * Determine if the given abstract type has been resolved.
+ *
+ * @param string $abstract
+ * @return bool
+ */
+ public function resolved($abstract)
+ {
+ $abstract = $this->normalize($abstract);
+
+ if ($this->isAlias($abstract)) {
+ $abstract = $this->getAlias($abstract);
+ }
+
+ return isset($this->resolved[$abstract]) || isset($this->instances[$abstract]);
+ }
+
+ /**
+ * Determine if a given string is an alias.
+ *
+ * @param string $name
+ * @return bool
+ */
+ public function isAlias($name)
+ {
+ return isset($this->aliases[$this->normalize($name)]);
+ }
+
+ /**
+ * Register a binding with the container.
+ *
+ * @param string|array $abstract
+ * @param \Closure|string|null $concrete
+ * @param bool $shared
+ * @return void
+ */
+ public function bind($abstract, $concrete = null, $shared = false)
+ {
+ $abstract = $this->normalize($abstract);
+
+ $concrete = $this->normalize($concrete);
+
+ // If the given types are actually an array, we will assume an alias is being
+ // defined and will grab this "real" abstract class name and register this
+ // alias with the container so that it can be used as a shortcut for it.
+ if (is_array($abstract)) {
+ list($abstract, $alias) = $this->extractAlias($abstract);
+
+ $this->alias($abstract, $alias);
+ }
+
+ // If no concrete type was given, we will simply set the concrete type to the
+ // abstract type. After that, the concrete type to be registered as shared
+ // without being forced to state their classes in both of the parameters.
+ $this->dropStaleInstances($abstract);
+
+ if (is_null($concrete)) {
+ $concrete = $abstract;
+ }
+
+ // If the factory is not a Closure, it means it is just a class name which is
+ // bound into this container to the abstract type and we will just wrap it
+ // up inside its own Closure to give us more convenience when extending.
+ if (! $concrete instanceof Closure) {
+ $concrete = $this->getClosure($abstract, $concrete);
+ }
+
+ $this->bindings[$abstract] = compact('concrete', 'shared');
+
+ // If the abstract type was already resolved in this container we'll fire the
+ // rebound listener so that any objects which have already gotten resolved
+ // can have their copy of the object updated via the listener callbacks.
+ if ($this->resolved($abstract)) {
+ $this->rebound($abstract);
+ }
+ }
+
+ /**
+ * Get the Closure to be used when building a type.
+ *
+ * @param string $abstract
+ * @param string $concrete
+ * @return \Closure
+ */
+ protected function getClosure($abstract, $concrete)
+ {
+ return function ($c, $parameters = []) use ($abstract, $concrete) {
+ $method = ($abstract == $concrete) ? 'build' : 'make';
+
+ return $c->$method($concrete, $parameters);
+ };
+ }
+
+ /**
+ * Add a contextual binding to the container.
+ *
+ * @param string $concrete
+ * @param string $abstract
+ * @param \Closure|string $implementation
+ * @return void
+ */
+ public function addContextualBinding($concrete, $abstract, $implementation)
+ {
+ $this->contextual[$this->normalize($concrete)][$this->normalize($abstract)] = $this->normalize($implementation);
+ }
+
+ /**
+ * Register a binding if it hasn't already been registered.
+ *
+ * @param string $abstract
+ * @param \Closure|string|null $concrete
+ * @param bool $shared
+ * @return void
+ */
+ public function bindIf($abstract, $concrete = null, $shared = false)
+ {
+ if (! $this->bound($abstract)) {
+ $this->bind($abstract, $concrete, $shared);
+ }
+ }
+
+ /**
+ * Register a shared binding in the container.
+ *
+ * @param string|array $abstract
+ * @param \Closure|string|null $concrete
+ * @return void
+ */
+ public function singleton($abstract, $concrete = null)
+ {
+ $this->bind($abstract, $concrete, true);
+ }
+
+ /**
+ * Wrap a Closure such that it is shared.
+ *
+ * @param \Closure $closure
+ * @return \Closure
+ */
+ public function share(Closure $closure)
+ {
+ return function ($container) use ($closure) {
+ // We'll simply declare a static variable within the Closures and if it has
+ // not been set we will execute the given Closures to resolve this value
+ // and return it back to these consumers of the method as an instance.
+ static $object;
+
+ if (is_null($object)) {
+ $object = $closure($container);
+ }
+
+ return $object;
+ };
+ }
+
+ /**
+ * "Extend" an abstract type in the container.
+ *
+ * @param string $abstract
+ * @param \Closure $closure
+ * @return void
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function extend($abstract, Closure $closure)
+ {
+ $abstract = $this->normalize($abstract);
+
+ if (isset($this->instances[$abstract])) {
+ $this->instances[$abstract] = $closure($this->instances[$abstract], $this);
+
+ $this->rebound($abstract);
+ } else {
+ $this->extenders[$abstract][] = $closure;
+ }
+ }
+
+ /**
+ * Register an existing instance as shared in the container.
+ *
+ * @param string $abstract
+ * @param mixed $instance
+ * @return void
+ */
+ public function instance($abstract, $instance)
+ {
+ $abstract = $this->normalize($abstract);
+
+ // First, we will extract the alias from the abstract if it is an array so we
+ // are using the correct name when binding the type. If we get an alias it
+ // will be registered with the container so we can resolve it out later.
+ if (is_array($abstract)) {
+ list($abstract, $alias) = $this->extractAlias($abstract);
+
+ $this->alias($abstract, $alias);
+ }
+
+ unset($this->aliases[$abstract]);
+
+ // We'll check to determine if this type has been bound before, and if it has
+ // we will fire the rebound callbacks registered with the container and it
+ // can be updated with consuming classes that have gotten resolved here.
+ $bound = $this->bound($abstract);
+
+ $this->instances[$abstract] = $instance;
+
+ if ($bound) {
+ $this->rebound($abstract);
+ }
+ }
+
+ /**
+ * Assign a set of tags to a given binding.
+ *
+ * @param array|string $abstracts
+ * @param array|mixed ...$tags
+ * @return void
+ */
+ public function tag($abstracts, $tags)
+ {
+ $tags = is_array($tags) ? $tags : array_slice(func_get_args(), 1);
+
+ foreach ($tags as $tag) {
+ if (! isset($this->tags[$tag])) {
+ $this->tags[$tag] = [];
+ }
+
+ foreach ((array) $abstracts as $abstract) {
+ $this->tags[$tag][] = $this->normalize($abstract);
+ }
+ }
+ }
+
+ /**
+ * Resolve all of the bindings for a given tag.
+ *
+ * @param string $tag
+ * @return array
+ */
+ public function tagged($tag)
+ {
+ $results = [];
+
+ if (isset($this->tags[$tag])) {
+ foreach ($this->tags[$tag] as $abstract) {
+ $results[] = $this->make($abstract);
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Alias a type to a different name.
+ *
+ * @param string $abstract
+ * @param string $alias
+ * @return void
+ */
+ public function alias($abstract, $alias)
+ {
+ $this->aliases[$alias] = $this->normalize($abstract);
+ }
+
+ /**
+ * Extract the type and alias from a given definition.
+ *
+ * @param array $definition
+ * @return array
+ */
+ protected function extractAlias(array $definition)
+ {
+ return [key($definition), current($definition)];
+ }
+
+ /**
+ * Bind a new callback to an abstract's rebind event.
+ *
+ * @param string $abstract
+ * @param \Closure $callback
+ * @return mixed
+ */
+ public function rebinding($abstract, Closure $callback)
+ {
+ $this->reboundCallbacks[$this->normalize($abstract)][] = $callback;
+
+ if ($this->bound($abstract)) {
+ return $this->make($abstract);
+ }
+ }
+
+ /**
+ * Refresh an instance on the given target and method.
+ *
+ * @param string $abstract
+ * @param mixed $target
+ * @param string $method
+ * @return mixed
+ */
+ public function refresh($abstract, $target, $method)
+ {
+ return $this->rebinding($this->normalize($abstract), function ($app, $instance) use ($target, $method) {
+ $target->{$method}($instance);
+ });
+ }
+
+ /**
+ * Fire the "rebound" callbacks for the given abstract type.
+ *
+ * @param string $abstract
+ * @return void
+ */
+ protected function rebound($abstract)
+ {
+ $instance = $this->make($abstract);
+
+ foreach ($this->getReboundCallbacks($abstract) as $callback) {
+ call_user_func($callback, $this, $instance);
+ }
+ }
+
+ /**
+ * Get the rebound callbacks for a given type.
+ *
+ * @param string $abstract
+ * @return array
+ */
+ protected function getReboundCallbacks($abstract)
+ {
+ if (isset($this->reboundCallbacks[$abstract])) {
+ return $this->reboundCallbacks[$abstract];
+ }
+
+ return [];
+ }
+
+ /**
+ * Wrap the given closure such that its dependencies will be injected when executed.
+ *
+ * @param \Closure $callback
+ * @param array $parameters
+ * @return \Closure
+ */
+ public function wrap(Closure $callback, array $parameters = [])
+ {
+ return function () use ($callback, $parameters) {
+ return $this->call($callback, $parameters);
+ };
+ }
+
+ /**
+ * Call the given Closure / class@method and inject its dependencies.
+ *
+ * @param callable|string $callback
+ * @param array $parameters
+ * @param string|null $defaultMethod
+ * @return mixed
+ */
+ public function call($callback, array $parameters = [], $defaultMethod = null)
+ {
+ if ($this->isCallableWithAtSign($callback) || $defaultMethod) {
+ return $this->callClass($callback, $parameters, $defaultMethod);
+ }
+
+ $dependencies = $this->getMethodDependencies($callback, $parameters);
+
+ return call_user_func_array($callback, $dependencies);
+ }
+
+ /**
+ * Determine if the given string is in Class@method syntax.
+ *
+ * @param mixed $callback
+ * @return bool
+ */
+ protected function isCallableWithAtSign($callback)
+ {
+ return is_string($callback) && strpos($callback, '@') !== false;
+ }
+
+ /**
+ * Get all dependencies for a given method.
+ *
+ * @param callable|string $callback
+ * @param array $parameters
+ * @return array
+ */
+ protected function getMethodDependencies($callback, array $parameters = [])
+ {
+ $dependencies = [];
+
+ foreach ($this->getCallReflector($callback)->getParameters() as $parameter) {
+ $this->addDependencyForCallParameter($parameter, $parameters, $dependencies);
+ }
+
+ return array_merge($dependencies, $parameters);
+ }
+
+ /**
+ * Get the proper reflection instance for the given callback.
+ *
+ * @param callable|string $callback
+ * @return \ReflectionFunctionAbstract
+ */
+ protected function getCallReflector($callback)
+ {
+ if (is_string($callback) && strpos($callback, '::') !== false) {
+ $callback = explode('::', $callback);
+ }
+
+ if (is_array($callback)) {
+ return new ReflectionMethod($callback[0], $callback[1]);
+ }
+
+ return new ReflectionFunction($callback);
+ }
+
+ /**
+ * Get the dependency for the given call parameter.
+ *
+ * @param \ReflectionParameter $parameter
+ * @param array $parameters
+ * @param array $dependencies
+ * @return mixed
+ */
+ protected function addDependencyForCallParameter(ReflectionParameter $parameter, array &$parameters, &$dependencies)
+ {
+ if (array_key_exists($parameter->name, $parameters)) {
+ $dependencies[] = $parameters[$parameter->name];
+
+ unset($parameters[$parameter->name]);
+ } elseif ($parameter->getClass()) {
+ $dependencies[] = $this->make($parameter->getClass()->name);
+ } elseif ($parameter->isDefaultValueAvailable()) {
+ $dependencies[] = $parameter->getDefaultValue();
+ }
+ }
+
+ /**
+ * Call a string reference to a class using Class@method syntax.
+ *
+ * @param string $target
+ * @param array $parameters
+ * @param string|null $defaultMethod
+ * @return mixed
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function callClass($target, array $parameters = [], $defaultMethod = null)
+ {
+ $segments = explode('@', $target);
+
+ // If the listener has an @ sign, we will assume it is being used to delimit
+ // the class name from the handle method name. This allows for handlers
+ // to run multiple handler methods in a single class for convenience.
+ $method = count($segments) == 2 ? $segments[1] : $defaultMethod;
+
+ if (is_null($method)) {
+ throw new InvalidArgumentException('Method not provided.');
+ }
+
+ return $this->call([$this->make($segments[0]), $method], $parameters);
+ }
+
+ /**
+ * Resolve the given type from the container.
+ *
+ * @param string $abstract
+ * @param array $parameters
+ * @return mixed
+ */
+ public function make($abstract, array $parameters = [])
+ {
+ $abstract = $this->getAlias($this->normalize($abstract));
+
+ // If an instance of the type is currently being managed as a singleton we'll
+ // just return an existing instance instead of instantiating new instances
+ // so the developer can keep using the same objects instance every time.
+ if (isset($this->instances[$abstract])) {
+ return $this->instances[$abstract];
+ }
+
+ $concrete = $this->getConcrete($abstract);
+
+ // We're ready to instantiate an instance of the concrete type registered for
+ // the binding. This will instantiate the types, as well as resolve any of
+ // its "nested" dependencies recursively until all have gotten resolved.
+ if ($this->isBuildable($concrete, $abstract)) {
+ $object = $this->build($concrete, $parameters);
+ } else {
+ $object = $this->make($concrete, $parameters);
+ }
+
+ // If we defined any extenders for this type, we'll need to spin through them
+ // and apply them to the object being built. This allows for the extension
+ // of services, such as changing configuration or decorating the object.
+ foreach ($this->getExtenders($abstract) as $extender) {
+ $object = $extender($object, $this);
+ }
+
+ // If the requested type is registered as a singleton we'll want to cache off
+ // the instances in "memory" so we can return it later without creating an
+ // entirely new instance of an object on each subsequent request for it.
+ if ($this->isShared($abstract)) {
+ $this->instances[$abstract] = $object;
+ }
+
+ $this->fireResolvingCallbacks($abstract, $object);
+
+ $this->resolved[$abstract] = true;
+
+ return $object;
+ }
+
+ /**
+ * Get the concrete type for a given abstract.
+ *
+ * @param string $abstract
+ * @return mixed $concrete
+ */
+ protected function getConcrete($abstract)
+ {
+ if (! is_null($concrete = $this->getContextualConcrete($abstract))) {
+ return $concrete;
+ }
+
+ // If we don't have a registered resolver or concrete for the type, we'll just
+ // assume each type is a concrete name and will attempt to resolve it as is
+ // since the container should be able to resolve concretes automatically.
+ if (! isset($this->bindings[$abstract])) {
+ return $abstract;
+ }
+
+ return $this->bindings[$abstract]['concrete'];
+ }
+
+ /**
+ * Get the contextual concrete binding for the given abstract.
+ *
+ * @param string $abstract
+ * @return string|null
+ */
+ protected function getContextualConcrete($abstract)
+ {
+ if (isset($this->contextual[end($this->buildStack)][$abstract])) {
+ return $this->contextual[end($this->buildStack)][$abstract];
+ }
+ }
+
+ /**
+ * Normalize the given class name by removing leading slashes.
+ *
+ * @param mixed $service
+ * @return mixed
+ */
+ protected function normalize($service)
+ {
+ return is_string($service) ? ltrim($service, '\\') : $service;
+ }
+
+ /**
+ * Get the extender callbacks for a given type.
+ *
+ * @param string $abstract
+ * @return array
+ */
+ protected function getExtenders($abstract)
+ {
+ if (isset($this->extenders[$abstract])) {
+ return $this->extenders[$abstract];
+ }
+
+ return [];
+ }
+
+ /**
+ * Instantiate a concrete instance of the given type.
+ *
+ * @param string $concrete
+ * @param array $parameters
+ * @return mixed
+ *
+ * @throws \Illuminate\Contracts\Container\BindingResolutionException
+ */
+ public function build($concrete, array $parameters = [])
+ {
+ // If the concrete type is actually a Closure, we will just execute it and
+ // hand back the results of the functions, which allows functions to be
+ // used as resolvers for more fine-tuned resolution of these objects.
+ if ($concrete instanceof Closure) {
+ return $concrete($this, $parameters);
+ }
+
+ $reflector = new ReflectionClass($concrete);
+
+ // If the type is not instantiable, the developer is attempting to resolve
+ // an abstract type such as an Interface of Abstract Class and there is
+ // no binding registered for the abstractions so we need to bail out.
+ if (! $reflector->isInstantiable()) {
+ if (! empty($this->buildStack)) {
+ $previous = implode(', ', $this->buildStack);
+
+ $message = "Target [$concrete] is not instantiable while building [$previous].";
+ } else {
+ $message = "Target [$concrete] is not instantiable.";
+ }
+
+ throw new BindingResolutionException($message);
+ }
+
+ $this->buildStack[] = $concrete;
+
+ $constructor = $reflector->getConstructor();
+
+ // If there are no constructors, that means there are no dependencies then
+ // we can just resolve the instances of the objects right away, without
+ // resolving any other types or dependencies out of these containers.
+ if (is_null($constructor)) {
+ array_pop($this->buildStack);
+
+ return new $concrete;
+ }
+
+ $dependencies = $constructor->getParameters();
+
+ // Once we have all the constructor's parameters we can create each of the
+ // dependency instances and then use the reflection instances to make a
+ // new instance of this class, injecting the created dependencies in.
+ $parameters = $this->keyParametersByArgument(
+ $dependencies, $parameters
+ );
+
+ $instances = $this->getDependencies(
+ $dependencies, $parameters
+ );
+
+ array_pop($this->buildStack);
+
+ return $reflector->newInstanceArgs($instances);
+ }
+
+ /**
+ * Resolve all of the dependencies from the ReflectionParameters.
+ *
+ * @param array $parameters
+ * @param array $primitives
+ * @return array
+ */
+ protected function getDependencies(array $parameters, array $primitives = [])
+ {
+ $dependencies = [];
+
+ foreach ($parameters as $parameter) {
+ $dependency = $parameter->getClass();
+
+ // If the class is null, it means the dependency is a string or some other
+ // primitive type which we can not resolve since it is not a class and
+ // we will just bomb out with an error since we have no-where to go.
+ if (array_key_exists($parameter->name, $primitives)) {
+ $dependencies[] = $primitives[$parameter->name];
+ } elseif (is_null($dependency)) {
+ $dependencies[] = $this->resolveNonClass($parameter);
+ } else {
+ $dependencies[] = $this->resolveClass($parameter);
+ }
+ }
+
+ return $dependencies;
+ }
+
+ /**
+ * Resolve a non-class hinted dependency.
+ *
+ * @param \ReflectionParameter $parameter
+ * @return mixed
+ *
+ * @throws \Illuminate\Contracts\Container\BindingResolutionException
+ */
+ protected function resolveNonClass(ReflectionParameter $parameter)
+ {
+ if (! is_null($concrete = $this->getContextualConcrete('$'.$parameter->name))) {
+ if ($concrete instanceof Closure) {
+ return call_user_func($concrete, $this);
+ } else {
+ return $concrete;
+ }
+ }
+
+ if ($parameter->isDefaultValueAvailable()) {
+ return $parameter->getDefaultValue();
+ }
+
+ $message = "Unresolvable dependency resolving [$parameter] in class {$parameter->getDeclaringClass()->getName()}";
+
+ throw new BindingResolutionException($message);
+ }
+
+ /**
+ * Resolve a class based dependency from the container.
+ *
+ * @param \ReflectionParameter $parameter
+ * @return mixed
+ *
+ * @throws \Illuminate\Contracts\Container\BindingResolutionException
+ */
+ protected function resolveClass(ReflectionParameter $parameter)
+ {
+ try {
+ return $this->make($parameter->getClass()->name);
+ }
+
+ // If we can not resolve the class instance, we will check to see if the value
+ // is optional, and if it is we will return the optional parameter value as
+ // the value of the dependency, similarly to how we do this with scalars.
+ catch (BindingResolutionException $e) {
+ if ($parameter->isOptional()) {
+ return $parameter->getDefaultValue();
+ }
+
+ throw $e;
+ }
+ }
+
+ /**
+ * If extra parameters are passed by numeric ID, rekey them by argument name.
+ *
+ * @param array $dependencies
+ * @param array $parameters
+ * @return array
+ */
+ protected function keyParametersByArgument(array $dependencies, array $parameters)
+ {
+ foreach ($parameters as $key => $value) {
+ if (is_numeric($key)) {
+ unset($parameters[$key]);
+
+ $parameters[$dependencies[$key]->name] = $value;
+ }
+ }
+
+ return $parameters;
+ }
+
+ /**
+ * Register a new resolving callback.
+ *
+ * @param string $abstract
+ * @param \Closure|null $callback
+ * @return void
+ */
+ public function resolving($abstract, Closure $callback = null)
+ {
+ if ($callback === null && $abstract instanceof Closure) {
+ $this->resolvingCallback($abstract);
+ } else {
+ $this->resolvingCallbacks[$this->normalize($abstract)][] = $callback;
+ }
+ }
+
+ /**
+ * Register a new after resolving callback for all types.
+ *
+ * @param string $abstract
+ * @param \Closure|null $callback
+ * @return void
+ */
+ public function afterResolving($abstract, Closure $callback = null)
+ {
+ if ($abstract instanceof Closure && $callback === null) {
+ $this->afterResolvingCallback($abstract);
+ } else {
+ $this->afterResolvingCallbacks[$this->normalize($abstract)][] = $callback;
+ }
+ }
+
+ /**
+ * Register a new resolving callback by type of its first argument.
+ *
+ * @param \Closure $callback
+ * @return void
+ */
+ protected function resolvingCallback(Closure $callback)
+ {
+ $abstract = $this->getFunctionHint($callback);
+
+ if ($abstract) {
+ $this->resolvingCallbacks[$abstract][] = $callback;
+ } else {
+ $this->globalResolvingCallbacks[] = $callback;
+ }
+ }
+
+ /**
+ * Register a new after resolving callback by type of its first argument.
+ *
+ * @param \Closure $callback
+ * @return void
+ */
+ protected function afterResolvingCallback(Closure $callback)
+ {
+ $abstract = $this->getFunctionHint($callback);
+
+ if ($abstract) {
+ $this->afterResolvingCallbacks[$abstract][] = $callback;
+ } else {
+ $this->globalAfterResolvingCallbacks[] = $callback;
+ }
+ }
+
+ /**
+ * Get the type hint for this closure's first argument.
+ *
+ * @param \Closure $callback
+ * @return mixed
+ */
+ protected function getFunctionHint(Closure $callback)
+ {
+ $function = new ReflectionFunction($callback);
+
+ if ($function->getNumberOfParameters() == 0) {
+ return;
+ }
+
+ $expected = $function->getParameters()[0];
+
+ if (! $expected->getClass()) {
+ return;
+ }
+
+ return $expected->getClass()->name;
+ }
+
+ /**
+ * Fire all of the resolving callbacks.
+ *
+ * @param string $abstract
+ * @param mixed $object
+ * @return void
+ */
+ protected function fireResolvingCallbacks($abstract, $object)
+ {
+ $this->fireCallbackArray($object, $this->globalResolvingCallbacks);
+
+ $this->fireCallbackArray(
+ $object, $this->getCallbacksForType(
+ $abstract, $object, $this->resolvingCallbacks
+ )
+ );
+
+ $this->fireCallbackArray($object, $this->globalAfterResolvingCallbacks);
+
+ $this->fireCallbackArray(
+ $object, $this->getCallbacksForType(
+ $abstract, $object, $this->afterResolvingCallbacks
+ )
+ );
+ }
+
+ /**
+ * Get all callbacks for a given type.
+ *
+ * @param string $abstract
+ * @param object $object
+ * @param array $callbacksPerType
+ *
+ * @return array
+ */
+ protected function getCallbacksForType($abstract, $object, array $callbacksPerType)
+ {
+ $results = [];
+
+ foreach ($callbacksPerType as $type => $callbacks) {
+ if ($type === $abstract || $object instanceof $type) {
+ $results = array_merge($results, $callbacks);
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Fire an array of callbacks with an object.
+ *
+ * @param mixed $object
+ * @param array $callbacks
+ * @return void
+ */
+ protected function fireCallbackArray($object, array $callbacks)
+ {
+ foreach ($callbacks as $callback) {
+ $callback($object, $this);
+ }
+ }
+
+ /**
+ * Determine if a given type is shared.
+ *
+ * @param string $abstract
+ * @return bool
+ */
+ public function isShared($abstract)
+ {
+ $abstract = $this->normalize($abstract);
+
+ if (isset($this->instances[$abstract])) {
+ return true;
+ }
+
+ if (! isset($this->bindings[$abstract]['shared'])) {
+ return false;
+ }
+
+ return $this->bindings[$abstract]['shared'] === true;
+ }
+
+ /**
+ * Determine if the given concrete is buildable.
+ *
+ * @param mixed $concrete
+ * @param string $abstract
+ * @return bool
+ */
+ protected function isBuildable($concrete, $abstract)
+ {
+ return $concrete === $abstract || $concrete instanceof Closure;
+ }
+
+ /**
+ * Get the alias for an abstract if available.
+ *
+ * @param string $abstract
+ * @return string
+ */
+ protected function getAlias($abstract)
+ {
+ if (! isset($this->aliases[$abstract])) {
+ return $abstract;
+ }
+
+ return $this->getAlias($this->aliases[$abstract]);
+ }
+
+ /**
+ * Get the container's bindings.
+ *
+ * @return array
+ */
+ public function getBindings()
+ {
+ return $this->bindings;
+ }
+
+ /**
+ * Drop all of the stale instances and aliases.
+ *
+ * @param string $abstract
+ * @return void
+ */
+ protected function dropStaleInstances($abstract)
+ {
+ unset($this->instances[$abstract], $this->aliases[$abstract]);
+ }
+
+ /**
+ * Remove a resolved instance from the instance cache.
+ *
+ * @param string $abstract
+ * @return void
+ */
+ public function forgetInstance($abstract)
+ {
+ unset($this->instances[$this->normalize($abstract)]);
+ }
+
+ /**
+ * Clear all of the instances from the container.
+ *
+ * @return void
+ */
+ public function forgetInstances()
+ {
+ $this->instances = [];
+ }
+
+ /**
+ * Flush the container of all bindings and resolved instances.
+ *
+ * @return void
+ */
+ public function flush()
+ {
+ $this->aliases = [];
+ $this->resolved = [];
+ $this->bindings = [];
+ $this->instances = [];
+ }
+
+ /**
+ * Set the globally available instance of the container.
+ *
+ * @return static
+ */
+ public static function getInstance()
+ {
+ return static::$instance;
+ }
+
+ /**
+ * Set the shared instance of the container.
+ *
+ * @param \Illuminate\Contracts\Container\Container $container
+ * @return void
+ */
+ public static function setInstance(ContainerContract $container)
+ {
+ static::$instance = $container;
+ }
+
+ /**
+ * Determine if a given offset exists.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function offsetExists($key)
+ {
+ return $this->bound($key);
+ }
+
+ /**
+ * Get the value at a given offset.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function offsetGet($key)
+ {
+ return $this->make($key);
+ }
+
+ /**
+ * Set the value at a given offset.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ */
+ public function offsetSet($key, $value)
+ {
+ // If the value is not a Closure, we will make it one. This simply gives
+ // more "drop-in" replacement functionality for the Pimple which this
+ // container's simplest functions are base modeled and built after.
+ if (! $value instanceof Closure) {
+ $value = function () use ($value) {
+ return $value;
+ };
+ }
+
+ $this->bind($key, $value);
+ }
+
+ /**
+ * Unset the value at a given offset.
+ *
+ * @param string $key
+ * @return void
+ */
+ public function offsetUnset($key)
+ {
+ $key = $this->normalize($key);
+
+ unset($this->bindings[$key], $this->instances[$key], $this->resolved[$key]);
+ }
+
+ /**
+ * Dynamically access container services.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function __get($key)
+ {
+ return $this[$key];
+ }
+
+ /**
+ * Dynamically set container services.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this[$key] = $value;
+ }
+}
diff --git a/vendor/illuminate/container/ContextualBindingBuilder.php b/vendor/illuminate/container/ContextualBindingBuilder.php
new file mode 100644
index 00000000..fc5cd611
--- /dev/null
+++ b/vendor/illuminate/container/ContextualBindingBuilder.php
@@ -0,0 +1,66 @@
+concrete = $concrete;
+ $this->container = $container;
+ }
+
+ /**
+ * Define the abstract target that depends on the context.
+ *
+ * @param string $abstract
+ * @return $this
+ */
+ public function needs($abstract)
+ {
+ $this->needs = $abstract;
+
+ return $this;
+ }
+
+ /**
+ * Define the implementation for the contextual binding.
+ *
+ * @param \Closure|string $implementation
+ * @return void
+ */
+ public function give($implementation)
+ {
+ $this->container->addContextualBinding($this->concrete, $this->needs, $implementation);
+ }
+}
diff --git a/vendor/illuminate/container/composer.json b/vendor/illuminate/container/composer.json
new file mode 100755
index 00000000..67d68528
--- /dev/null
+++ b/vendor/illuminate/container/composer.json
@@ -0,0 +1,31 @@
+{
+ "name": "illuminate/container",
+ "description": "The Illuminate Container package.",
+ "license": "MIT",
+ "homepage": "http://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.5.9",
+ "illuminate/contracts": "5.2.*"
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Container\\": ""
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/contracts/Auth/Access/Authorizable.php b/vendor/illuminate/contracts/Auth/Access/Authorizable.php
new file mode 100644
index 00000000..2f9657c5
--- /dev/null
+++ b/vendor/illuminate/contracts/Auth/Access/Authorizable.php
@@ -0,0 +1,15 @@
+id = $id;
+ $this->class = $class;
+ }
+}
diff --git a/vendor/illuminate/contracts/Debug/ExceptionHandler.php b/vendor/illuminate/contracts/Debug/ExceptionHandler.php
new file mode 100644
index 00000000..e3f18a59
--- /dev/null
+++ b/vendor/illuminate/contracts/Debug/ExceptionHandler.php
@@ -0,0 +1,34 @@
+provider = $provider;
+ }
+
+ /**
+ * Get the validation error message provider.
+ *
+ * @return \Illuminate\Contracts\Support\MessageBag
+ */
+ public function errors()
+ {
+ return $this->provider->getMessageBag();
+ }
+
+ /**
+ * Get the validation error message provider.
+ *
+ * @return \Illuminate\Contracts\Support\MessageProvider
+ */
+ public function getMessageProvider()
+ {
+ return $this->provider;
+ }
+}
diff --git a/vendor/illuminate/contracts/Validation/Validator.php b/vendor/illuminate/contracts/Validation/Validator.php
new file mode 100644
index 00000000..9cf68c76
--- /dev/null
+++ b/vendor/illuminate/contracts/Validation/Validator.php
@@ -0,0 +1,40 @@
+=5.5.9"
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Contracts\\": ""
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/database/Capsule/Manager.php b/vendor/illuminate/database/Capsule/Manager.php
new file mode 100755
index 00000000..1a144019
--- /dev/null
+++ b/vendor/illuminate/database/Capsule/Manager.php
@@ -0,0 +1,201 @@
+setupContainer($container ?: new Container);
+
+ // Once we have the container setup, we will setup the default configuration
+ // options in the container "config" binding. This will make the database
+ // manager behave correctly since all the correct binding are in place.
+ $this->setupDefaultConfiguration();
+
+ $this->setupManager();
+ }
+
+ /**
+ * Setup the default database configuration options.
+ *
+ * @return void
+ */
+ protected function setupDefaultConfiguration()
+ {
+ $this->container['config']['database.fetch'] = PDO::FETCH_OBJ;
+
+ $this->container['config']['database.default'] = 'default';
+ }
+
+ /**
+ * Build the database manager instance.
+ *
+ * @return void
+ */
+ protected function setupManager()
+ {
+ $factory = new ConnectionFactory($this->container);
+
+ $this->manager = new DatabaseManager($this->container, $factory);
+ }
+
+ /**
+ * Get a connection instance from the global manager.
+ *
+ * @param string $connection
+ * @return \Illuminate\Database\Connection
+ */
+ public static function connection($connection = null)
+ {
+ return static::$instance->getConnection($connection);
+ }
+
+ /**
+ * Get a fluent query builder instance.
+ *
+ * @param string $table
+ * @param string $connection
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public static function table($table, $connection = null)
+ {
+ return static::$instance->connection($connection)->table($table);
+ }
+
+ /**
+ * Get a schema builder instance.
+ *
+ * @param string $connection
+ * @return \Illuminate\Database\Schema\Builder
+ */
+ public static function schema($connection = null)
+ {
+ return static::$instance->connection($connection)->getSchemaBuilder();
+ }
+
+ /**
+ * Get a registered connection instance.
+ *
+ * @param string $name
+ * @return \Illuminate\Database\Connection
+ */
+ public function getConnection($name = null)
+ {
+ return $this->manager->connection($name);
+ }
+
+ /**
+ * Register a connection with the manager.
+ *
+ * @param array $config
+ * @param string $name
+ * @return void
+ */
+ public function addConnection(array $config, $name = 'default')
+ {
+ $connections = $this->container['config']['database.connections'];
+
+ $connections[$name] = $config;
+
+ $this->container['config']['database.connections'] = $connections;
+ }
+
+ /**
+ * Bootstrap Eloquent so it is ready for usage.
+ *
+ * @return void
+ */
+ public function bootEloquent()
+ {
+ Eloquent::setConnectionResolver($this->manager);
+
+ // If we have an event dispatcher instance, we will go ahead and register it
+ // with the Eloquent ORM, allowing for model callbacks while creating and
+ // updating "model" instances; however, if it not necessary to operate.
+ if ($dispatcher = $this->getEventDispatcher()) {
+ Eloquent::setEventDispatcher($dispatcher);
+ }
+ }
+
+ /**
+ * Set the fetch mode for the database connections.
+ *
+ * @param int $fetchMode
+ * @return $this
+ */
+ public function setFetchMode($fetchMode)
+ {
+ $this->container['config']['database.fetch'] = $fetchMode;
+
+ return $this;
+ }
+
+ /**
+ * Get the database manager instance.
+ *
+ * @return \Illuminate\Database\DatabaseManager
+ */
+ public function getDatabaseManager()
+ {
+ return $this->manager;
+ }
+
+ /**
+ * Get the current event dispatcher instance.
+ *
+ * @return \Illuminate\Contracts\Events\Dispatcher|null
+ */
+ public function getEventDispatcher()
+ {
+ if ($this->container->bound('events')) {
+ return $this->container['events'];
+ }
+ }
+
+ /**
+ * Set the event dispatcher instance to be used by connections.
+ *
+ * @param \Illuminate\Contracts\Events\Dispatcher $dispatcher
+ * @return void
+ */
+ public function setEventDispatcher(Dispatcher $dispatcher)
+ {
+ $this->container->instance('events', $dispatcher);
+ }
+
+ /**
+ * Dynamically pass methods to the default connection.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public static function __callStatic($method, $parameters)
+ {
+ return call_user_func_array([static::connection(), $method], $parameters);
+ }
+}
diff --git a/vendor/illuminate/database/Connection.php b/vendor/illuminate/database/Connection.php
new file mode 100755
index 00000000..96e277b3
--- /dev/null
+++ b/vendor/illuminate/database/Connection.php
@@ -0,0 +1,1157 @@
+pdo = $pdo;
+
+ // First we will setup the default properties. We keep track of the DB
+ // name we are connected to since it is needed when some reflective
+ // type commands are run such as checking whether a table exists.
+ $this->database = $database;
+
+ $this->tablePrefix = $tablePrefix;
+
+ $this->config = $config;
+
+ // We need to initialize a query grammar and the query post processors
+ // which are both very important parts of the database abstractions
+ // so we initialize these to their default values while starting.
+ $this->useDefaultQueryGrammar();
+
+ $this->useDefaultPostProcessor();
+ }
+
+ /**
+ * Set the query grammar to the default implementation.
+ *
+ * @return void
+ */
+ public function useDefaultQueryGrammar()
+ {
+ $this->queryGrammar = $this->getDefaultQueryGrammar();
+ }
+
+ /**
+ * Get the default query grammar instance.
+ *
+ * @return \Illuminate\Database\Query\Grammars\Grammar
+ */
+ protected function getDefaultQueryGrammar()
+ {
+ return new QueryGrammar;
+ }
+
+ /**
+ * Set the schema grammar to the default implementation.
+ *
+ * @return void
+ */
+ public function useDefaultSchemaGrammar()
+ {
+ $this->schemaGrammar = $this->getDefaultSchemaGrammar();
+ }
+
+ /**
+ * Get the default schema grammar instance.
+ *
+ * @return \Illuminate\Database\Schema\Grammars\Grammar
+ */
+ protected function getDefaultSchemaGrammar()
+ {
+ //
+ }
+
+ /**
+ * Set the query post processor to the default implementation.
+ *
+ * @return void
+ */
+ public function useDefaultPostProcessor()
+ {
+ $this->postProcessor = $this->getDefaultPostProcessor();
+ }
+
+ /**
+ * Get the default post processor instance.
+ *
+ * @return \Illuminate\Database\Query\Processors\Processor
+ */
+ protected function getDefaultPostProcessor()
+ {
+ return new Processor;
+ }
+
+ /**
+ * Get a schema builder instance for the connection.
+ *
+ * @return \Illuminate\Database\Schema\Builder
+ */
+ public function getSchemaBuilder()
+ {
+ if (is_null($this->schemaGrammar)) {
+ $this->useDefaultSchemaGrammar();
+ }
+
+ return new SchemaBuilder($this);
+ }
+
+ /**
+ * Begin a fluent query against a database table.
+ *
+ * @param string $table
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public function table($table)
+ {
+ return $this->query()->from($table);
+ }
+
+ /**
+ * Get a new query builder instance.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public function query()
+ {
+ return new QueryBuilder(
+ $this, $this->getQueryGrammar(), $this->getPostProcessor()
+ );
+ }
+
+ /**
+ * Get a new raw query expression.
+ *
+ * @param mixed $value
+ * @return \Illuminate\Database\Query\Expression
+ */
+ public function raw($value)
+ {
+ return new Expression($value);
+ }
+
+ /**
+ * Run a select statement and return a single result.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return mixed
+ */
+ public function selectOne($query, $bindings = [])
+ {
+ $records = $this->select($query, $bindings);
+
+ return count($records) > 0 ? reset($records) : null;
+ }
+
+ /**
+ * Run a select statement against the database.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return array
+ */
+ public function selectFromWriteConnection($query, $bindings = [])
+ {
+ return $this->select($query, $bindings, false);
+ }
+
+ /**
+ * Run a select statement against the database.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @param bool $useReadPdo
+ * @return array
+ */
+ public function select($query, $bindings = [], $useReadPdo = true)
+ {
+ return $this->run($query, $bindings, function ($me, $query, $bindings) use ($useReadPdo) {
+ if ($me->pretending()) {
+ return [];
+ }
+
+ // For select statements, we'll simply execute the query and return an array
+ // of the database result set. Each element in the array will be a single
+ // row from the database table, and will either be an array or objects.
+ $statement = $this->getPdoForSelect($useReadPdo)->prepare($query);
+
+ $statement->execute($me->prepareBindings($bindings));
+
+ return $statement->fetchAll($me->getFetchMode());
+ });
+ }
+
+ /**
+ * Get the PDO connection to use for a select query.
+ *
+ * @param bool $useReadPdo
+ * @return \PDO
+ */
+ protected function getPdoForSelect($useReadPdo = true)
+ {
+ return $useReadPdo ? $this->getReadPdo() : $this->getPdo();
+ }
+
+ /**
+ * Run an insert statement against the database.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return bool
+ */
+ public function insert($query, $bindings = [])
+ {
+ return $this->statement($query, $bindings);
+ }
+
+ /**
+ * Run an update statement against the database.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return int
+ */
+ public function update($query, $bindings = [])
+ {
+ return $this->affectingStatement($query, $bindings);
+ }
+
+ /**
+ * Run a delete statement against the database.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return int
+ */
+ public function delete($query, $bindings = [])
+ {
+ return $this->affectingStatement($query, $bindings);
+ }
+
+ /**
+ * Execute an SQL statement and return the boolean result.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return bool
+ */
+ public function statement($query, $bindings = [])
+ {
+ return $this->run($query, $bindings, function ($me, $query, $bindings) {
+ if ($me->pretending()) {
+ return true;
+ }
+
+ $bindings = $me->prepareBindings($bindings);
+
+ return $me->getPdo()->prepare($query)->execute($bindings);
+ });
+ }
+
+ /**
+ * Run an SQL statement and get the number of rows affected.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return int
+ */
+ public function affectingStatement($query, $bindings = [])
+ {
+ return $this->run($query, $bindings, function ($me, $query, $bindings) {
+ if ($me->pretending()) {
+ return 0;
+ }
+
+ // For update or delete statements, we want to get the number of rows affected
+ // by the statement and return that back to the developer. We'll first need
+ // to execute the statement and then we'll use PDO to fetch the affected.
+ $statement = $me->getPdo()->prepare($query);
+
+ $statement->execute($me->prepareBindings($bindings));
+
+ return $statement->rowCount();
+ });
+ }
+
+ /**
+ * Run a raw, unprepared query against the PDO connection.
+ *
+ * @param string $query
+ * @return bool
+ */
+ public function unprepared($query)
+ {
+ return $this->run($query, [], function ($me, $query) {
+ if ($me->pretending()) {
+ return true;
+ }
+
+ return (bool) $me->getPdo()->exec($query);
+ });
+ }
+
+ /**
+ * Prepare the query bindings for execution.
+ *
+ * @param array $bindings
+ * @return array
+ */
+ public function prepareBindings(array $bindings)
+ {
+ $grammar = $this->getQueryGrammar();
+
+ foreach ($bindings as $key => $value) {
+ // We need to transform all instances of DateTimeInterface into the actual
+ // date string. Each query grammar maintains its own date string format
+ // so we'll just ask the grammar for the format to get from the date.
+ if ($value instanceof DateTimeInterface) {
+ $bindings[$key] = $value->format($grammar->getDateFormat());
+ } elseif ($value === false) {
+ $bindings[$key] = 0;
+ }
+ }
+
+ return $bindings;
+ }
+
+ /**
+ * Execute a Closure within a transaction.
+ *
+ * @param \Closure $callback
+ * @return mixed
+ *
+ * @throws \Throwable
+ */
+ public function transaction(Closure $callback)
+ {
+ $this->beginTransaction();
+
+ // We'll simply execute the given callback within a try / catch block
+ // and if we catch any exception we can rollback the transaction
+ // so that none of the changes are persisted to the database.
+ try {
+ $result = $callback($this);
+
+ $this->commit();
+ }
+
+ // If we catch an exception, we will roll back so nothing gets messed
+ // up in the database. Then we'll re-throw the exception so it can
+ // be handled how the developer sees fit for their applications.
+ catch (Exception $e) {
+ $this->rollBack();
+
+ throw $e;
+ } catch (Throwable $e) {
+ $this->rollBack();
+
+ throw $e;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Start a new database transaction.
+ *
+ * @return void
+ */
+ public function beginTransaction()
+ {
+ ++$this->transactions;
+
+ if ($this->transactions == 1) {
+ $this->pdo->beginTransaction();
+ } elseif ($this->transactions > 1 && $this->queryGrammar->supportsSavepoints()) {
+ $this->pdo->exec(
+ $this->queryGrammar->compileSavepoint('trans'.$this->transactions)
+ );
+ }
+
+ $this->fireConnectionEvent('beganTransaction');
+ }
+
+ /**
+ * Commit the active database transaction.
+ *
+ * @return void
+ */
+ public function commit()
+ {
+ if ($this->transactions == 1) {
+ $this->pdo->commit();
+ }
+
+ --$this->transactions;
+
+ $this->fireConnectionEvent('committed');
+ }
+
+ /**
+ * Rollback the active database transaction.
+ *
+ * @return void
+ */
+ public function rollBack()
+ {
+ if ($this->transactions == 1) {
+ $this->pdo->rollBack();
+ } elseif ($this->transactions > 1 && $this->queryGrammar->supportsSavepoints()) {
+ $this->pdo->exec(
+ $this->queryGrammar->compileSavepointRollBack('trans'.$this->transactions)
+ );
+ }
+
+ $this->transactions = max(0, $this->transactions - 1);
+
+ $this->fireConnectionEvent('rollingBack');
+ }
+
+ /**
+ * Get the number of active transactions.
+ *
+ * @return int
+ */
+ public function transactionLevel()
+ {
+ return $this->transactions;
+ }
+
+ /**
+ * Execute the given callback in "dry run" mode.
+ *
+ * @param \Closure $callback
+ * @return array
+ */
+ public function pretend(Closure $callback)
+ {
+ $loggingQueries = $this->loggingQueries;
+
+ $this->enableQueryLog();
+
+ $this->pretending = true;
+
+ $this->queryLog = [];
+
+ // Basically to make the database connection "pretend", we will just return
+ // the default values for all the query methods, then we will return an
+ // array of queries that were "executed" within the Closure callback.
+ $callback($this);
+
+ $this->pretending = false;
+
+ $this->loggingQueries = $loggingQueries;
+
+ return $this->queryLog;
+ }
+
+ /**
+ * Run a SQL statement and log its execution context.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @param \Closure $callback
+ * @return mixed
+ *
+ * @throws \Illuminate\Database\QueryException
+ */
+ protected function run($query, $bindings, Closure $callback)
+ {
+ $this->reconnectIfMissingConnection();
+
+ $start = microtime(true);
+
+ // Here we will run this query. If an exception occurs we'll determine if it was
+ // caused by a connection that has been lost. If that is the cause, we'll try
+ // to re-establish connection and re-run the query with a fresh connection.
+ try {
+ $result = $this->runQueryCallback($query, $bindings, $callback);
+ } catch (QueryException $e) {
+ $result = $this->tryAgainIfCausedByLostConnection(
+ $e, $query, $bindings, $callback
+ );
+ }
+
+ // Once we have run the query we will calculate the time that it took to run and
+ // then log the query, bindings, and execution time so we will report them on
+ // the event that the developer needs them. We'll log time in milliseconds.
+ $time = $this->getElapsedTime($start);
+
+ $this->logQuery($query, $bindings, $time);
+
+ return $result;
+ }
+
+ /**
+ * Run a SQL statement.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @param \Closure $callback
+ * @return mixed
+ *
+ * @throws \Illuminate\Database\QueryException
+ */
+ protected function runQueryCallback($query, $bindings, Closure $callback)
+ {
+ // To execute the statement, we'll simply call the callback, which will actually
+ // run the SQL against the PDO connection. Then we can calculate the time it
+ // took to execute and log the query SQL, bindings and time in our memory.
+ try {
+ $result = $callback($this, $query, $bindings);
+ }
+
+ // If an exception occurs when attempting to run a query, we'll format the error
+ // message to include the bindings with SQL, which will make this exception a
+ // lot more helpful to the developer instead of just the database's errors.
+ catch (Exception $e) {
+ throw new QueryException(
+ $query, $this->prepareBindings($bindings), $e
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * Handle a query exception that occurred during query execution.
+ *
+ * @param \Illuminate\Database\QueryException $e
+ * @param string $query
+ * @param array $bindings
+ * @param \Closure $callback
+ * @return mixed
+ *
+ * @throws \Illuminate\Database\QueryException
+ */
+ protected function tryAgainIfCausedByLostConnection(QueryException $e, $query, $bindings, Closure $callback)
+ {
+ if ($this->causedByLostConnection($e->getPrevious())) {
+ $this->reconnect();
+
+ return $this->runQueryCallback($query, $bindings, $callback);
+ }
+
+ throw $e;
+ }
+
+ /**
+ * Disconnect from the underlying PDO connection.
+ *
+ * @return void
+ */
+ public function disconnect()
+ {
+ $this->setPdo(null)->setReadPdo(null);
+ }
+
+ /**
+ * Reconnect to the database.
+ *
+ * @return void
+ *
+ * @throws \LogicException
+ */
+ public function reconnect()
+ {
+ if (is_callable($this->reconnector)) {
+ return call_user_func($this->reconnector, $this);
+ }
+
+ throw new LogicException('Lost connection and no reconnector available.');
+ }
+
+ /**
+ * Reconnect to the database if a PDO connection is missing.
+ *
+ * @return void
+ */
+ protected function reconnectIfMissingConnection()
+ {
+ if (is_null($this->getPdo()) || is_null($this->getReadPdo())) {
+ $this->reconnect();
+ }
+ }
+
+ /**
+ * Log a query in the connection's query log.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @param float|null $time
+ * @return void
+ */
+ public function logQuery($query, $bindings, $time = null)
+ {
+ if (isset($this->events)) {
+ $this->events->fire(new Events\QueryExecuted(
+ $query, $bindings, $time, $this
+ ));
+ }
+
+ if ($this->loggingQueries) {
+ $this->queryLog[] = compact('query', 'bindings', 'time');
+ }
+ }
+
+ /**
+ * Register a database query listener with the connection.
+ *
+ * @param \Closure $callback
+ * @return void
+ */
+ public function listen(Closure $callback)
+ {
+ if (isset($this->events)) {
+ $this->events->listen(Events\QueryExecuted::class, $callback);
+ }
+ }
+
+ /**
+ * Fire an event for this connection.
+ *
+ * @param string $event
+ * @return void
+ */
+ protected function fireConnectionEvent($event)
+ {
+ if (! isset($this->events)) {
+ return;
+ }
+
+ switch ($event) {
+ case 'beganTransaction':
+ return $this->events->fire(new Events\TransactionBeginning($this));
+ case 'committed':
+ return $this->events->fire(new Events\TransactionCommitted($this));
+ case 'rollingBack':
+ return $this->events->fire(new Events\TransactionRolledBack($this));
+ }
+ }
+
+ /**
+ * Get the elapsed time since a given starting point.
+ *
+ * @param int $start
+ * @return float
+ */
+ protected function getElapsedTime($start)
+ {
+ return round((microtime(true) - $start) * 1000, 2);
+ }
+
+ /**
+ * Is Doctrine available?
+ *
+ * @return bool
+ */
+ public function isDoctrineAvailable()
+ {
+ return class_exists('Doctrine\DBAL\Connection');
+ }
+
+ /**
+ * Get a Doctrine Schema Column instance.
+ *
+ * @param string $table
+ * @param string $column
+ * @return \Doctrine\DBAL\Schema\Column
+ */
+ public function getDoctrineColumn($table, $column)
+ {
+ $schema = $this->getDoctrineSchemaManager();
+
+ return $schema->listTableDetails($table)->getColumn($column);
+ }
+
+ /**
+ * Get the Doctrine DBAL schema manager for the connection.
+ *
+ * @return \Doctrine\DBAL\Schema\AbstractSchemaManager
+ */
+ public function getDoctrineSchemaManager()
+ {
+ return $this->getDoctrineDriver()->getSchemaManager($this->getDoctrineConnection());
+ }
+
+ /**
+ * Get the Doctrine DBAL database connection instance.
+ *
+ * @return \Doctrine\DBAL\Connection
+ */
+ public function getDoctrineConnection()
+ {
+ if (is_null($this->doctrineConnection)) {
+ $driver = $this->getDoctrineDriver();
+
+ $data = ['pdo' => $this->pdo, 'dbname' => $this->getConfig('database')];
+
+ $this->doctrineConnection = new DoctrineConnection($data, $driver);
+ }
+
+ return $this->doctrineConnection;
+ }
+
+ /**
+ * Get the current PDO connection.
+ *
+ * @return \PDO
+ */
+ public function getPdo()
+ {
+ return $this->pdo;
+ }
+
+ /**
+ * Get the current PDO connection used for reading.
+ *
+ * @return \PDO
+ */
+ public function getReadPdo()
+ {
+ if ($this->transactions >= 1) {
+ return $this->getPdo();
+ }
+
+ return $this->readPdo ?: $this->pdo;
+ }
+
+ /**
+ * Set the PDO connection.
+ *
+ * @param \PDO|null $pdo
+ * @return $this
+ */
+ public function setPdo($pdo)
+ {
+ if ($this->transactions >= 1) {
+ throw new RuntimeException("Can't swap PDO instance while within transaction.");
+ }
+
+ $this->pdo = $pdo;
+
+ return $this;
+ }
+
+ /**
+ * Set the PDO connection used for reading.
+ *
+ * @param \PDO|null $pdo
+ * @return $this
+ */
+ public function setReadPdo($pdo)
+ {
+ $this->readPdo = $pdo;
+
+ return $this;
+ }
+
+ /**
+ * Set the reconnect instance on the connection.
+ *
+ * @param callable $reconnector
+ * @return $this
+ */
+ public function setReconnector(callable $reconnector)
+ {
+ $this->reconnector = $reconnector;
+
+ return $this;
+ }
+
+ /**
+ * Get the database connection name.
+ *
+ * @return string|null
+ */
+ public function getName()
+ {
+ return $this->getConfig('name');
+ }
+
+ /**
+ * Get an option from the configuration options.
+ *
+ * @param string $option
+ * @return mixed
+ */
+ public function getConfig($option)
+ {
+ return Arr::get($this->config, $option);
+ }
+
+ /**
+ * Get the PDO driver name.
+ *
+ * @return string
+ */
+ public function getDriverName()
+ {
+ return $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
+ }
+
+ /**
+ * Get the query grammar used by the connection.
+ *
+ * @return \Illuminate\Database\Query\Grammars\Grammar
+ */
+ public function getQueryGrammar()
+ {
+ return $this->queryGrammar;
+ }
+
+ /**
+ * Set the query grammar used by the connection.
+ *
+ * @param \Illuminate\Database\Query\Grammars\Grammar $grammar
+ * @return void
+ */
+ public function setQueryGrammar(Query\Grammars\Grammar $grammar)
+ {
+ $this->queryGrammar = $grammar;
+ }
+
+ /**
+ * Get the schema grammar used by the connection.
+ *
+ * @return \Illuminate\Database\Schema\Grammars\Grammar
+ */
+ public function getSchemaGrammar()
+ {
+ return $this->schemaGrammar;
+ }
+
+ /**
+ * Set the schema grammar used by the connection.
+ *
+ * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
+ * @return void
+ */
+ public function setSchemaGrammar(Schema\Grammars\Grammar $grammar)
+ {
+ $this->schemaGrammar = $grammar;
+ }
+
+ /**
+ * Get the query post processor used by the connection.
+ *
+ * @return \Illuminate\Database\Query\Processors\Processor
+ */
+ public function getPostProcessor()
+ {
+ return $this->postProcessor;
+ }
+
+ /**
+ * Set the query post processor used by the connection.
+ *
+ * @param \Illuminate\Database\Query\Processors\Processor $processor
+ * @return void
+ */
+ public function setPostProcessor(Processor $processor)
+ {
+ $this->postProcessor = $processor;
+ }
+
+ /**
+ * Get the event dispatcher used by the connection.
+ *
+ * @return \Illuminate\Contracts\Events\Dispatcher
+ */
+ public function getEventDispatcher()
+ {
+ return $this->events;
+ }
+
+ /**
+ * Set the event dispatcher instance on the connection.
+ *
+ * @param \Illuminate\Contracts\Events\Dispatcher $events
+ * @return void
+ */
+ public function setEventDispatcher(Dispatcher $events)
+ {
+ $this->events = $events;
+ }
+
+ /**
+ * Determine if the connection in a "dry run".
+ *
+ * @return bool
+ */
+ public function pretending()
+ {
+ return $this->pretending === true;
+ }
+
+ /**
+ * Get the default fetch mode for the connection.
+ *
+ * @return int
+ */
+ public function getFetchMode()
+ {
+ return $this->fetchMode;
+ }
+
+ /**
+ * Set the default fetch mode for the connection.
+ *
+ * @param int $fetchMode
+ * @return int
+ */
+ public function setFetchMode($fetchMode)
+ {
+ $this->fetchMode = $fetchMode;
+ }
+
+ /**
+ * Get the connection query log.
+ *
+ * @return array
+ */
+ public function getQueryLog()
+ {
+ return $this->queryLog;
+ }
+
+ /**
+ * Clear the query log.
+ *
+ * @return void
+ */
+ public function flushQueryLog()
+ {
+ $this->queryLog = [];
+ }
+
+ /**
+ * Enable the query log on the connection.
+ *
+ * @return void
+ */
+ public function enableQueryLog()
+ {
+ $this->loggingQueries = true;
+ }
+
+ /**
+ * Disable the query log on the connection.
+ *
+ * @return void
+ */
+ public function disableQueryLog()
+ {
+ $this->loggingQueries = false;
+ }
+
+ /**
+ * Determine whether we're logging queries.
+ *
+ * @return bool
+ */
+ public function logging()
+ {
+ return $this->loggingQueries;
+ }
+
+ /**
+ * Get the name of the connected database.
+ *
+ * @return string
+ */
+ public function getDatabaseName()
+ {
+ return $this->database;
+ }
+
+ /**
+ * Set the name of the connected database.
+ *
+ * @param string $database
+ * @return string
+ */
+ public function setDatabaseName($database)
+ {
+ $this->database = $database;
+ }
+
+ /**
+ * Get the table prefix for the connection.
+ *
+ * @return string
+ */
+ public function getTablePrefix()
+ {
+ return $this->tablePrefix;
+ }
+
+ /**
+ * Set the table prefix in use by the connection.
+ *
+ * @param string $prefix
+ * @return void
+ */
+ public function setTablePrefix($prefix)
+ {
+ $this->tablePrefix = $prefix;
+
+ $this->getQueryGrammar()->setTablePrefix($prefix);
+ }
+
+ /**
+ * Set the table prefix and return the grammar.
+ *
+ * @param \Illuminate\Database\Grammar $grammar
+ * @return \Illuminate\Database\Grammar
+ */
+ public function withTablePrefix(Grammar $grammar)
+ {
+ $grammar->setTablePrefix($this->tablePrefix);
+
+ return $grammar;
+ }
+}
diff --git a/vendor/illuminate/database/ConnectionInterface.php b/vendor/illuminate/database/ConnectionInterface.php
new file mode 100755
index 00000000..16eb6675
--- /dev/null
+++ b/vendor/illuminate/database/ConnectionInterface.php
@@ -0,0 +1,149 @@
+ $connection) {
+ $this->addConnection($name, $connection);
+ }
+ }
+
+ /**
+ * Get a database connection instance.
+ *
+ * @param string $name
+ * @return \Illuminate\Database\ConnectionInterface
+ */
+ public function connection($name = null)
+ {
+ if (is_null($name)) {
+ $name = $this->getDefaultConnection();
+ }
+
+ return $this->connections[$name];
+ }
+
+ /**
+ * Add a connection to the resolver.
+ *
+ * @param string $name
+ * @param \Illuminate\Database\ConnectionInterface $connection
+ * @return void
+ */
+ public function addConnection($name, ConnectionInterface $connection)
+ {
+ $this->connections[$name] = $connection;
+ }
+
+ /**
+ * Check if a connection has been registered.
+ *
+ * @param string $name
+ * @return bool
+ */
+ public function hasConnection($name)
+ {
+ return isset($this->connections[$name]);
+ }
+
+ /**
+ * Get the default connection name.
+ *
+ * @return string
+ */
+ public function getDefaultConnection()
+ {
+ return $this->default;
+ }
+
+ /**
+ * Set the default connection name.
+ *
+ * @param string $name
+ * @return void
+ */
+ public function setDefaultConnection($name)
+ {
+ $this->default = $name;
+ }
+}
diff --git a/vendor/illuminate/database/ConnectionResolverInterface.php b/vendor/illuminate/database/ConnectionResolverInterface.php
new file mode 100755
index 00000000..eb0397a5
--- /dev/null
+++ b/vendor/illuminate/database/ConnectionResolverInterface.php
@@ -0,0 +1,29 @@
+container = $container;
+ }
+
+ /**
+ * Establish a PDO connection based on the configuration.
+ *
+ * @param array $config
+ * @param string $name
+ * @return \Illuminate\Database\Connection
+ */
+ public function make(array $config, $name = null)
+ {
+ $config = $this->parseConfig($config, $name);
+
+ if (isset($config['read'])) {
+ return $this->createReadWriteConnection($config);
+ }
+
+ return $this->createSingleConnection($config);
+ }
+
+ /**
+ * Create a single database connection instance.
+ *
+ * @param array $config
+ * @return \Illuminate\Database\Connection
+ */
+ protected function createSingleConnection(array $config)
+ {
+ $pdo = $this->createConnector($config)->connect($config);
+
+ return $this->createConnection($config['driver'], $pdo, $config['database'], $config['prefix'], $config);
+ }
+
+ /**
+ * Create a single database connection instance.
+ *
+ * @param array $config
+ * @return \Illuminate\Database\Connection
+ */
+ protected function createReadWriteConnection(array $config)
+ {
+ $connection = $this->createSingleConnection($this->getWriteConfig($config));
+
+ return $connection->setReadPdo($this->createReadPdo($config));
+ }
+
+ /**
+ * Create a new PDO instance for reading.
+ *
+ * @param array $config
+ * @return \PDO
+ */
+ protected function createReadPdo(array $config)
+ {
+ $readConfig = $this->getReadConfig($config);
+
+ return $this->createConnector($readConfig)->connect($readConfig);
+ }
+
+ /**
+ * Get the read configuration for a read / write connection.
+ *
+ * @param array $config
+ * @return array
+ */
+ protected function getReadConfig(array $config)
+ {
+ $readConfig = $this->getReadWriteConfig($config, 'read');
+
+ if (isset($readConfig['host']) && is_array($readConfig['host'])) {
+ $readConfig['host'] = count($readConfig['host']) > 1
+ ? $readConfig['host'][array_rand($readConfig['host'])]
+ : $readConfig['host'][0];
+ }
+
+ return $this->mergeReadWriteConfig($config, $readConfig);
+ }
+
+ /**
+ * Get the read configuration for a read / write connection.
+ *
+ * @param array $config
+ * @return array
+ */
+ protected function getWriteConfig(array $config)
+ {
+ $writeConfig = $this->getReadWriteConfig($config, 'write');
+
+ return $this->mergeReadWriteConfig($config, $writeConfig);
+ }
+
+ /**
+ * Get a read / write level configuration.
+ *
+ * @param array $config
+ * @param string $type
+ * @return array
+ */
+ protected function getReadWriteConfig(array $config, $type)
+ {
+ if (isset($config[$type][0])) {
+ return $config[$type][array_rand($config[$type])];
+ }
+
+ return $config[$type];
+ }
+
+ /**
+ * Merge a configuration for a read / write connection.
+ *
+ * @param array $config
+ * @param array $merge
+ * @return array
+ */
+ protected function mergeReadWriteConfig(array $config, array $merge)
+ {
+ return Arr::except(array_merge($config, $merge), ['read', 'write']);
+ }
+
+ /**
+ * Parse and prepare the database configuration.
+ *
+ * @param array $config
+ * @param string $name
+ * @return array
+ */
+ protected function parseConfig(array $config, $name)
+ {
+ return Arr::add(Arr::add($config, 'prefix', ''), 'name', $name);
+ }
+
+ /**
+ * Create a connector instance based on the configuration.
+ *
+ * @param array $config
+ * @return \Illuminate\Database\Connectors\ConnectorInterface
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function createConnector(array $config)
+ {
+ if (! isset($config['driver'])) {
+ throw new InvalidArgumentException('A driver must be specified.');
+ }
+
+ if ($this->container->bound($key = "db.connector.{$config['driver']}")) {
+ return $this->container->make($key);
+ }
+
+ switch ($config['driver']) {
+ case 'mysql':
+ return new MySqlConnector;
+
+ case 'pgsql':
+ return new PostgresConnector;
+
+ case 'sqlite':
+ return new SQLiteConnector;
+
+ case 'sqlsrv':
+ return new SqlServerConnector;
+ }
+
+ throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]");
+ }
+
+ /**
+ * Create a new connection instance.
+ *
+ * @param string $driver
+ * @param \PDO $connection
+ * @param string $database
+ * @param string $prefix
+ * @param array $config
+ * @return \Illuminate\Database\Connection
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function createConnection($driver, PDO $connection, $database, $prefix = '', array $config = [])
+ {
+ if ($this->container->bound($key = "db.connection.{$driver}")) {
+ return $this->container->make($key, [$connection, $database, $prefix, $config]);
+ }
+
+ switch ($driver) {
+ case 'mysql':
+ return new MySqlConnection($connection, $database, $prefix, $config);
+
+ case 'pgsql':
+ return new PostgresConnection($connection, $database, $prefix, $config);
+
+ case 'sqlite':
+ return new SQLiteConnection($connection, $database, $prefix, $config);
+
+ case 'sqlsrv':
+ return new SqlServerConnection($connection, $database, $prefix, $config);
+ }
+
+ throw new InvalidArgumentException("Unsupported driver [$driver]");
+ }
+}
diff --git a/vendor/illuminate/database/Connectors/Connector.php b/vendor/illuminate/database/Connectors/Connector.php
new file mode 100755
index 00000000..ea2637c7
--- /dev/null
+++ b/vendor/illuminate/database/Connectors/Connector.php
@@ -0,0 +1,106 @@
+ PDO::CASE_NATURAL,
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+ PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
+ PDO::ATTR_STRINGIFY_FETCHES => false,
+ PDO::ATTR_EMULATE_PREPARES => false,
+ ];
+
+ /**
+ * Get the PDO options based on the configuration.
+ *
+ * @param array $config
+ * @return array
+ */
+ public function getOptions(array $config)
+ {
+ $options = Arr::get($config, 'options', []);
+
+ return array_diff_key($this->options, $options) + $options;
+ }
+
+ /**
+ * Create a new PDO connection.
+ *
+ * @param string $dsn
+ * @param array $config
+ * @param array $options
+ * @return \PDO
+ */
+ public function createConnection($dsn, array $config, array $options)
+ {
+ $username = Arr::get($config, 'username');
+
+ $password = Arr::get($config, 'password');
+
+ try {
+ $pdo = new PDO($dsn, $username, $password, $options);
+ } catch (Exception $e) {
+ $pdo = $this->tryAgainIfCausedByLostConnection(
+ $e, $dsn, $username, $password, $options
+ );
+ }
+
+ return $pdo;
+ }
+
+ /**
+ * Get the default PDO connection options.
+ *
+ * @return array
+ */
+ public function getDefaultOptions()
+ {
+ return $this->options;
+ }
+
+ /**
+ * Set the default PDO connection options.
+ *
+ * @param array $options
+ * @return void
+ */
+ public function setDefaultOptions(array $options)
+ {
+ $this->options = $options;
+ }
+
+ /**
+ * Handle a exception that occurred during connect execution.
+ *
+ * @param \Exception $e
+ * @param string $dsn
+ * @param string $username
+ * @param string $password
+ * @param array $options
+ * @return \PDO
+ *
+ * @throws \Exception
+ */
+ protected function tryAgainIfCausedByLostConnection(Exception $e, $dsn, $username, $password, $options)
+ {
+ if ($this->causedByLostConnection($e)) {
+ return new PDO($dsn, $username, $password, $options);
+ }
+
+ throw $e;
+ }
+}
diff --git a/vendor/illuminate/database/Connectors/ConnectorInterface.php b/vendor/illuminate/database/Connectors/ConnectorInterface.php
new file mode 100755
index 00000000..08597ac0
--- /dev/null
+++ b/vendor/illuminate/database/Connectors/ConnectorInterface.php
@@ -0,0 +1,14 @@
+getDsn($config);
+
+ $options = $this->getOptions($config);
+
+ // We need to grab the PDO options that should be used while making the brand
+ // new connection instance. The PDO options control various aspects of the
+ // connection's behavior, and some might be specified by the developers.
+ $connection = $this->createConnection($dsn, $config, $options);
+
+ if (isset($config['unix_socket'])) {
+ $connection->exec("use `{$config['database']}`;");
+ }
+
+ $collation = $config['collation'];
+
+ // Next we will set the "names" and "collation" on the clients connections so
+ // a correct character set will be used by this client. The collation also
+ // is set on the server but needs to be set here on this client objects.
+ $charset = $config['charset'];
+
+ $names = "set names '$charset'".
+ (! is_null($collation) ? " collate '$collation'" : '');
+
+ $connection->prepare($names)->execute();
+
+ // Next, we will check to see if a timezone has been specified in this config
+ // and if it has we will issue a statement to modify the timezone with the
+ // database. Setting this DB timezone is an optional configuration item.
+ if (isset($config['timezone'])) {
+ $connection->prepare(
+ 'set time_zone="'.$config['timezone'].'"'
+ )->execute();
+ }
+
+ // If the "strict" option has been configured for the connection we will setup
+ // strict mode for this session. Strict mode enforces some extra rules when
+ // using the MySQL database system and is a quicker way to enforce them.
+ if (isset($config['strict'])) {
+ if ($config['strict']) {
+ $connection->prepare("set session sql_mode='STRICT_ALL_TABLES'")->execute();
+ } else {
+ $connection->prepare("set session sql_mode=''")->execute();
+ }
+ }
+
+ return $connection;
+ }
+
+ /**
+ * Create a DSN string from a configuration.
+ *
+ * Chooses socket or host/port based on the 'unix_socket' config value.
+ *
+ * @param array $config
+ * @return string
+ */
+ protected function getDsn(array $config)
+ {
+ return $this->configHasSocket($config) ? $this->getSocketDsn($config) : $this->getHostDsn($config);
+ }
+
+ /**
+ * Determine if the given configuration array has a UNIX socket value.
+ *
+ * @param array $config
+ * @return bool
+ */
+ protected function configHasSocket(array $config)
+ {
+ return isset($config['unix_socket']) && ! empty($config['unix_socket']);
+ }
+
+ /**
+ * Get the DSN string for a socket configuration.
+ *
+ * @param array $config
+ * @return string
+ */
+ protected function getSocketDsn(array $config)
+ {
+ return "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}";
+ }
+
+ /**
+ * Get the DSN string for a host / port configuration.
+ *
+ * @param array $config
+ * @return string
+ */
+ protected function getHostDsn(array $config)
+ {
+ extract($config);
+
+ return isset($port)
+ ? "mysql:host={$host};port={$port};dbname={$database}"
+ : "mysql:host={$host};dbname={$database}";
+ }
+}
diff --git a/vendor/illuminate/database/Connectors/PostgresConnector.php b/vendor/illuminate/database/Connectors/PostgresConnector.php
new file mode 100755
index 00000000..05fb5a43
--- /dev/null
+++ b/vendor/illuminate/database/Connectors/PostgresConnector.php
@@ -0,0 +1,117 @@
+ PDO::CASE_NATURAL,
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+ PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
+ PDO::ATTR_STRINGIFY_FETCHES => false,
+ ];
+
+ /**
+ * Establish a database connection.
+ *
+ * @param array $config
+ * @return \PDO
+ */
+ public function connect(array $config)
+ {
+ // First we'll create the basic DSN and connection instance connecting to the
+ // using the configuration option specified by the developer. We will also
+ // set the default character set on the connections to UTF-8 by default.
+ $dsn = $this->getDsn($config);
+
+ $options = $this->getOptions($config);
+
+ $connection = $this->createConnection($dsn, $config, $options);
+
+ $charset = $config['charset'];
+
+ $connection->prepare("set names '$charset'")->execute();
+
+ // Next, we will check to see if a timezone has been specified in this config
+ // and if it has we will issue a statement to modify the timezone with the
+ // database. Setting this DB timezone is an optional configuration item.
+ if (isset($config['timezone'])) {
+ $timezone = $config['timezone'];
+
+ $connection->prepare("set time zone '$timezone'")->execute();
+ }
+
+ // Unlike MySQL, Postgres allows the concept of "schema" and a default schema
+ // may have been specified on the connections. If that is the case we will
+ // set the default schema search paths to the specified database schema.
+ if (isset($config['schema'])) {
+ $schema = $this->formatSchema($config['schema']);
+
+ $connection->prepare("set search_path to {$schema}")->execute();
+ }
+
+ // Postgres allows an application_name to be set by the user and this name is
+ // used to when monitoring the application with pg_stat_activity. So we'll
+ // determine if the option has been specified and run a statement if so.
+ if (isset($config['application_name'])) {
+ $applicationName = $config['application_name'];
+
+ $connection->prepare("set application_name to '$applicationName'")->execute();
+ }
+
+ return $connection;
+ }
+
+ /**
+ * Create a DSN string from a configuration.
+ *
+ * @param array $config
+ * @return string
+ */
+ protected function getDsn(array $config)
+ {
+ // First we will create the basic DSN setup as well as the port if it is in
+ // in the configuration options. This will give us the basic DSN we will
+ // need to establish the PDO connections and return them back for use.
+ extract($config);
+
+ $host = isset($host) ? "host={$host};" : '';
+
+ $dsn = "pgsql:{$host}dbname={$database}";
+
+ // If a port was specified, we will add it to this Postgres DSN connections
+ // format. Once we have done that we are ready to return this connection
+ // string back out for usage, as this has been fully constructed here.
+ if (isset($config['port'])) {
+ $dsn .= ";port={$port}";
+ }
+
+ if (isset($config['sslmode'])) {
+ $dsn .= ";sslmode={$sslmode}";
+ }
+
+ return $dsn;
+ }
+
+ /**
+ * Format the schema for the DSN.
+ *
+ * @param array|string $schema
+ * @return string
+ */
+ protected function formatSchema($schema)
+ {
+ if (is_array($schema)) {
+ return '"'.implode('", "', $schema).'"';
+ } else {
+ return '"'.$schema.'"';
+ }
+ }
+}
diff --git a/vendor/illuminate/database/Connectors/SQLiteConnector.php b/vendor/illuminate/database/Connectors/SQLiteConnector.php
new file mode 100755
index 00000000..28f90915
--- /dev/null
+++ b/vendor/illuminate/database/Connectors/SQLiteConnector.php
@@ -0,0 +1,39 @@
+getOptions($config);
+
+ // SQLite supports "in-memory" databases that only last as long as the owning
+ // connection does. These are useful for tests or for short lifetime store
+ // querying. In-memory databases may only have a single open connection.
+ if ($config['database'] == ':memory:') {
+ return $this->createConnection('sqlite::memory:', $config, $options);
+ }
+
+ $path = realpath($config['database']);
+
+ // Here we'll verify that the SQLite database exists before going any further
+ // as the developer probably wants to know if the database exists and this
+ // SQLite driver will not throw any exception if it does not by default.
+ if ($path === false) {
+ throw new InvalidArgumentException("Database (${config['database']}) does not exist.");
+ }
+
+ return $this->createConnection("sqlite:{$path}", $config, $options);
+ }
+}
diff --git a/vendor/illuminate/database/Connectors/SqlServerConnector.php b/vendor/illuminate/database/Connectors/SqlServerConnector.php
new file mode 100755
index 00000000..46e0b841
--- /dev/null
+++ b/vendor/illuminate/database/Connectors/SqlServerConnector.php
@@ -0,0 +1,137 @@
+ PDO::CASE_NATURAL,
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+ PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
+ PDO::ATTR_STRINGIFY_FETCHES => false,
+ ];
+
+ /**
+ * Establish a database connection.
+ *
+ * @param array $config
+ * @return \PDO
+ */
+ public function connect(array $config)
+ {
+ $options = $this->getOptions($config);
+
+ return $this->createConnection($this->getDsn($config), $config, $options);
+ }
+
+ /**
+ * Create a DSN string from a configuration.
+ *
+ * @param array $config
+ * @return string
+ */
+ protected function getDsn(array $config)
+ {
+ // First we will create the basic DSN setup as well as the port if it is in
+ // in the configuration options. This will give us the basic DSN we will
+ // need to establish the PDO connections and return them back for use.
+ if (in_array('dblib', $this->getAvailableDrivers())) {
+ return $this->getDblibDsn($config);
+ } else {
+ return $this->getSqlSrvDsn($config);
+ }
+ }
+
+ /**
+ * Get the DSN string for a DbLib connection.
+ *
+ * @param array $config
+ * @return string
+ */
+ protected function getDblibDsn(array $config)
+ {
+ $arguments = [
+ 'host' => $this->buildHostString($config, ':'),
+ 'dbname' => $config['database'],
+ ];
+
+ $arguments = array_merge(
+ $arguments, Arr::only($config, ['appname', 'charset'])
+ );
+
+ return $this->buildConnectString('dblib', $arguments);
+ }
+
+ /**
+ * Get the DSN string for a SqlSrv connection.
+ *
+ * @param array $config
+ * @return string
+ */
+ protected function getSqlSrvDsn(array $config)
+ {
+ $arguments = [
+ 'Server' => $this->buildHostString($config, ','),
+ ];
+
+ if (isset($config['database'])) {
+ $arguments['Database'] = $config['database'];
+ }
+
+ if (isset($config['appname'])) {
+ $arguments['APP'] = $config['appname'];
+ }
+
+ return $this->buildConnectString('sqlsrv', $arguments);
+ }
+
+ /**
+ * Build a connection string from the given arguments.
+ *
+ * @param string $driver
+ * @param array $arguments
+ * @return string
+ */
+ protected function buildConnectString($driver, array $arguments)
+ {
+ $options = array_map(function ($key) use ($arguments) {
+ return sprintf('%s=%s', $key, $arguments[$key]);
+ }, array_keys($arguments));
+
+ return $driver.':'.implode(';', $options);
+ }
+
+ /**
+ * Build a host string from the given configuration.
+ *
+ * @param array $config
+ * @param string $separator
+ * @return string
+ */
+ protected function buildHostString(array $config, $separator)
+ {
+ if (isset($config['port'])) {
+ return $config['host'].$separator.$config['port'];
+ } else {
+ return $config['host'];
+ }
+ }
+
+ /**
+ * Get the available PDO drivers.
+ *
+ * @return array
+ */
+ protected function getAvailableDrivers()
+ {
+ return PDO::getAvailableDrivers();
+ }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/BaseCommand.php b/vendor/illuminate/database/Console/Migrations/BaseCommand.php
new file mode 100755
index 00000000..f3459ac9
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/BaseCommand.php
@@ -0,0 +1,18 @@
+laravel->databasePath().'/migrations';
+ }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/InstallCommand.php b/vendor/illuminate/database/Console/Migrations/InstallCommand.php
new file mode 100755
index 00000000..103dcaa9
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/InstallCommand.php
@@ -0,0 +1,70 @@
+repository = $repository;
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function fire()
+ {
+ $this->repository->setSource($this->input->getOption('database'));
+
+ $this->repository->createRepository();
+
+ $this->info('Migration table created successfully.');
+ }
+
+ /**
+ * Get the console command options.
+ *
+ * @return array
+ */
+ protected function getOptions()
+ {
+ return [
+ ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
+ ];
+ }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/MigrateCommand.php b/vendor/illuminate/database/Console/Migrations/MigrateCommand.php
new file mode 100755
index 00000000..38c51b66
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/MigrateCommand.php
@@ -0,0 +1,131 @@
+migrator = $migrator;
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function fire()
+ {
+ if (! $this->confirmToProceed()) {
+ return;
+ }
+
+ $this->prepareDatabase();
+
+ // The pretend option can be used for "simulating" the migration and grabbing
+ // the SQL queries that would fire if the migration were to be run against
+ // a database for real, which is helpful for double checking migrations.
+ $pretend = $this->input->getOption('pretend');
+
+ // Next, we will check to see if a path option has been defined. If it has
+ // we will use the path relative to the root of this installation folder
+ // so that migrations may be run for any path within the applications.
+ if (! is_null($path = $this->input->getOption('path'))) {
+ $path = $this->laravel->basePath().'/'.$path;
+ } else {
+ $path = $this->getMigrationPath();
+ }
+
+ $this->migrator->run($path, [
+ 'pretend' => $pretend,
+ 'step' => $this->input->getOption('step'),
+ ]);
+
+ // Once the migrator has run we will grab the note output and send it out to
+ // the console screen, since the migrator itself functions without having
+ // any instances of the OutputInterface contract passed into the class.
+ foreach ($this->migrator->getNotes() as $note) {
+ $this->output->writeln($note);
+ }
+
+ // Finally, if the "seed" option has been given, we will re-run the database
+ // seed task to re-populate the database, which is convenient when adding
+ // a migration and a seed at the same time, as it is only this command.
+ if ($this->input->getOption('seed')) {
+ $this->call('db:seed', ['--force' => true]);
+ }
+ }
+
+ /**
+ * Prepare the migration database for running.
+ *
+ * @return void
+ */
+ protected function prepareDatabase()
+ {
+ $this->migrator->setConnection($this->input->getOption('database'));
+
+ if (! $this->migrator->repositoryExists()) {
+ $options = ['--database' => $this->input->getOption('database')];
+
+ $this->call('migrate:install', $options);
+ }
+ }
+
+ /**
+ * Get the console command options.
+ *
+ * @return array
+ */
+ protected function getOptions()
+ {
+ return [
+ ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
+
+ ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
+
+ ['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to be executed.'],
+
+ ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],
+
+ ['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'],
+
+ ['step', null, InputOption::VALUE_NONE, 'Force the migrations to be run so they can be rolled back individually.'],
+ ];
+ }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php b/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php
new file mode 100644
index 00000000..6990910e
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php
@@ -0,0 +1,114 @@
+creator = $creator;
+ $this->composer = $composer;
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function fire()
+ {
+ // It's possible for the developer to specify the tables to modify in this
+ // schema operation. The developer may also specify if this table needs
+ // to be freshly created so we can create the appropriate migrations.
+ $name = $this->input->getArgument('name');
+
+ $table = $this->input->getOption('table');
+
+ $create = $this->input->getOption('create');
+
+ if (! $table && is_string($create)) {
+ $table = $create;
+ }
+
+ // Now we are ready to write the migration out to disk. Once we've written
+ // the migration out, we will dump-autoload for the entire framework to
+ // make sure that the migrations are registered by the class loaders.
+ $this->writeMigration($name, $table, $create);
+
+ $this->composer->dumpAutoloads();
+ }
+
+ /**
+ * Write the migration file to disk.
+ *
+ * @param string $name
+ * @param string $table
+ * @param bool $create
+ * @return string
+ */
+ protected function writeMigration($name, $table, $create)
+ {
+ $path = $this->getMigrationPath();
+
+ $file = pathinfo($this->creator->create($name, $path, $table, $create), PATHINFO_FILENAME);
+
+ $this->line("Created Migration: $file");
+ }
+
+ /**
+ * Get migration path (either specified by '--path' option or default location).
+ *
+ * @return string
+ */
+ protected function getMigrationPath()
+ {
+ if (! is_null($targetPath = $this->input->getOption('path'))) {
+ return $this->laravel->basePath().'/'.$targetPath;
+ }
+
+ return parent::getMigrationPath();
+ }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/RefreshCommand.php b/vendor/illuminate/database/Console/Migrations/RefreshCommand.php
new file mode 100755
index 00000000..ce4e8f19
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/RefreshCommand.php
@@ -0,0 +1,108 @@
+confirmToProceed()) {
+ return;
+ }
+
+ $database = $this->input->getOption('database');
+
+ $force = $this->input->getOption('force');
+
+ $path = $this->input->getOption('path');
+
+ $this->call('migrate:reset', [
+ '--database' => $database, '--force' => $force,
+ ]);
+
+ // The refresh command is essentially just a brief aggregate of a few other of
+ // the migration commands and just provides a convenient wrapper to execute
+ // them in succession. We'll also see if we need to re-seed the database.
+ $this->call('migrate', [
+ '--database' => $database,
+ '--force' => $force,
+ '--path' => $path,
+ ]);
+
+ if ($this->needsSeeding()) {
+ $this->runSeeder($database);
+ }
+ }
+
+ /**
+ * Determine if the developer has requested database seeding.
+ *
+ * @return bool
+ */
+ protected function needsSeeding()
+ {
+ return $this->option('seed') || $this->option('seeder');
+ }
+
+ /**
+ * Run the database seeder command.
+ *
+ * @param string $database
+ * @return void
+ */
+ protected function runSeeder($database)
+ {
+ $class = $this->option('seeder') ?: 'DatabaseSeeder';
+
+ $force = $this->input->getOption('force');
+
+ $this->call('db:seed', [
+ '--database' => $database, '--class' => $class, '--force' => $force,
+ ]);
+ }
+
+ /**
+ * Get the console command options.
+ *
+ * @return array
+ */
+ protected function getOptions()
+ {
+ return [
+ ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
+
+ ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
+
+ ['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to be executed.'],
+
+ ['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'],
+
+ ['seeder', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder.'],
+ ];
+ }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/ResetCommand.php b/vendor/illuminate/database/Console/Migrations/ResetCommand.php
new file mode 100755
index 00000000..8871d3d0
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/ResetCommand.php
@@ -0,0 +1,94 @@
+migrator = $migrator;
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function fire()
+ {
+ if (! $this->confirmToProceed()) {
+ return;
+ }
+
+ $this->migrator->setConnection($this->input->getOption('database'));
+
+ if (! $this->migrator->repositoryExists()) {
+ $this->output->writeln('Migration table not found.');
+
+ return;
+ }
+
+ $pretend = $this->input->getOption('pretend');
+
+ $this->migrator->reset($pretend);
+
+ // Once the migrator has run we will grab the note output and send it out to
+ // the console screen, since the migrator itself functions without having
+ // any instances of the OutputInterface contract passed into the class.
+ foreach ($this->migrator->getNotes() as $note) {
+ $this->output->writeln($note);
+ }
+ }
+
+ /**
+ * Get the console command options.
+ *
+ * @return array
+ */
+ protected function getOptions()
+ {
+ return [
+ ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
+
+ ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
+
+ ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],
+ ];
+ }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/RollbackCommand.php b/vendor/illuminate/database/Console/Migrations/RollbackCommand.php
new file mode 100755
index 00000000..a341b4fe
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/RollbackCommand.php
@@ -0,0 +1,88 @@
+migrator = $migrator;
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function fire()
+ {
+ if (! $this->confirmToProceed()) {
+ return;
+ }
+
+ $this->migrator->setConnection($this->input->getOption('database'));
+
+ $pretend = $this->input->getOption('pretend');
+
+ $this->migrator->rollback($pretend);
+
+ // Once the migrator has run we will grab the note output and send it out to
+ // the console screen, since the migrator itself functions without having
+ // any instances of the OutputInterface contract passed into the class.
+ foreach ($this->migrator->getNotes() as $note) {
+ $this->output->writeln($note);
+ }
+ }
+
+ /**
+ * Get the console command options.
+ *
+ * @return array
+ */
+ protected function getOptions()
+ {
+ return [
+ ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
+
+ ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
+
+ ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],
+ ];
+ }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/StatusCommand.php b/vendor/illuminate/database/Console/Migrations/StatusCommand.php
new file mode 100644
index 00000000..aba7acf0
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/StatusCommand.php
@@ -0,0 +1,102 @@
+migrator = $migrator;
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function fire()
+ {
+ if (! $this->migrator->repositoryExists()) {
+ return $this->error('No migrations found.');
+ }
+
+ $this->migrator->setConnection($this->input->getOption('database'));
+
+ if (! is_null($path = $this->input->getOption('path'))) {
+ $path = $this->laravel->basePath().'/'.$path;
+ } else {
+ $path = $this->getMigrationPath();
+ }
+
+ $ran = $this->migrator->getRepository()->getRan();
+
+ $migrations = [];
+
+ foreach ($this->getAllMigrationFiles($path) as $migration) {
+ $migrations[] = in_array($migration, $ran) ? ['Y', $migration] : ['N', $migration];
+ }
+
+ if (count($migrations) > 0) {
+ $this->table(['Ran?', 'Migration'], $migrations);
+ } else {
+ $this->error('No migrations found');
+ }
+ }
+
+ /**
+ * Get all of the migration files.
+ *
+ * @param string $path
+ * @return array
+ */
+ protected function getAllMigrationFiles($path)
+ {
+ return $this->migrator->getMigrationFiles($path);
+ }
+
+ /**
+ * Get the console command options.
+ *
+ * @return array
+ */
+ protected function getOptions()
+ {
+ return [
+ ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
+
+ ['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to use.'],
+ ];
+ }
+}
diff --git a/vendor/illuminate/database/Console/Seeds/SeedCommand.php b/vendor/illuminate/database/Console/Seeds/SeedCommand.php
new file mode 100644
index 00000000..a505de06
--- /dev/null
+++ b/vendor/illuminate/database/Console/Seeds/SeedCommand.php
@@ -0,0 +1,106 @@
+resolver = $resolver;
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function fire()
+ {
+ if (! $this->confirmToProceed()) {
+ return;
+ }
+
+ $this->resolver->setDefaultConnection($this->getDatabase());
+
+ Model::unguarded(function () {
+ $this->getSeeder()->run();
+ });
+ }
+
+ /**
+ * Get a seeder instance from the container.
+ *
+ * @return \Illuminate\Database\Seeder
+ */
+ protected function getSeeder()
+ {
+ $class = $this->laravel->make($this->input->getOption('class'));
+
+ return $class->setContainer($this->laravel)->setCommand($this);
+ }
+
+ /**
+ * Get the name of the database connection to use.
+ *
+ * @return string
+ */
+ protected function getDatabase()
+ {
+ $database = $this->input->getOption('database');
+
+ return $database ?: $this->laravel['config']['database.default'];
+ }
+
+ /**
+ * Get the console command options.
+ *
+ * @return array
+ */
+ protected function getOptions()
+ {
+ return [
+ ['class', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder', 'DatabaseSeeder'],
+
+ ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to seed'],
+
+ ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
+ ];
+ }
+}
diff --git a/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php b/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php
new file mode 100644
index 00000000..3db79f12
--- /dev/null
+++ b/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php
@@ -0,0 +1,96 @@
+composer = $composer;
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function fire()
+ {
+ parent::fire();
+
+ $this->composer->dumpAutoloads();
+ }
+
+ /**
+ * Get the stub file for the generator.
+ *
+ * @return string
+ */
+ protected function getStub()
+ {
+ return __DIR__.'/stubs/seeder.stub';
+ }
+
+ /**
+ * Get the destination class path.
+ *
+ * @param string $name
+ * @return string
+ */
+ protected function getPath($name)
+ {
+ return $this->laravel->databasePath().'/seeds/'.$name.'.php';
+ }
+
+ /**
+ * Parse the name and format according to the root namespace.
+ *
+ * @param string $name
+ * @return string
+ */
+ protected function parseName($name)
+ {
+ return $name;
+ }
+}
diff --git a/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub b/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub
new file mode 100644
index 00000000..4aa38454
--- /dev/null
+++ b/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub
@@ -0,0 +1,16 @@
+app = $app;
+ $this->factory = $factory;
+ }
+
+ /**
+ * Get a database connection instance.
+ *
+ * @param string $name
+ * @return \Illuminate\Database\Connection
+ */
+ public function connection($name = null)
+ {
+ list($name, $type) = $this->parseConnectionName($name);
+
+ // If we haven't created this connection, we'll create it based on the config
+ // provided in the application. Once we've created the connections we will
+ // set the "fetch mode" for PDO which determines the query return types.
+ if (! isset($this->connections[$name])) {
+ $connection = $this->makeConnection($name);
+
+ $this->setPdoForType($connection, $type);
+
+ $this->connections[$name] = $this->prepare($connection);
+ }
+
+ return $this->connections[$name];
+ }
+
+ /**
+ * Parse the connection into an array of the name and read / write type.
+ *
+ * @param string $name
+ * @return array
+ */
+ protected function parseConnectionName($name)
+ {
+ $name = $name ?: $this->getDefaultConnection();
+
+ return Str::endsWith($name, ['::read', '::write'])
+ ? explode('::', $name, 2) : [$name, null];
+ }
+
+ /**
+ * Disconnect from the given database and remove from local cache.
+ *
+ * @param string $name
+ * @return void
+ */
+ public function purge($name = null)
+ {
+ $this->disconnect($name);
+
+ unset($this->connections[$name]);
+ }
+
+ /**
+ * Disconnect from the given database.
+ *
+ * @param string $name
+ * @return void
+ */
+ public function disconnect($name = null)
+ {
+ if (isset($this->connections[$name = $name ?: $this->getDefaultConnection()])) {
+ $this->connections[$name]->disconnect();
+ }
+ }
+
+ /**
+ * Reconnect to the given database.
+ *
+ * @param string $name
+ * @return \Illuminate\Database\Connection
+ */
+ public function reconnect($name = null)
+ {
+ $this->disconnect($name = $name ?: $this->getDefaultConnection());
+
+ if (! isset($this->connections[$name])) {
+ return $this->connection($name);
+ }
+
+ return $this->refreshPdoConnections($name);
+ }
+
+ /**
+ * Refresh the PDO connections on a given connection.
+ *
+ * @param string $name
+ * @return \Illuminate\Database\Connection
+ */
+ protected function refreshPdoConnections($name)
+ {
+ $fresh = $this->makeConnection($name);
+
+ return $this->connections[$name]
+ ->setPdo($fresh->getPdo())
+ ->setReadPdo($fresh->getReadPdo());
+ }
+
+ /**
+ * Make the database connection instance.
+ *
+ * @param string $name
+ * @return \Illuminate\Database\Connection
+ */
+ protected function makeConnection($name)
+ {
+ $config = $this->getConfig($name);
+
+ // First we will check by the connection name to see if an extension has been
+ // registered specifically for that connection. If it has we will call the
+ // Closure and pass it the config allowing it to resolve the connection.
+ if (isset($this->extensions[$name])) {
+ return call_user_func($this->extensions[$name], $config, $name);
+ }
+
+ $driver = $config['driver'];
+
+ // Next we will check to see if an extension has been registered for a driver
+ // and will call the Closure if so, which allows us to have a more generic
+ // resolver for the drivers themselves which applies to all connections.
+ if (isset($this->extensions[$driver])) {
+ return call_user_func($this->extensions[$driver], $config, $name);
+ }
+
+ return $this->factory->make($config, $name);
+ }
+
+ /**
+ * Prepare the database connection instance.
+ *
+ * @param \Illuminate\Database\Connection $connection
+ * @return \Illuminate\Database\Connection
+ */
+ protected function prepare(Connection $connection)
+ {
+ $connection->setFetchMode($this->app['config']['database.fetch']);
+
+ if ($this->app->bound('events')) {
+ $connection->setEventDispatcher($this->app['events']);
+ }
+
+ // Here we'll set a reconnector callback. This reconnector can be any callable
+ // so we will set a Closure to reconnect from this manager with the name of
+ // the connection, which will allow us to reconnect from the connections.
+ $connection->setReconnector(function ($connection) {
+ $this->reconnect($connection->getName());
+ });
+
+ return $connection;
+ }
+
+ /**
+ * Prepare the read write mode for database connection instance.
+ *
+ * @param \Illuminate\Database\Connection $connection
+ * @param string $type
+ * @return \Illuminate\Database\Connection
+ */
+ protected function setPdoForType(Connection $connection, $type = null)
+ {
+ if ($type == 'read') {
+ $connection->setPdo($connection->getReadPdo());
+ } elseif ($type == 'write') {
+ $connection->setReadPdo($connection->getPdo());
+ }
+
+ return $connection;
+ }
+
+ /**
+ * Get the configuration for a connection.
+ *
+ * @param string $name
+ * @return array
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function getConfig($name)
+ {
+ $name = $name ?: $this->getDefaultConnection();
+
+ // To get the database connection configuration, we will just pull each of the
+ // connection configurations and get the configurations for the given name.
+ // If the configuration doesn't exist, we'll throw an exception and bail.
+ $connections = $this->app['config']['database.connections'];
+
+ if (is_null($config = Arr::get($connections, $name))) {
+ throw new InvalidArgumentException("Database [$name] not configured.");
+ }
+
+ return $config;
+ }
+
+ /**
+ * Get the default connection name.
+ *
+ * @return string
+ */
+ public function getDefaultConnection()
+ {
+ return $this->app['config']['database.default'];
+ }
+
+ /**
+ * Set the default connection name.
+ *
+ * @param string $name
+ * @return void
+ */
+ public function setDefaultConnection($name)
+ {
+ $this->app['config']['database.default'] = $name;
+ }
+
+ /**
+ * Get all of the support drivers.
+ *
+ * @return array
+ */
+ public function supportedDrivers()
+ {
+ return ['mysql', 'pgsql', 'sqlite', 'sqlsrv'];
+ }
+
+ /**
+ * Get all of the drivers that are actually available.
+ *
+ * @return array
+ */
+ public function availableDrivers()
+ {
+ return array_intersect($this->supportedDrivers(), str_replace('dblib', 'sqlsrv', PDO::getAvailableDrivers()));
+ }
+
+ /**
+ * Register an extension connection resolver.
+ *
+ * @param string $name
+ * @param callable $resolver
+ * @return void
+ */
+ public function extend($name, callable $resolver)
+ {
+ $this->extensions[$name] = $resolver;
+ }
+
+ /**
+ * Return all of the created connections.
+ *
+ * @return array
+ */
+ public function getConnections()
+ {
+ return $this->connections;
+ }
+
+ /**
+ * Dynamically pass methods to the default connection.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ return call_user_func_array([$this->connection(), $method], $parameters);
+ }
+}
diff --git a/vendor/illuminate/database/DatabaseServiceProvider.php b/vendor/illuminate/database/DatabaseServiceProvider.php
new file mode 100755
index 00000000..1129baaa
--- /dev/null
+++ b/vendor/illuminate/database/DatabaseServiceProvider.php
@@ -0,0 +1,88 @@
+app['db']);
+
+ Model::setEventDispatcher($this->app['events']);
+ }
+
+ /**
+ * Register the service provider.
+ *
+ * @return void
+ */
+ public function register()
+ {
+ Model::clearBootedModels();
+
+ $this->registerEloquentFactory();
+
+ $this->registerQueueableEntityResolver();
+
+ // The connection factory is used to create the actual connection instances on
+ // the database. We will inject the factory into the manager so that it may
+ // make the connections while they are actually needed and not of before.
+ $this->app->singleton('db.factory', function ($app) {
+ return new ConnectionFactory($app);
+ });
+
+ // The database manager is used to resolve various connections, since multiple
+ // connections might be managed. It also implements the connection resolver
+ // interface which may be used by other components requiring connections.
+ $this->app->singleton('db', function ($app) {
+ return new DatabaseManager($app, $app['db.factory']);
+ });
+
+ $this->app->bind('db.connection', function ($app) {
+ return $app['db']->connection();
+ });
+ }
+
+ /**
+ * Register the Eloquent factory instance in the container.
+ *
+ * @return void
+ */
+ protected function registerEloquentFactory()
+ {
+ $this->app->singleton(FakerGenerator::class, function () {
+ return FakerFactory::create();
+ });
+
+ $this->app->singleton(EloquentFactory::class, function ($app) {
+ $faker = $app->make(FakerGenerator::class);
+
+ return EloquentFactory::construct($faker, database_path('factories'));
+ });
+ }
+
+ /**
+ * Register the queueable entity resolver implementation.
+ *
+ * @return void
+ */
+ protected function registerQueueableEntityResolver()
+ {
+ $this->app->singleton('Illuminate\Contracts\Queue\EntityResolver', function () {
+ return new QueueEntityResolver;
+ });
+ }
+}
diff --git a/vendor/illuminate/database/DetectsLostConnections.php b/vendor/illuminate/database/DetectsLostConnections.php
new file mode 100644
index 00000000..78c65a98
--- /dev/null
+++ b/vendor/illuminate/database/DetectsLostConnections.php
@@ -0,0 +1,28 @@
+getMessage();
+
+ return Str::contains($message, [
+ 'server has gone away',
+ 'no connection to the server',
+ 'Lost connection',
+ 'is dead or not enabled',
+ 'Error while sending',
+ ]);
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Builder.php b/vendor/illuminate/database/Eloquent/Builder.php
new file mode 100755
index 00000000..0d963eec
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Builder.php
@@ -0,0 +1,1193 @@
+query = $query;
+ }
+
+ /**
+ * Register a new global scope.
+ *
+ * @param string $identifier
+ * @param \Illuminate\Database\Eloquent\Scope|\Closure $scope
+ * @return $this
+ */
+ public function withGlobalScope($identifier, $scope)
+ {
+ $this->scopes[$identifier] = $scope;
+
+ return $this;
+ }
+
+ /**
+ * Remove a registered global scope.
+ *
+ * @param \Illuminate\Database\Eloquent\Scope|string $scope
+ * @return $this
+ */
+ public function withoutGlobalScope($scope)
+ {
+ if (is_string($scope)) {
+ unset($this->scopes[$scope]);
+
+ return $this;
+ }
+
+ foreach ($this->scopes as $key => $value) {
+ if ($scope instanceof $value) {
+ unset($this->scopes[$key]);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Remove all or passed registered global scopes.
+ *
+ * @param array|null $scopes
+ * @return $this
+ */
+ public function withoutGlobalScopes(array $scopes = null)
+ {
+ if (is_array($scopes)) {
+ foreach ($scopes as $scope) {
+ $this->withoutGlobalScope($scope);
+ }
+ } else {
+ $this->scopes = [];
+ }
+
+ return $this;
+ }
+
+ /**
+ * Find a model by its primary key.
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null
+ */
+ public function find($id, $columns = ['*'])
+ {
+ if (is_array($id)) {
+ return $this->findMany($id, $columns);
+ }
+
+ $this->query->where($this->model->getQualifiedKeyName(), '=', $id);
+
+ return $this->first($columns);
+ }
+
+ /**
+ * Find a model by its primary key.
+ *
+ * @param array $ids
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Collection
+ */
+ public function findMany($ids, $columns = ['*'])
+ {
+ if (empty($ids)) {
+ return $this->model->newCollection();
+ }
+
+ $this->query->whereIn($this->model->getQualifiedKeyName(), $ids);
+
+ return $this->get($columns);
+ }
+
+ /**
+ * Find a model by its primary key or throw an exception.
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection
+ *
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ */
+ public function findOrFail($id, $columns = ['*'])
+ {
+ $result = $this->find($id, $columns);
+
+ if (is_array($id)) {
+ if (count($result) == count(array_unique($id))) {
+ return $result;
+ }
+ } elseif (! is_null($result)) {
+ return $result;
+ }
+
+ throw (new ModelNotFoundException)->setModel(get_class($this->model));
+ }
+
+ /**
+ * Execute the query and get the first result.
+ *
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model|static|null
+ */
+ public function first($columns = ['*'])
+ {
+ return $this->take(1)->get($columns)->first();
+ }
+
+ /**
+ * Execute the query and get the first result or throw an exception.
+ *
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model|static
+ *
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ */
+ public function firstOrFail($columns = ['*'])
+ {
+ if (! is_null($model = $this->first($columns))) {
+ return $model;
+ }
+
+ throw (new ModelNotFoundException)->setModel(get_class($this->model));
+ }
+
+ /**
+ * Execute the query as a "select" statement.
+ *
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Collection|static[]
+ */
+ public function get($columns = ['*'])
+ {
+ $models = $this->getModels($columns);
+
+ // If we actually found models we will also eager load any relationships that
+ // have been specified as needing to be eager loaded, which will solve the
+ // n+1 query issue for the developers to avoid running a lot of queries.
+ if (count($models) > 0) {
+ $models = $this->eagerLoadRelations($models);
+ }
+
+ return $this->model->newCollection($models);
+ }
+
+ /**
+ * Get a single column's value from the first result of a query.
+ *
+ * @param string $column
+ * @return mixed
+ */
+ public function value($column)
+ {
+ $result = $this->first([$column]);
+
+ if ($result) {
+ return $result->{$column};
+ }
+ }
+
+ /**
+ * Chunk the results of the query.
+ *
+ * @param int $count
+ * @param callable $callback
+ * @return void
+ */
+ public function chunk($count, callable $callback)
+ {
+ $results = $this->forPage($page = 1, $count)->get();
+
+ while (count($results) > 0) {
+ // On each chunk result set, we will pass them to the callback and then let the
+ // developer take care of everything within the callback, which allows us to
+ // keep the memory low for spinning through large result sets for working.
+ if (call_user_func($callback, $results) === false) {
+ break;
+ }
+
+ $page++;
+
+ $results = $this->forPage($page, $count)->get();
+ }
+ }
+
+ /**
+ * Get an array with the values of a given column.
+ *
+ * @param string $column
+ * @param string|null $key
+ * @return \Illuminate\Support\Collection
+ */
+ public function pluck($column, $key = null)
+ {
+ $results = $this->toBase()->pluck($column, $key);
+
+ // If the model has a mutator for the requested column, we will spin through
+ // the results and mutate the values so that the mutated version of these
+ // columns are returned as you would expect from these Eloquent models.
+ if ($this->model->hasGetMutator($column)) {
+ foreach ($results as $key => &$value) {
+ $fill = [$column => $value];
+
+ $value = $this->model->newFromBuilder($fill)->$column;
+ }
+ }
+
+ return collect($results);
+ }
+
+ /**
+ * Alias for the "pluck" method.
+ *
+ * @param string $column
+ * @param string $key
+ * @return \Illuminate\Support\Collection
+ *
+ * @deprecated since version 5.2. Use the "pluck" method directly.
+ */
+ public function lists($column, $key = null)
+ {
+ return $this->pluck($column, $key);
+ }
+
+ /**
+ * Paginate the given query.
+ *
+ * @param int $perPage
+ * @param array $columns
+ * @param string $pageName
+ * @param int|null $page
+ * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
+ {
+ $query = $this->toBase();
+
+ $total = $query->getCountForPagination();
+
+ $this->forPage(
+ $page = $page ?: Paginator::resolveCurrentPage($pageName),
+ $perPage = $perPage ?: $this->model->getPerPage()
+ );
+
+ return new LengthAwarePaginator($this->get($columns), $total, $perPage, $page, [
+ 'path' => Paginator::resolveCurrentPath(),
+ 'pageName' => $pageName,
+ ]);
+ }
+
+ /**
+ * Paginate the given query into a simple paginator.
+ *
+ * @param int $perPage
+ * @param array $columns
+ * @param string $pageName
+ * @return \Illuminate\Contracts\Pagination\Paginator
+ */
+ public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page')
+ {
+ $page = Paginator::resolveCurrentPage($pageName);
+
+ $perPage = $perPage ?: $this->model->getPerPage();
+
+ $this->skip(($page - 1) * $perPage)->take($perPage + 1);
+
+ return new Paginator($this->get($columns), $perPage, $page, [
+ 'path' => Paginator::resolveCurrentPath(),
+ 'pageName' => $pageName,
+ ]);
+ }
+
+ /**
+ * Update a record in the database.
+ *
+ * @param array $values
+ * @return int
+ */
+ public function update(array $values)
+ {
+ return $this->query->update($this->addUpdatedAtColumn($values));
+ }
+
+ /**
+ * Increment a column's value by a given amount.
+ *
+ * @param string $column
+ * @param int $amount
+ * @param array $extra
+ * @return int
+ */
+ public function increment($column, $amount = 1, array $extra = [])
+ {
+ $extra = $this->addUpdatedAtColumn($extra);
+
+ return $this->toBase()->increment($column, $amount, $extra);
+ }
+
+ /**
+ * Decrement a column's value by a given amount.
+ *
+ * @param string $column
+ * @param int $amount
+ * @param array $extra
+ * @return int
+ */
+ public function decrement($column, $amount = 1, array $extra = [])
+ {
+ $extra = $this->addUpdatedAtColumn($extra);
+
+ return $this->toBase()->decrement($column, $amount, $extra);
+ }
+
+ /**
+ * Add the "updated at" column to an array of values.
+ *
+ * @param array $values
+ * @return array
+ */
+ protected function addUpdatedAtColumn(array $values)
+ {
+ if (! $this->model->usesTimestamps()) {
+ return $values;
+ }
+
+ $column = $this->model->getUpdatedAtColumn();
+
+ return Arr::add($values, $column, $this->model->freshTimestampString());
+ }
+
+ /**
+ * Delete a record from the database.
+ *
+ * @return mixed
+ */
+ public function delete()
+ {
+ if (isset($this->onDelete)) {
+ return call_user_func($this->onDelete, $this);
+ }
+
+ return $this->query->delete();
+ }
+
+ /**
+ * Run the default delete function on the builder.
+ *
+ * @return mixed
+ */
+ public function forceDelete()
+ {
+ return $this->query->delete();
+ }
+
+ /**
+ * Register a replacement for the default delete function.
+ *
+ * @param \Closure $callback
+ * @return void
+ */
+ public function onDelete(Closure $callback)
+ {
+ $this->onDelete = $callback;
+ }
+
+ /**
+ * Get the hydrated models without eager loading.
+ *
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model[]
+ */
+ public function getModels($columns = ['*'])
+ {
+ $results = $this->toBase()->get($columns);
+
+ $connection = $this->model->getConnectionName();
+
+ return $this->model->hydrate($results, $connection)->all();
+ }
+
+ /**
+ * Eager load the relationships for the models.
+ *
+ * @param array $models
+ * @return array
+ */
+ public function eagerLoadRelations(array $models)
+ {
+ foreach ($this->eagerLoad as $name => $constraints) {
+ // For nested eager loads we'll skip loading them here and they will be set as an
+ // eager load on the query to retrieve the relation so that they will be eager
+ // loaded on that query, because that is where they get hydrated as models.
+ if (strpos($name, '.') === false) {
+ $models = $this->loadRelation($models, $name, $constraints);
+ }
+ }
+
+ return $models;
+ }
+
+ /**
+ * Eagerly load the relationship on a set of models.
+ *
+ * @param array $models
+ * @param string $name
+ * @param \Closure $constraints
+ * @return array
+ */
+ protected function loadRelation(array $models, $name, Closure $constraints)
+ {
+ // First we will "back up" the existing where conditions on the query so we can
+ // add our eager constraints. Then we will merge the wheres that were on the
+ // query back to it in order that any where conditions might be specified.
+ $relation = $this->getRelation($name);
+
+ $relation->addEagerConstraints($models);
+
+ call_user_func($constraints, $relation);
+
+ $models = $relation->initRelation($models, $name);
+
+ // Once we have the results, we just match those back up to their parent models
+ // using the relationship instance. Then we just return the finished arrays
+ // of models which have been eagerly hydrated and are readied for return.
+ $results = $relation->getEager();
+
+ return $relation->match($models, $results, $name);
+ }
+
+ /**
+ * Get the relation instance for the given relation name.
+ *
+ * @param string $name
+ * @return \Illuminate\Database\Eloquent\Relations\Relation
+ */
+ public function getRelation($name)
+ {
+ // We want to run a relationship query without any constrains so that we will
+ // not have to remove these where clauses manually which gets really hacky
+ // and is error prone while we remove the developer's own where clauses.
+ $relation = Relation::noConstraints(function () use ($name) {
+ return $this->getModel()->$name();
+ });
+
+ $nested = $this->nestedRelations($name);
+
+ // If there are nested relationships set on the query, we will put those onto
+ // the query instances so that they can be handled after this relationship
+ // is loaded. In this way they will all trickle down as they are loaded.
+ if (count($nested) > 0) {
+ $relation->getQuery()->with($nested);
+ }
+
+ return $relation;
+ }
+
+ /**
+ * Get the deeply nested relations for a given top-level relation.
+ *
+ * @param string $relation
+ * @return array
+ */
+ protected function nestedRelations($relation)
+ {
+ $nested = [];
+
+ // We are basically looking for any relationships that are nested deeper than
+ // the given top-level relationship. We will just check for any relations
+ // that start with the given top relations and adds them to our arrays.
+ foreach ($this->eagerLoad as $name => $constraints) {
+ if ($this->isNested($name, $relation)) {
+ $nested[substr($name, strlen($relation.'.'))] = $constraints;
+ }
+ }
+
+ return $nested;
+ }
+
+ /**
+ * Determine if the relationship is nested.
+ *
+ * @param string $name
+ * @param string $relation
+ * @return bool
+ */
+ protected function isNested($name, $relation)
+ {
+ $dots = Str::contains($name, '.');
+
+ return $dots && Str::startsWith($name, $relation.'.');
+ }
+
+ /**
+ * Add a basic where clause to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param mixed $value
+ * @param string $boolean
+ * @return $this
+ */
+ public function where($column, $operator = null, $value = null, $boolean = 'and')
+ {
+ if ($column instanceof Closure) {
+ $query = $this->model->newQueryWithoutScopes();
+
+ call_user_func($column, $query);
+
+ $this->query->addNestedWhereQuery($query->getQuery(), $boolean);
+ } else {
+ call_user_func_array([$this->query, 'where'], func_get_args());
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add an "or where" clause to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public function orWhere($column, $operator = null, $value = null)
+ {
+ return $this->where($column, $operator, $value, 'or');
+ }
+
+ /**
+ * Add a relationship count condition to the query.
+ *
+ * @param string $relation
+ * @param string $operator
+ * @param int $count
+ * @param string $boolean
+ * @param \Closure|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public function has($relation, $operator = '>=', $count = 1, $boolean = 'and', Closure $callback = null)
+ {
+ if (strpos($relation, '.') !== false) {
+ return $this->hasNested($relation, $operator, $count, $boolean, $callback);
+ }
+
+ $relation = $this->getHasRelationQuery($relation);
+
+ $query = $relation->getRelationCountQuery($relation->getRelated()->newQuery(), $this);
+
+ if ($callback) {
+ call_user_func($callback, $query);
+ }
+
+ return $this->addHasWhere(
+ $query->applyScopes(), $relation, $operator, $count, $boolean
+ );
+ }
+
+ /**
+ * Add nested relationship count conditions to the query.
+ *
+ * @param string $relations
+ * @param string $operator
+ * @param int $count
+ * @param string $boolean
+ * @param \Closure|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ protected function hasNested($relations, $operator = '>=', $count = 1, $boolean = 'and', $callback = null)
+ {
+ $relations = explode('.', $relations);
+
+ // In order to nest "has", we need to add count relation constraints on the
+ // callback Closure. We'll do this by simply passing the Closure its own
+ // reference to itself so it calls itself recursively on each segment.
+ $closure = function ($q) use (&$closure, &$relations, $operator, $count, $boolean, $callback) {
+ if (count($relations) > 1) {
+ $q->whereHas(array_shift($relations), $closure);
+ } else {
+ $q->has(array_shift($relations), $operator, $count, 'and', $callback);
+ }
+ };
+
+ return $this->has(array_shift($relations), '>=', 1, $boolean, $closure);
+ }
+
+ /**
+ * Add a relationship count condition to the query.
+ *
+ * @param string $relation
+ * @param string $boolean
+ * @param \Closure|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public function doesntHave($relation, $boolean = 'and', Closure $callback = null)
+ {
+ return $this->has($relation, '<', 1, $boolean, $callback);
+ }
+
+ /**
+ * Add a relationship count condition to the query with where clauses.
+ *
+ * @param string $relation
+ * @param \Closure $callback
+ * @param string $operator
+ * @param int $count
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public function whereHas($relation, Closure $callback, $operator = '>=', $count = 1)
+ {
+ return $this->has($relation, $operator, $count, 'and', $callback);
+ }
+
+ /**
+ * Add a relationship count condition to the query with where clauses.
+ *
+ * @param string $relation
+ * @param \Closure|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public function whereDoesntHave($relation, Closure $callback = null)
+ {
+ return $this->doesntHave($relation, 'and', $callback);
+ }
+
+ /**
+ * Add a relationship count condition to the query with an "or".
+ *
+ * @param string $relation
+ * @param string $operator
+ * @param int $count
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public function orHas($relation, $operator = '>=', $count = 1)
+ {
+ return $this->has($relation, $operator, $count, 'or');
+ }
+
+ /**
+ * Add a relationship count condition to the query with where clauses and an "or".
+ *
+ * @param string $relation
+ * @param \Closure $callback
+ * @param string $operator
+ * @param int $count
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public function orWhereHas($relation, Closure $callback, $operator = '>=', $count = 1)
+ {
+ return $this->has($relation, $operator, $count, 'or', $callback);
+ }
+
+ /**
+ * Add the "has" condition where clause to the query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $hasQuery
+ * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
+ * @param string $operator
+ * @param int $count
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ protected function addHasWhere(Builder $hasQuery, Relation $relation, $operator, $count, $boolean)
+ {
+ $this->mergeModelDefinedRelationWheresToHasQuery($hasQuery, $relation);
+
+ if (is_numeric($count)) {
+ $count = new Expression($count);
+ }
+
+ return $this->where(new Expression('('.$hasQuery->toSql().')'), $operator, $count, $boolean);
+ }
+
+ /**
+ * Merge the "wheres" from a relation query to a has query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $hasQuery
+ * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
+ * @return void
+ */
+ protected function mergeModelDefinedRelationWheresToHasQuery(Builder $hasQuery, Relation $relation)
+ {
+ // Here we have the "has" query and the original relation. We need to copy over any
+ // where clauses the developer may have put in the relationship function over to
+ // the has query, and then copy the bindings from the "has" query to the main.
+ $relationQuery = $relation->getBaseQuery();
+
+ $hasQuery->mergeWheres(
+ $relationQuery->wheres, $relationQuery->getBindings()
+ );
+
+ $this->query->addBinding($hasQuery->getQuery()->getBindings(), 'where');
+ }
+
+ /**
+ * Get the "has relation" base query instance.
+ *
+ * @param string $relation
+ * @return \Illuminate\Database\Eloquent\Relations\Relation
+ */
+ protected function getHasRelationQuery($relation)
+ {
+ return Relation::noConstraints(function () use ($relation) {
+ return $this->getModel()->$relation();
+ });
+ }
+
+ /**
+ * Set the relationships that should be eager loaded.
+ *
+ * @param mixed $relations
+ * @return $this
+ */
+ public function with($relations)
+ {
+ if (is_string($relations)) {
+ $relations = func_get_args();
+ }
+
+ $eagers = $this->parseWithRelations($relations);
+
+ $this->eagerLoad = array_merge($this->eagerLoad, $eagers);
+
+ return $this;
+ }
+
+ /**
+ * Parse a list of relations into individuals.
+ *
+ * @param array $relations
+ * @return array
+ */
+ protected function parseWithRelations(array $relations)
+ {
+ $results = [];
+
+ foreach ($relations as $name => $constraints) {
+ // If the "relation" value is actually a numeric key, we can assume that no
+ // constraints have been specified for the eager load and we'll just put
+ // an empty Closure with the loader so that we can treat all the same.
+ if (is_numeric($name)) {
+ $f = function () {
+ //
+ };
+
+ list($name, $constraints) = [$constraints, $f];
+ }
+
+ // We need to separate out any nested includes. Which allows the developers
+ // to load deep relationships using "dots" without stating each level of
+ // the relationship with its own key in the array of eager load names.
+ $results = $this->parseNestedWith($name, $results);
+
+ $results[$name] = $constraints;
+ }
+
+ return $results;
+ }
+
+ /**
+ * Parse the nested relationships in a relation.
+ *
+ * @param string $name
+ * @param array $results
+ * @return array
+ */
+ protected function parseNestedWith($name, $results)
+ {
+ $progress = [];
+
+ // If the relation has already been set on the result array, we will not set it
+ // again, since that would override any constraints that were already placed
+ // on the relationships. We will only set the ones that are not specified.
+ foreach (explode('.', $name) as $segment) {
+ $progress[] = $segment;
+
+ if (! isset($results[$last = implode('.', $progress)])) {
+ $results[$last] = function () {
+ //
+ };
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Call the given model scope on the underlying model.
+ *
+ * @param string $scope
+ * @param array $parameters
+ * @return \Illuminate\Database\Query\Builder
+ */
+ protected function callScope($scope, $parameters)
+ {
+ array_unshift($parameters, $this);
+
+ $query = $this->getQuery();
+
+ // We will keep track of how many wheres are on the query before running the
+ // scope so that we can properly group the added scope constraints in the
+ // query as their own isolated nested where statement and avoid issues.
+ $originalWhereCount = count($query->wheres);
+
+ $result = call_user_func_array([$this->model, $scope], $parameters) ?: $this;
+
+ if ($this->shouldNestWheresForScope($query, $originalWhereCount)) {
+ $this->nestWheresForScope($query, $originalWhereCount);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Apply the scopes to the Eloquent builder instance and return it.
+ *
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public function applyScopes()
+ {
+ if (! $this->scopes) {
+ return $this;
+ }
+
+ $builder = clone $this;
+
+ $query = $builder->getQuery();
+
+ // We will keep track of how many wheres are on the query before running the
+ // scope so that we can properly group the added scope constraints in the
+ // query as their own isolated nested where statement and avoid issues.
+ $originalWhereCount = count($query->wheres);
+
+ $whereCounts = [$originalWhereCount];
+
+ foreach ($this->scopes as $scope) {
+ $this->applyScope($scope, $builder);
+
+ // Again, we will keep track of the count each time we add where clauses so that
+ // we will properly isolate each set of scope constraints inside of their own
+ // nested where clause to avoid any conflicts or issues with logical order.
+ $whereCounts[] = count($query->wheres);
+ }
+
+ if ($this->shouldNestWheresForScope($query, $originalWhereCount)) {
+ $this->nestWheresForScope($query, $whereCounts);
+ }
+
+ return $builder;
+ }
+
+ /**
+ * Apply a single scope on the given builder instance.
+ *
+ * @param \Illuminate\Database\Eloquent\Scope|\Closure $scope
+ * @param \Illuminate\Database\Eloquent\Builder $builder
+ * @return void
+ */
+ protected function applyScope($scope, $builder)
+ {
+ if ($scope instanceof Closure) {
+ $scope($builder);
+ } elseif ($scope instanceof Scope) {
+ $scope->apply($builder, $this->getModel());
+ }
+ }
+
+ /**
+ * Determine if the scope added after the given offset should be nested.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param int $originalWhereCount
+ * @return bool
+ */
+ protected function shouldNestWheresForScope(QueryBuilder $query, $originalWhereCount)
+ {
+ return $originalWhereCount && count($query->wheres) > $originalWhereCount;
+ }
+
+ /**
+ * Nest where conditions by slicing them at the given where count.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param int|array $whereCounts
+ * @return void
+ */
+ protected function nestWheresForScope(QueryBuilder $query, $whereCounts)
+ {
+ // Here, we totally remove all of the where clauses since we are going to
+ // rebuild them as nested queries by slicing the groups of wheres into
+ // their own sections. This is to prevent any confusing logic order.
+ $allWheres = $query->wheres;
+
+ $query->wheres = [];
+
+ // We will construct where offsets by adding the outer most offsets to the
+ // collection (0 and total where count) while also flattening the array
+ // and extracting unique values, ensuring that all wheres are sliced.
+ $whereOffsets = collect([0, $whereCounts, count($allWheres)])
+ ->flatten()->unique();
+
+ $sliceFrom = $whereOffsets->shift();
+
+ foreach ($whereOffsets as $sliceTo) {
+ $this->sliceWhereConditions(
+ $query, $allWheres, $sliceFrom, $sliceTo
+ );
+
+ $sliceFrom = $sliceTo;
+ }
+ }
+
+ /**
+ * Create a slice of where conditions at the given offsets and nest them if needed.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $wheres
+ * @param int $sliceFrom
+ * @param int $sliceTo
+ * @return void
+ */
+ protected function sliceWhereConditions(QueryBuilder $query, array $wheres, $sliceFrom, $sliceTo)
+ {
+ $whereSlice = array_slice($wheres, $sliceFrom, $sliceTo - $sliceFrom);
+
+ $whereBooleans = collect($whereSlice)->pluck('boolean');
+
+ // Here we'll check if the given subset of where clauses contains any "or"
+ // booleans and in this case create a nested where expression. That way
+ // we don't add any unnecessary nesting thus keeping the query clean.
+ if ($whereBooleans->contains('or')) {
+ $query->wheres[] = $this->nestWhereSlice($whereSlice);
+ } else {
+ $query->wheres = array_merge($query->wheres, $whereSlice);
+ }
+ }
+
+ /**
+ * Create a where array with nested where conditions.
+ *
+ * @param array $whereSlice
+ * @return array
+ */
+ protected function nestWhereSlice($whereSlice)
+ {
+ $whereGroup = $this->getQuery()->forNestedWhere();
+
+ $whereGroup->wheres = $whereSlice;
+
+ return ['type' => 'Nested', 'query' => $whereGroup, 'boolean' => 'and'];
+ }
+
+ /**
+ * Get the underlying query builder instance.
+ *
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function getQuery()
+ {
+ return $this->query;
+ }
+
+ /**
+ * Get a base query builder instance.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public function toBase()
+ {
+ return $this->applyScopes()->getQuery();
+ }
+
+ /**
+ * Set the underlying query builder instance.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return $this
+ */
+ public function setQuery($query)
+ {
+ $this->query = $query;
+
+ return $this;
+ }
+
+ /**
+ * Get the relationships being eagerly loaded.
+ *
+ * @return array
+ */
+ public function getEagerLoads()
+ {
+ return $this->eagerLoad;
+ }
+
+ /**
+ * Set the relationships being eagerly loaded.
+ *
+ * @param array $eagerLoad
+ * @return $this
+ */
+ public function setEagerLoads(array $eagerLoad)
+ {
+ $this->eagerLoad = $eagerLoad;
+
+ return $this;
+ }
+
+ /**
+ * Get the model instance being queried.
+ *
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function getModel()
+ {
+ return $this->model;
+ }
+
+ /**
+ * Set a model instance for the model being queried.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $model
+ * @return $this
+ */
+ public function setModel(Model $model)
+ {
+ $this->model = $model;
+
+ $this->query->from($model->getTable());
+
+ return $this;
+ }
+
+ /**
+ * Extend the builder with a given callback.
+ *
+ * @param string $name
+ * @param \Closure $callback
+ * @return void
+ */
+ public function macro($name, Closure $callback)
+ {
+ $this->macros[$name] = $callback;
+ }
+
+ /**
+ * Get the given macro by name.
+ *
+ * @param string $name
+ * @return \Closure
+ */
+ public function getMacro($name)
+ {
+ return Arr::get($this->macros, $name);
+ }
+
+ /**
+ * Dynamically handle calls into the query instance.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ if (isset($this->macros[$method])) {
+ array_unshift($parameters, $this);
+
+ return call_user_func_array($this->macros[$method], $parameters);
+ }
+
+ if (method_exists($this->model, $scope = 'scope'.ucfirst($method))) {
+ return $this->callScope($scope, $parameters);
+ }
+
+ if (in_array($method, $this->passthru)) {
+ return call_user_func_array([$this->toBase(), $method], $parameters);
+ }
+
+ call_user_func_array([$this->query, $method], $parameters);
+
+ return $this;
+ }
+
+ /**
+ * Force a clone of the underlying query builder when cloning.
+ *
+ * @return void
+ */
+ public function __clone()
+ {
+ $this->query = clone $this->query;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Collection.php b/vendor/illuminate/database/Eloquent/Collection.php
new file mode 100755
index 00000000..922ddb4b
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Collection.php
@@ -0,0 +1,323 @@
+getKey();
+ }
+
+ return Arr::first($this->items, function ($itemKey, $model) use ($key) {
+ return $model->getKey() == $key;
+
+ }, $default);
+ }
+
+ /**
+ * Load a set of relationships onto the collection.
+ *
+ * @param mixed $relations
+ * @return $this
+ */
+ public function load($relations)
+ {
+ if (count($this->items) > 0) {
+ if (is_string($relations)) {
+ $relations = func_get_args();
+ }
+
+ $query = $this->first()->newQuery()->with($relations);
+
+ $this->items = $query->eagerLoadRelations($this->items);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add an item to the collection.
+ *
+ * @param mixed $item
+ * @return $this
+ */
+ public function add($item)
+ {
+ $this->items[] = $item;
+
+ return $this;
+ }
+
+ /**
+ * Determine if a key exists in the collection.
+ *
+ * @param mixed $key
+ * @param mixed $value
+ * @return bool
+ */
+ public function contains($key, $value = null)
+ {
+ if (func_num_args() == 2) {
+ return parent::contains($key, $value);
+ }
+
+ if ($this->useAsCallable($key)) {
+ return parent::contains($key);
+ }
+
+ $key = $key instanceof Model ? $key->getKey() : $key;
+
+ return parent::contains(function ($k, $m) use ($key) {
+ return $m->getKey() == $key;
+ });
+ }
+
+ /**
+ * Get the array of primary keys.
+ *
+ * @return array
+ */
+ public function modelKeys()
+ {
+ return array_map(function ($m) {
+ return $m->getKey();
+ }, $this->items);
+ }
+
+ /**
+ * Merge the collection with the given items.
+ *
+ * @param \ArrayAccess|array $items
+ * @return static
+ */
+ public function merge($items)
+ {
+ $dictionary = $this->getDictionary();
+
+ foreach ($items as $item) {
+ $dictionary[$item->getKey()] = $item;
+ }
+
+ return new static(array_values($dictionary));
+ }
+
+ /**
+ * Diff the collection with the given items.
+ *
+ * @param \ArrayAccess|array $items
+ * @return static
+ */
+ public function diff($items)
+ {
+ $diff = new static;
+
+ $dictionary = $this->getDictionary($items);
+
+ foreach ($this->items as $item) {
+ if (! isset($dictionary[$item->getKey()])) {
+ $diff->add($item);
+ }
+ }
+
+ return $diff;
+ }
+
+ /**
+ * Intersect the collection with the given items.
+ *
+ * @param \ArrayAccess|array $items
+ * @return static
+ */
+ public function intersect($items)
+ {
+ $intersect = new static;
+
+ $dictionary = $this->getDictionary($items);
+
+ foreach ($this->items as $item) {
+ if (isset($dictionary[$item->getKey()])) {
+ $intersect->add($item);
+ }
+ }
+
+ return $intersect;
+ }
+
+ /**
+ * Return only unique items from the collection.
+ *
+ * @param string|callable|null $key
+ * @return static
+ */
+ public function unique($key = null)
+ {
+ if (! is_null($key)) {
+ return parent::unique($key);
+ }
+
+ return new static(array_values($this->getDictionary()));
+ }
+
+ /**
+ * Returns only the models from the collection with the specified keys.
+ *
+ * @param mixed $keys
+ * @return static
+ */
+ public function only($keys)
+ {
+ $dictionary = Arr::only($this->getDictionary(), $keys);
+
+ return new static(array_values($dictionary));
+ }
+
+ /**
+ * Returns all models in the collection except the models with specified keys.
+ *
+ * @param mixed $keys
+ * @return static
+ */
+ public function except($keys)
+ {
+ $dictionary = Arr::except($this->getDictionary(), $keys);
+
+ return new static(array_values($dictionary));
+ }
+
+ /**
+ * Make the given, typically hidden, attributes visible across the entire collection.
+ *
+ * @param array|string $attributes
+ * @return $this
+ */
+ public function makeVisible($attributes)
+ {
+ $this->each(function ($model) use ($attributes) {
+ $model->makeVisible($attributes);
+ });
+
+ return $this;
+ }
+
+ /**
+ * Make the given, typically hidden, attributes visible across the entire collection.
+ *
+ * @param array|string $attributes
+ * @return $this
+ *
+ * @deprecated since version 5.2. Use the "makeVisible" method directly.
+ */
+ public function withHidden($attributes)
+ {
+ return $this->makeVisible($attributes);
+ }
+
+ /**
+ * Get a dictionary keyed by primary keys.
+ *
+ * @param \ArrayAccess|array|null $items
+ * @return array
+ */
+ public function getDictionary($items = null)
+ {
+ $items = is_null($items) ? $this->items : $items;
+
+ $dictionary = [];
+
+ foreach ($items as $value) {
+ $dictionary[$value->getKey()] = $value;
+ }
+
+ return $dictionary;
+ }
+
+ /**
+ * The following methods are intercepted to always return base collections.
+ */
+
+ /**
+ * Get an array with the values of a given key.
+ *
+ * @param string $value
+ * @param string|null $key
+ * @return \Illuminate\Support\Collection
+ */
+ public function pluck($value, $key = null)
+ {
+ return $this->toBase()->pluck($value, $key);
+ }
+
+ /**
+ * Get the keys of the collection items.
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ public function keys()
+ {
+ return $this->toBase()->keys();
+ }
+
+ /**
+ * Zip the collection together with one or more arrays.
+ *
+ * @param mixed ...$items
+ * @return \Illuminate\Support\Collection
+ */
+ public function zip($items)
+ {
+ return call_user_func_array([$this->toBase(), 'zip'], func_get_args());
+ }
+
+ /**
+ * Collapse the collection of items into a single array.
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ public function collapse()
+ {
+ return $this->toBase()->collapse();
+ }
+
+ /**
+ * Get a flattened array of the items in the collection.
+ *
+ * @param int $depth
+ * @return \Illuminate\Support\Collection
+ */
+ public function flatten($depth = INF)
+ {
+ return $this->toBase()->flatten($depth);
+ }
+
+ /**
+ * Flip the items in the collection.
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ public function flip()
+ {
+ return $this->toBase()->flip();
+ }
+
+ /**
+ * Get a base Support collection instance from this collection.
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ public function toBase()
+ {
+ return new BaseCollection($this->items);
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Factory.php b/vendor/illuminate/database/Eloquent/Factory.php
new file mode 100644
index 00000000..099f4b4f
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Factory.php
@@ -0,0 +1,229 @@
+faker = $faker;
+ }
+
+ /**
+ * The model definitions in the container.
+ *
+ * @var array
+ */
+ protected $definitions = [];
+
+ /**
+ * Create a new factory container.
+ *
+ * @param \Faker\Generator $faker
+ * @param string|null $pathToFactories
+ * @return static
+ */
+ public static function construct(Faker $faker, $pathToFactories = null)
+ {
+ $pathToFactories = $pathToFactories ?: database_path('factories');
+
+ return (new static($faker))->load($pathToFactories);
+ }
+
+ /**
+ * Define a class with a given short-name.
+ *
+ * @param string $class
+ * @param string $name
+ * @param callable $attributes
+ * @return void
+ */
+ public function defineAs($class, $name, callable $attributes)
+ {
+ return $this->define($class, $attributes, $name);
+ }
+
+ /**
+ * Define a class with a given set of attributes.
+ *
+ * @param string $class
+ * @param callable $attributes
+ * @param string $name
+ * @return void
+ */
+ public function define($class, callable $attributes, $name = 'default')
+ {
+ $this->definitions[$class][$name] = $attributes;
+ }
+
+ /**
+ * Create an instance of the given model and persist it to the database.
+ *
+ * @param string $class
+ * @param array $attributes
+ * @return mixed
+ */
+ public function create($class, array $attributes = [])
+ {
+ return $this->of($class)->create($attributes);
+ }
+
+ /**
+ * Create an instance of the given model and type and persist it to the database.
+ *
+ * @param string $class
+ * @param string $name
+ * @param array $attributes
+ * @return mixed
+ */
+ public function createAs($class, $name, array $attributes = [])
+ {
+ return $this->of($class, $name)->create($attributes);
+ }
+
+ /**
+ * Load factories from path.
+ *
+ * @param string $path
+ * @return $this
+ */
+ public function load($path)
+ {
+ $factory = $this;
+
+ if (is_dir($path)) {
+ foreach (Finder::create()->files()->in($path) as $file) {
+ require $file->getRealPath();
+ }
+ }
+
+ return $factory;
+ }
+
+ /**
+ * Create an instance of the given model.
+ *
+ * @param string $class
+ * @param array $attributes
+ * @return mixed
+ */
+ public function make($class, array $attributes = [])
+ {
+ return $this->of($class)->make($attributes);
+ }
+
+ /**
+ * Create an instance of the given model and type.
+ *
+ * @param string $class
+ * @param string $name
+ * @param array $attributes
+ * @return mixed
+ */
+ public function makeAs($class, $name, array $attributes = [])
+ {
+ return $this->of($class, $name)->make($attributes);
+ }
+
+ /**
+ * Get the raw attribute array for a given named model.
+ *
+ * @param string $class
+ * @param string $name
+ * @param array $attributes
+ * @return array
+ */
+ public function rawOf($class, $name, array $attributes = [])
+ {
+ return $this->raw($class, $attributes, $name);
+ }
+
+ /**
+ * Get the raw attribute array for a given model.
+ *
+ * @param string $class
+ * @param array $attributes
+ * @param string $name
+ * @return array
+ */
+ public function raw($class, array $attributes = [], $name = 'default')
+ {
+ $raw = call_user_func($this->definitions[$class][$name], $this->faker);
+
+ return array_merge($raw, $attributes);
+ }
+
+ /**
+ * Create a builder for the given model.
+ *
+ * @param string $class
+ * @param string $name
+ * @return \Illuminate\Database\Eloquent\FactoryBuilder
+ */
+ public function of($class, $name = 'default')
+ {
+ return new FactoryBuilder($class, $name, $this->definitions, $this->faker);
+ }
+
+ /**
+ * Determine if the given offset exists.
+ *
+ * @param string $offset
+ * @return bool
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->definitions[$offset]);
+ }
+
+ /**
+ * Get the value of the given offset.
+ *
+ * @param string $offset
+ * @return mixed
+ */
+ public function offsetGet($offset)
+ {
+ return $this->make($offset);
+ }
+
+ /**
+ * Set the given offset to the given value.
+ *
+ * @param string $offset
+ * @param callable $value
+ * @return void
+ */
+ public function offsetSet($offset, $value)
+ {
+ return $this->define($offset, $value);
+ }
+
+ /**
+ * Unset the value at the given offset.
+ *
+ * @param string $offset
+ * @return void
+ */
+ public function offsetUnset($offset)
+ {
+ unset($this->definitions[$offset]);
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/FactoryBuilder.php b/vendor/illuminate/database/Eloquent/FactoryBuilder.php
new file mode 100644
index 00000000..89d274e8
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/FactoryBuilder.php
@@ -0,0 +1,135 @@
+name = $name;
+ $this->class = $class;
+ $this->faker = $faker;
+ $this->definitions = $definitions;
+ }
+
+ /**
+ * Set the amount of models you wish to create / make.
+ *
+ * @param int $amount
+ * @return $this
+ */
+ public function times($amount)
+ {
+ $this->amount = $amount;
+
+ return $this;
+ }
+
+ /**
+ * Create a collection of models and persist them to the database.
+ *
+ * @param array $attributes
+ * @return mixed
+ */
+ public function create(array $attributes = [])
+ {
+ $results = $this->make($attributes);
+
+ if ($this->amount === 1) {
+ $results->save();
+ } else {
+ foreach ($results as $result) {
+ $result->save();
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Create a collection of models.
+ *
+ * @param array $attributes
+ * @return mixed
+ */
+ public function make(array $attributes = [])
+ {
+ if ($this->amount === 1) {
+ return $this->makeInstance($attributes);
+ } else {
+ $results = [];
+
+ for ($i = 0; $i < $this->amount; $i++) {
+ $results[] = $this->makeInstance($attributes);
+ }
+
+ return new Collection($results);
+ }
+ }
+
+ /**
+ * Make an instance of the model with the given attributes.
+ *
+ * @param array $attributes
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ protected function makeInstance(array $attributes = [])
+ {
+ return Model::unguarded(function () use ($attributes) {
+ if (! isset($this->definitions[$this->class][$this->name])) {
+ throw new InvalidArgumentException("Unable to locate factory with name [{$this->name}] [{$this->class}].");
+ }
+
+ $definition = call_user_func($this->definitions[$this->class][$this->name], $this->faker, $attributes);
+
+ return new $this->class(array_merge($definition, $attributes));
+ });
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/MassAssignmentException.php b/vendor/illuminate/database/Eloquent/MassAssignmentException.php
new file mode 100755
index 00000000..7c81aae5
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/MassAssignmentException.php
@@ -0,0 +1,10 @@
+bootIfNotBooted();
+
+ $this->syncOriginal();
+
+ $this->fill($attributes);
+ }
+
+ /**
+ * Check if the model needs to be booted and if so, do it.
+ *
+ * @return void
+ */
+ protected function bootIfNotBooted()
+ {
+ $class = get_class($this);
+
+ if (! isset(static::$booted[$class])) {
+ static::$booted[$class] = true;
+
+ $this->fireModelEvent('booting', false);
+
+ static::boot();
+
+ $this->fireModelEvent('booted', false);
+ }
+ }
+
+ /**
+ * The "booting" method of the model.
+ *
+ * @return void
+ */
+ protected static function boot()
+ {
+ static::bootTraits();
+ }
+
+ /**
+ * Boot all of the bootable traits on the model.
+ *
+ * @return void
+ */
+ protected static function bootTraits()
+ {
+ foreach (class_uses_recursive(get_called_class()) as $trait) {
+ if (method_exists(get_called_class(), $method = 'boot'.class_basename($trait))) {
+ forward_static_call([get_called_class(), $method]);
+ }
+ }
+ }
+
+ /**
+ * Clear the list of booted models so they will be re-booted.
+ *
+ * @return void
+ */
+ public static function clearBootedModels()
+ {
+ static::$booted = [];
+ static::$globalScopes = [];
+ }
+
+ /**
+ * Register a new global scope on the model.
+ *
+ * @param \Illuminate\Database\Eloquent\Scope|\Closure|string $scope
+ * @param \Closure|null $implementation
+ * @return mixed
+ *
+ * @throws \InvalidArgumentException
+ */
+ public static function addGlobalScope($scope, Closure $implementation = null)
+ {
+ if (is_string($scope) && $implementation !== null) {
+ return static::$globalScopes[get_called_class()][$scope] = $implementation;
+ }
+
+ if ($scope instanceof Closure) {
+ return static::$globalScopes[get_called_class()][uniqid('scope')] = $scope;
+ }
+
+ if ($scope instanceof Scope) {
+ return static::$globalScopes[get_called_class()][get_class($scope)] = $scope;
+ }
+
+ throw new InvalidArgumentException('Global scope must be an instance of Closure or Scope.');
+ }
+
+ /**
+ * Determine if a model has a global scope.
+ *
+ * @param \Illuminate\Database\Eloquent\Scope|string $scope
+ * @return bool
+ */
+ public static function hasGlobalScope($scope)
+ {
+ return ! is_null(static::getGlobalScope($scope));
+ }
+
+ /**
+ * Get a global scope registered with the model.
+ *
+ * @param \Illuminate\Database\Eloquent\Scope|string $scope
+ * @return \Illuminate\Database\Eloquent\Scope|\Closure|null
+ */
+ public static function getGlobalScope($scope)
+ {
+ $modelScopes = Arr::get(static::$globalScopes, get_called_class(), []);
+
+ if (is_string($scope)) {
+ return isset($modelScopes[$scope]) ? $modelScopes[$scope] : null;
+ }
+
+ return Arr::first($modelScopes, function ($key, $value) use ($scope) {
+ return $scope instanceof $value;
+ });
+ }
+
+ /**
+ * Get the global scopes for this class instance.
+ *
+ * @return array
+ */
+ public function getGlobalScopes()
+ {
+ return Arr::get(static::$globalScopes, get_class($this), []);
+ }
+
+ /**
+ * Register an observer with the Model.
+ *
+ * @param object|string $class
+ * @param int $priority
+ * @return void
+ */
+ public static function observe($class, $priority = 0)
+ {
+ $instance = new static;
+
+ $className = is_string($class) ? $class : get_class($class);
+
+ // When registering a model observer, we will spin through the possible events
+ // and determine if this observer has that method. If it does, we will hook
+ // it into the model's event system, making it convenient to watch these.
+ foreach ($instance->getObservableEvents() as $event) {
+ if (method_exists($class, $event)) {
+ static::registerModelEvent($event, $className.'@'.$event, $priority);
+ }
+ }
+ }
+
+ /**
+ * Fill the model with an array of attributes.
+ *
+ * @param array $attributes
+ * @return $this
+ *
+ * @throws \Illuminate\Database\Eloquent\MassAssignmentException
+ */
+ public function fill(array $attributes)
+ {
+ $totallyGuarded = $this->totallyGuarded();
+
+ foreach ($this->fillableFromArray($attributes) as $key => $value) {
+ $key = $this->removeTableFromKey($key);
+
+ // The developers may choose to place some attributes in the "fillable"
+ // array, which means only those attributes may be set through mass
+ // assignment to the model, and all others will just be ignored.
+ if ($this->isFillable($key)) {
+ $this->setAttribute($key, $value);
+ } elseif ($totallyGuarded) {
+ throw new MassAssignmentException($key);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Fill the model with an array of attributes. Force mass assignment.
+ *
+ * @param array $attributes
+ * @return $this
+ */
+ public function forceFill(array $attributes)
+ {
+ // Since some versions of PHP have a bug that prevents it from properly
+ // binding the late static context in a closure, we will first store
+ // the model in a variable, which we will then use in the closure.
+ $model = $this;
+
+ return static::unguarded(function () use ($model, $attributes) {
+ return $model->fill($attributes);
+ });
+ }
+
+ /**
+ * Get the fillable attributes of a given array.
+ *
+ * @param array $attributes
+ * @return array
+ */
+ protected function fillableFromArray(array $attributes)
+ {
+ if (count($this->fillable) > 0 && ! static::$unguarded) {
+ return array_intersect_key($attributes, array_flip($this->fillable));
+ }
+
+ return $attributes;
+ }
+
+ /**
+ * Create a new instance of the given model.
+ *
+ * @param array $attributes
+ * @param bool $exists
+ * @return static
+ */
+ public function newInstance($attributes = [], $exists = false)
+ {
+ // This method just provides a convenient way for us to generate fresh model
+ // instances of this current model. It is particularly useful during the
+ // hydration of new objects via the Eloquent query builder instances.
+ $model = new static((array) $attributes);
+
+ $model->exists = $exists;
+
+ return $model;
+ }
+
+ /**
+ * Create a new model instance that is existing.
+ *
+ * @param array $attributes
+ * @param string|null $connection
+ * @return static
+ */
+ public function newFromBuilder($attributes = [], $connection = null)
+ {
+ $model = $this->newInstance([], true);
+
+ $model->setRawAttributes((array) $attributes, true);
+
+ $model->setConnection($connection ?: $this->connection);
+
+ return $model;
+ }
+
+ /**
+ * Create a collection of models from plain arrays.
+ *
+ * @param array $items
+ * @param string|null $connection
+ * @return \Illuminate\Database\Eloquent\Collection
+ */
+ public static function hydrate(array $items, $connection = null)
+ {
+ $instance = (new static)->setConnection($connection);
+
+ $items = array_map(function ($item) use ($instance) {
+ return $instance->newFromBuilder($item);
+ }, $items);
+
+ return $instance->newCollection($items);
+ }
+
+ /**
+ * Create a collection of models from a raw query.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @param string|null $connection
+ * @return \Illuminate\Database\Eloquent\Collection
+ */
+ public static function hydrateRaw($query, $bindings = [], $connection = null)
+ {
+ $instance = (new static)->setConnection($connection);
+
+ $items = $instance->getConnection()->select($query, $bindings);
+
+ return static::hydrate($items, $connection);
+ }
+
+ /**
+ * Save a new model and return the instance.
+ *
+ * @param array $attributes
+ * @return static
+ */
+ public static function create(array $attributes = [])
+ {
+ $model = new static($attributes);
+
+ $model->save();
+
+ return $model;
+ }
+
+ /**
+ * Save a new model and return the instance. Allow mass-assignment.
+ *
+ * @param array $attributes
+ * @return static
+ */
+ public static function forceCreate(array $attributes)
+ {
+ // Since some versions of PHP have a bug that prevents it from properly
+ // binding the late static context in a closure, we will first store
+ // the model in a variable, which we will then use in the closure.
+ $model = new static;
+
+ return static::unguarded(function () use ($model, $attributes) {
+ return $model->create($attributes);
+ });
+ }
+
+ /**
+ * Get the first record matching the attributes or create it.
+ *
+ * @param array $attributes
+ * @return static
+ */
+ public static function firstOrCreate(array $attributes)
+ {
+ if (! is_null($instance = (new static)->newQueryWithoutScopes()->where($attributes)->first())) {
+ return $instance;
+ }
+
+ return static::create($attributes);
+ }
+
+ /**
+ * Get the first record matching the attributes or instantiate it.
+ *
+ * @param array $attributes
+ * @return static
+ */
+ public static function firstOrNew(array $attributes)
+ {
+ if (! is_null($instance = (new static)->newQueryWithoutScopes()->where($attributes)->first())) {
+ return $instance;
+ }
+
+ return new static($attributes);
+ }
+
+ /**
+ * Create or update a record matching the attributes, and fill it with values.
+ *
+ * @param array $attributes
+ * @param array $values
+ * @param array $options
+ * @return static
+ */
+ public static function updateOrCreate(array $attributes, array $values = [], array $options = [])
+ {
+ $instance = static::firstOrNew($attributes);
+
+ $instance->fill($values)->save($options);
+
+ return $instance;
+ }
+
+ /**
+ * Begin querying the model.
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public static function query()
+ {
+ return (new static)->newQuery();
+ }
+
+ /**
+ * Begin querying the model on a given connection.
+ *
+ * @param string|null $connection
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public static function on($connection = null)
+ {
+ // First we will just create a fresh instance of this model, and then we can
+ // set the connection on the model so that it is be used for the queries
+ // we execute, as well as being set on each relationship we retrieve.
+ $instance = new static;
+
+ $instance->setConnection($connection);
+
+ return $instance->newQuery();
+ }
+
+ /**
+ * Begin querying the model on the write connection.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public static function onWriteConnection()
+ {
+ $instance = new static;
+
+ return $instance->newQuery()->useWritePdo();
+ }
+
+ /**
+ * Get all of the models from the database.
+ *
+ * @param array|mixed $columns
+ * @return \Illuminate\Database\Eloquent\Collection|static[]
+ */
+ public static function all($columns = ['*'])
+ {
+ $columns = is_array($columns) ? $columns : func_get_args();
+
+ $instance = new static;
+
+ return $instance->newQuery()->get($columns);
+ }
+
+ /**
+ * Find a model by its primary key or return new static.
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return \Illuminate\Support\Collection|static
+ */
+ public static function findOrNew($id, $columns = ['*'])
+ {
+ if (! is_null($model = static::find($id, $columns))) {
+ return $model;
+ }
+
+ return new static;
+ }
+
+ /**
+ * Reload a fresh model instance from the database.
+ *
+ * @param array $with
+ * @return $this|null
+ */
+ public function fresh(array $with = [])
+ {
+ if (! $this->exists) {
+ return;
+ }
+
+ $key = $this->getKeyName();
+
+ return static::with($with)->where($key, $this->getKey())->first();
+ }
+
+ /**
+ * Eager load relations on the model.
+ *
+ * @param array|string $relations
+ * @return $this
+ */
+ public function load($relations)
+ {
+ if (is_string($relations)) {
+ $relations = func_get_args();
+ }
+
+ $query = $this->newQuery()->with($relations);
+
+ $query->eagerLoadRelations([$this]);
+
+ return $this;
+ }
+
+ /**
+ * Begin querying a model with eager loading.
+ *
+ * @param array|string $relations
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public static function with($relations)
+ {
+ if (is_string($relations)) {
+ $relations = func_get_args();
+ }
+
+ $instance = new static;
+
+ return $instance->newQuery()->with($relations);
+ }
+
+ /**
+ * Append attributes to query when building a query.
+ *
+ * @param array|string $attributes
+ * @return $this
+ */
+ public function append($attributes)
+ {
+ if (is_string($attributes)) {
+ $attributes = func_get_args();
+ }
+
+ $this->appends = array_unique(
+ array_merge($this->appends, $attributes)
+ );
+
+ return $this;
+ }
+
+ /**
+ * Define a one-to-one relationship.
+ *
+ * @param string $related
+ * @param string $foreignKey
+ * @param string $localKey
+ * @return \Illuminate\Database\Eloquent\Relations\HasOne
+ */
+ public function hasOne($related, $foreignKey = null, $localKey = null)
+ {
+ $foreignKey = $foreignKey ?: $this->getForeignKey();
+
+ $instance = new $related;
+
+ $localKey = $localKey ?: $this->getKeyName();
+
+ return new HasOne($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
+ }
+
+ /**
+ * Define a polymorphic one-to-one relationship.
+ *
+ * @param string $related
+ * @param string $name
+ * @param string $type
+ * @param string $id
+ * @param string $localKey
+ * @return \Illuminate\Database\Eloquent\Relations\MorphOne
+ */
+ public function morphOne($related, $name, $type = null, $id = null, $localKey = null)
+ {
+ $instance = new $related;
+
+ list($type, $id) = $this->getMorphs($name, $type, $id);
+
+ $table = $instance->getTable();
+
+ $localKey = $localKey ?: $this->getKeyName();
+
+ return new MorphOne($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
+ }
+
+ /**
+ * Define an inverse one-to-one or many relationship.
+ *
+ * @param string $related
+ * @param string $foreignKey
+ * @param string $otherKey
+ * @param string $relation
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function belongsTo($related, $foreignKey = null, $otherKey = null, $relation = null)
+ {
+ // If no relation name was given, we will use this debug backtrace to extract
+ // the calling method's name and use that as the relationship name as most
+ // of the time this will be what we desire to use for the relationships.
+ if (is_null($relation)) {
+ list($current, $caller) = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
+
+ $relation = $caller['function'];
+ }
+
+ // If no foreign key was supplied, we can use a backtrace to guess the proper
+ // foreign key name by using the name of the relationship function, which
+ // when combined with an "_id" should conventionally match the columns.
+ if (is_null($foreignKey)) {
+ $foreignKey = Str::snake($relation).'_id';
+ }
+
+ $instance = new $related;
+
+ // Once we have the foreign key names, we'll just create a new Eloquent query
+ // for the related models and returns the relationship instance which will
+ // actually be responsible for retrieving and hydrating every relations.
+ $query = $instance->newQuery();
+
+ $otherKey = $otherKey ?: $instance->getKeyName();
+
+ return new BelongsTo($query, $this, $foreignKey, $otherKey, $relation);
+ }
+
+ /**
+ * Define a polymorphic, inverse one-to-one or many relationship.
+ *
+ * @param string $name
+ * @param string $type
+ * @param string $id
+ * @return \Illuminate\Database\Eloquent\Relations\MorphTo
+ */
+ public function morphTo($name = null, $type = null, $id = null)
+ {
+ // If no name is provided, we will use the backtrace to get the function name
+ // since that is most likely the name of the polymorphic interface. We can
+ // use that to get both the class and foreign key that will be utilized.
+ if (is_null($name)) {
+ list($current, $caller) = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
+
+ $name = Str::snake($caller['function']);
+ }
+
+ list($type, $id) = $this->getMorphs($name, $type, $id);
+
+ // If the type value is null it is probably safe to assume we're eager loading
+ // the relationship. When that is the case we will pass in a dummy query as
+ // there are multiple types in the morph and we can't use single queries.
+ if (is_null($class = $this->$type)) {
+ return new MorphTo(
+ $this->newQuery(), $this, $id, null, $type, $name
+ );
+ }
+
+ // If we are not eager loading the relationship we will essentially treat this
+ // as a belongs-to style relationship since morph-to extends that class and
+ // we will pass in the appropriate values so that it behaves as expected.
+ else {
+ $class = $this->getActualClassNameForMorph($class);
+
+ $instance = new $class;
+
+ return new MorphTo(
+ $instance->newQuery(), $this, $id, $instance->getKeyName(), $type, $name
+ );
+ }
+ }
+
+ /**
+ * Retrieve the fully qualified class name from a slug.
+ *
+ * @param string $class
+ * @return string
+ */
+ public function getActualClassNameForMorph($class)
+ {
+ return Arr::get(Relation::morphMap(), $class, $class);
+ }
+
+ /**
+ * Define a one-to-many relationship.
+ *
+ * @param string $related
+ * @param string $foreignKey
+ * @param string $localKey
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ */
+ public function hasMany($related, $foreignKey = null, $localKey = null)
+ {
+ $foreignKey = $foreignKey ?: $this->getForeignKey();
+
+ $instance = new $related;
+
+ $localKey = $localKey ?: $this->getKeyName();
+
+ return new HasMany($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
+ }
+
+ /**
+ * Define a has-many-through relationship.
+ *
+ * @param string $related
+ * @param string $through
+ * @param string|null $firstKey
+ * @param string|null $secondKey
+ * @param string|null $localKey
+ * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
+ */
+ public function hasManyThrough($related, $through, $firstKey = null, $secondKey = null, $localKey = null)
+ {
+ $through = new $through;
+
+ $firstKey = $firstKey ?: $this->getForeignKey();
+
+ $secondKey = $secondKey ?: $through->getForeignKey();
+
+ $localKey = $localKey ?: $this->getKeyName();
+
+ return new HasManyThrough((new $related)->newQuery(), $this, $through, $firstKey, $secondKey, $localKey);
+ }
+
+ /**
+ * Define a polymorphic one-to-many relationship.
+ *
+ * @param string $related
+ * @param string $name
+ * @param string $type
+ * @param string $id
+ * @param string $localKey
+ * @return \Illuminate\Database\Eloquent\Relations\MorphMany
+ */
+ public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
+ {
+ $instance = new $related;
+
+ // Here we will gather up the morph type and ID for the relationship so that we
+ // can properly query the intermediate table of a relation. Finally, we will
+ // get the table and create the relationship instances for the developers.
+ list($type, $id) = $this->getMorphs($name, $type, $id);
+
+ $table = $instance->getTable();
+
+ $localKey = $localKey ?: $this->getKeyName();
+
+ return new MorphMany($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
+ }
+
+ /**
+ * Define a many-to-many relationship.
+ *
+ * @param string $related
+ * @param string $table
+ * @param string $foreignKey
+ * @param string $otherKey
+ * @param string $relation
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
+ */
+ public function belongsToMany($related, $table = null, $foreignKey = null, $otherKey = null, $relation = null)
+ {
+ // If no relationship name was passed, we will pull backtraces to get the
+ // name of the calling function. We will use that function name as the
+ // title of this relation since that is a great convention to apply.
+ if (is_null($relation)) {
+ $relation = $this->getBelongsToManyCaller();
+ }
+
+ // First, we'll need to determine the foreign key and "other key" for the
+ // relationship. Once we have determined the keys we'll make the query
+ // instances as well as the relationship instances we need for this.
+ $foreignKey = $foreignKey ?: $this->getForeignKey();
+
+ $instance = new $related;
+
+ $otherKey = $otherKey ?: $instance->getForeignKey();
+
+ // If no table name was provided, we can guess it by concatenating the two
+ // models using underscores in alphabetical order. The two model names
+ // are transformed to snake case from their default CamelCase also.
+ if (is_null($table)) {
+ $table = $this->joiningTable($related);
+ }
+
+ // Now we're ready to create a new query builder for the related model and
+ // the relationship instances for the relation. The relations will set
+ // appropriate query constraint and entirely manages the hydrations.
+ $query = $instance->newQuery();
+
+ return new BelongsToMany($query, $this, $table, $foreignKey, $otherKey, $relation);
+ }
+
+ /**
+ * Define a polymorphic many-to-many relationship.
+ *
+ * @param string $related
+ * @param string $name
+ * @param string $table
+ * @param string $foreignKey
+ * @param string $otherKey
+ * @param bool $inverse
+ * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
+ */
+ public function morphToMany($related, $name, $table = null, $foreignKey = null, $otherKey = null, $inverse = false)
+ {
+ $caller = $this->getBelongsToManyCaller();
+
+ // First, we will need to determine the foreign key and "other key" for the
+ // relationship. Once we have determined the keys we will make the query
+ // instances, as well as the relationship instances we need for these.
+ $foreignKey = $foreignKey ?: $name.'_id';
+
+ $instance = new $related;
+
+ $otherKey = $otherKey ?: $instance->getForeignKey();
+
+ // Now we're ready to create a new query builder for this related model and
+ // the relationship instances for this relation. This relations will set
+ // appropriate query constraints then entirely manages the hydrations.
+ $query = $instance->newQuery();
+
+ $table = $table ?: Str::plural($name);
+
+ return new MorphToMany(
+ $query, $this, $name, $table, $foreignKey,
+ $otherKey, $caller, $inverse
+ );
+ }
+
+ /**
+ * Define a polymorphic, inverse many-to-many relationship.
+ *
+ * @param string $related
+ * @param string $name
+ * @param string $table
+ * @param string $foreignKey
+ * @param string $otherKey
+ * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
+ */
+ public function morphedByMany($related, $name, $table = null, $foreignKey = null, $otherKey = null)
+ {
+ $foreignKey = $foreignKey ?: $this->getForeignKey();
+
+ // For the inverse of the polymorphic many-to-many relations, we will change
+ // the way we determine the foreign and other keys, as it is the opposite
+ // of the morph-to-many method since we're figuring out these inverses.
+ $otherKey = $otherKey ?: $name.'_id';
+
+ return $this->morphToMany($related, $name, $table, $foreignKey, $otherKey, true);
+ }
+
+ /**
+ * Get the relationship name of the belongs to many.
+ *
+ * @return string
+ */
+ protected function getBelongsToManyCaller()
+ {
+ $self = __FUNCTION__;
+
+ $caller = Arr::first(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), function ($key, $trace) use ($self) {
+ $caller = $trace['function'];
+
+ return ! in_array($caller, Model::$manyMethods) && $caller != $self;
+ });
+
+ return ! is_null($caller) ? $caller['function'] : null;
+ }
+
+ /**
+ * Get the joining table name for a many-to-many relation.
+ *
+ * @param string $related
+ * @return string
+ */
+ public function joiningTable($related)
+ {
+ // The joining table name, by convention, is simply the snake cased models
+ // sorted alphabetically and concatenated with an underscore, so we can
+ // just sort the models and join them together to get the table name.
+ $base = Str::snake(class_basename($this));
+
+ $related = Str::snake(class_basename($related));
+
+ $models = [$related, $base];
+
+ // Now that we have the model names in an array we can just sort them and
+ // use the implode function to join them together with an underscores,
+ // which is typically used by convention within the database system.
+ sort($models);
+
+ return strtolower(implode('_', $models));
+ }
+
+ /**
+ * Destroy the models for the given IDs.
+ *
+ * @param array|int $ids
+ * @return int
+ */
+ public static function destroy($ids)
+ {
+ // We'll initialize a count here so we will return the total number of deletes
+ // for the operation. The developers can then check this number as a boolean
+ // type value or get this total count of records deleted for logging, etc.
+ $count = 0;
+
+ $ids = is_array($ids) ? $ids : func_get_args();
+
+ $instance = new static;
+
+ // We will actually pull the models from the database table and call delete on
+ // each of them individually so that their events get fired properly with a
+ // correct set of attributes in case the developers wants to check these.
+ $key = $instance->getKeyName();
+
+ foreach ($instance->whereIn($key, $ids)->get() as $model) {
+ if ($model->delete()) {
+ $count++;
+ }
+ }
+
+ return $count;
+ }
+
+ /**
+ * Delete the model from the database.
+ *
+ * @return bool|null
+ *
+ * @throws \Exception
+ */
+ public function delete()
+ {
+ if (is_null($this->getKeyName())) {
+ throw new Exception('No primary key defined on model.');
+ }
+
+ if ($this->exists) {
+ if ($this->fireModelEvent('deleting') === false) {
+ return false;
+ }
+
+ // Here, we'll touch the owning models, verifying these timestamps get updated
+ // for the models. This will allow any caching to get broken on the parents
+ // by the timestamp. Then we will go ahead and delete the model instance.
+ $this->touchOwners();
+
+ $this->performDeleteOnModel();
+
+ $this->exists = false;
+
+ // Once the model has been deleted, we will fire off the deleted event so that
+ // the developers may hook into post-delete operations. We will then return
+ // a boolean true as the delete is presumably successful on the database.
+ $this->fireModelEvent('deleted', false);
+
+ return true;
+ }
+ }
+
+ /**
+ * Force a hard delete on a soft deleted model.
+ *
+ * This method protects developers from running forceDelete when trait is missing.
+ *
+ * @return bool|null
+ */
+ public function forceDelete()
+ {
+ return $this->delete();
+ }
+
+ /**
+ * Perform the actual delete query on this model instance.
+ *
+ * @return void
+ */
+ protected function performDeleteOnModel()
+ {
+ $this->setKeysForSaveQuery($this->newQueryWithoutScopes())->delete();
+ }
+
+ /**
+ * Register a saving model event with the dispatcher.
+ *
+ * @param \Closure|string $callback
+ * @param int $priority
+ * @return void
+ */
+ public static function saving($callback, $priority = 0)
+ {
+ static::registerModelEvent('saving', $callback, $priority);
+ }
+
+ /**
+ * Register a saved model event with the dispatcher.
+ *
+ * @param \Closure|string $callback
+ * @param int $priority
+ * @return void
+ */
+ public static function saved($callback, $priority = 0)
+ {
+ static::registerModelEvent('saved', $callback, $priority);
+ }
+
+ /**
+ * Register an updating model event with the dispatcher.
+ *
+ * @param \Closure|string $callback
+ * @param int $priority
+ * @return void
+ */
+ public static function updating($callback, $priority = 0)
+ {
+ static::registerModelEvent('updating', $callback, $priority);
+ }
+
+ /**
+ * Register an updated model event with the dispatcher.
+ *
+ * @param \Closure|string $callback
+ * @param int $priority
+ * @return void
+ */
+ public static function updated($callback, $priority = 0)
+ {
+ static::registerModelEvent('updated', $callback, $priority);
+ }
+
+ /**
+ * Register a creating model event with the dispatcher.
+ *
+ * @param \Closure|string $callback
+ * @param int $priority
+ * @return void
+ */
+ public static function creating($callback, $priority = 0)
+ {
+ static::registerModelEvent('creating', $callback, $priority);
+ }
+
+ /**
+ * Register a created model event with the dispatcher.
+ *
+ * @param \Closure|string $callback
+ * @param int $priority
+ * @return void
+ */
+ public static function created($callback, $priority = 0)
+ {
+ static::registerModelEvent('created', $callback, $priority);
+ }
+
+ /**
+ * Register a deleting model event with the dispatcher.
+ *
+ * @param \Closure|string $callback
+ * @param int $priority
+ * @return void
+ */
+ public static function deleting($callback, $priority = 0)
+ {
+ static::registerModelEvent('deleting', $callback, $priority);
+ }
+
+ /**
+ * Register a deleted model event with the dispatcher.
+ *
+ * @param \Closure|string $callback
+ * @param int $priority
+ * @return void
+ */
+ public static function deleted($callback, $priority = 0)
+ {
+ static::registerModelEvent('deleted', $callback, $priority);
+ }
+
+ /**
+ * Remove all of the event listeners for the model.
+ *
+ * @return void
+ */
+ public static function flushEventListeners()
+ {
+ if (! isset(static::$dispatcher)) {
+ return;
+ }
+
+ $instance = new static;
+
+ foreach ($instance->getObservableEvents() as $event) {
+ static::$dispatcher->forget("eloquent.{$event}: ".get_called_class());
+ }
+ }
+
+ /**
+ * Register a model event with the dispatcher.
+ *
+ * @param string $event
+ * @param \Closure|string $callback
+ * @param int $priority
+ * @return void
+ */
+ protected static function registerModelEvent($event, $callback, $priority = 0)
+ {
+ if (isset(static::$dispatcher)) {
+ $name = get_called_class();
+
+ static::$dispatcher->listen("eloquent.{$event}: {$name}", $callback, $priority);
+ }
+ }
+
+ /**
+ * Get the observable event names.
+ *
+ * @return array
+ */
+ public function getObservableEvents()
+ {
+ return array_merge(
+ [
+ 'creating', 'created', 'updating', 'updated',
+ 'deleting', 'deleted', 'saving', 'saved',
+ 'restoring', 'restored',
+ ],
+ $this->observables
+ );
+ }
+
+ /**
+ * Set the observable event names.
+ *
+ * @param array $observables
+ * @return $this
+ */
+ public function setObservableEvents(array $observables)
+ {
+ $this->observables = $observables;
+
+ return $this;
+ }
+
+ /**
+ * Add an observable event name.
+ *
+ * @param array|mixed $observables
+ * @return void
+ */
+ public function addObservableEvents($observables)
+ {
+ $observables = is_array($observables) ? $observables : func_get_args();
+
+ $this->observables = array_unique(array_merge($this->observables, $observables));
+ }
+
+ /**
+ * Remove an observable event name.
+ *
+ * @param array|mixed $observables
+ * @return void
+ */
+ public function removeObservableEvents($observables)
+ {
+ $observables = is_array($observables) ? $observables : func_get_args();
+
+ $this->observables = array_diff($this->observables, $observables);
+ }
+
+ /**
+ * Increment a column's value by a given amount.
+ *
+ * @param string $column
+ * @param int $amount
+ * @return int
+ */
+ protected function increment($column, $amount = 1)
+ {
+ return $this->incrementOrDecrement($column, $amount, 'increment');
+ }
+
+ /**
+ * Decrement a column's value by a given amount.
+ *
+ * @param string $column
+ * @param int $amount
+ * @return int
+ */
+ protected function decrement($column, $amount = 1)
+ {
+ return $this->incrementOrDecrement($column, $amount, 'decrement');
+ }
+
+ /**
+ * Run the increment or decrement method on the model.
+ *
+ * @param string $column
+ * @param int $amount
+ * @param string $method
+ * @return int
+ */
+ protected function incrementOrDecrement($column, $amount, $method)
+ {
+ $query = $this->newQuery();
+
+ if (! $this->exists) {
+ return $query->{$method}($column, $amount);
+ }
+
+ $this->incrementOrDecrementAttributeValue($column, $amount, $method);
+
+ return $query->where($this->getKeyName(), $this->getKey())->{$method}($column, $amount);
+ }
+
+ /**
+ * Increment the underlying attribute value and sync with original.
+ *
+ * @param string $column
+ * @param int $amount
+ * @param string $method
+ * @return void
+ */
+ protected function incrementOrDecrementAttributeValue($column, $amount, $method)
+ {
+ $this->{$column} = $this->{$column} + ($method == 'increment' ? $amount : $amount * -1);
+
+ $this->syncOriginalAttribute($column);
+ }
+
+ /**
+ * Update the model in the database.
+ *
+ * @param array $attributes
+ * @param array $options
+ * @return bool|int
+ */
+ public function update(array $attributes = [], array $options = [])
+ {
+ if (! $this->exists) {
+ return $this->newQuery()->update($attributes);
+ }
+
+ return $this->fill($attributes)->save($options);
+ }
+
+ /**
+ * Save the model and all of its relationships.
+ *
+ * @return bool
+ */
+ public function push()
+ {
+ if (! $this->save()) {
+ return false;
+ }
+
+ // To sync all of the relationships to the database, we will simply spin through
+ // the relationships and save each model via this "push" method, which allows
+ // us to recurse into all of these nested relations for the model instance.
+ foreach ($this->relations as $models) {
+ $models = $models instanceof Collection
+ ? $models->all() : [$models];
+
+ foreach (array_filter($models) as $model) {
+ if (! $model->push()) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Save the model to the database.
+ *
+ * @param array $options
+ * @return bool
+ */
+ public function save(array $options = [])
+ {
+ $query = $this->newQueryWithoutScopes();
+
+ // If the "saving" event returns false we'll bail out of the save and return
+ // false, indicating that the save failed. This provides a chance for any
+ // listeners to cancel save operations if validations fail or whatever.
+ if ($this->fireModelEvent('saving') === false) {
+ return false;
+ }
+
+ // If the model already exists in the database we can just update our record
+ // that is already in this database using the current IDs in this "where"
+ // clause to only update this model. Otherwise, we'll just insert them.
+ if ($this->exists) {
+ $saved = $this->performUpdate($query, $options);
+ }
+
+ // If the model is brand new, we'll insert it into our database and set the
+ // ID attribute on the model to the value of the newly inserted row's ID
+ // which is typically an auto-increment value managed by the database.
+ else {
+ $saved = $this->performInsert($query, $options);
+ }
+
+ if ($saved) {
+ $this->finishSave($options);
+ }
+
+ return $saved;
+ }
+
+ /**
+ * Save the model to the database using transaction.
+ *
+ * @param array $options
+ * @return bool
+ *
+ * @throws \Throwable
+ */
+ public function saveOrFail(array $options = [])
+ {
+ return $this->getConnection()->transaction(function () use ($options) {
+ return $this->save($options);
+ });
+ }
+
+ /**
+ * Finish processing on a successful save operation.
+ *
+ * @param array $options
+ * @return void
+ */
+ protected function finishSave(array $options)
+ {
+ $this->fireModelEvent('saved', false);
+
+ $this->syncOriginal();
+
+ if (Arr::get($options, 'touch', true)) {
+ $this->touchOwners();
+ }
+ }
+
+ /**
+ * Perform a model update operation.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param array $options
+ * @return bool
+ */
+ protected function performUpdate(Builder $query, array $options = [])
+ {
+ $dirty = $this->getDirty();
+
+ if (count($dirty) > 0) {
+ // If the updating event returns false, we will cancel the update operation so
+ // developers can hook Validation systems into their models and cancel this
+ // operation if the model does not pass validation. Otherwise, we update.
+ if ($this->fireModelEvent('updating') === false) {
+ return false;
+ }
+
+ // First we need to create a fresh query instance and touch the creation and
+ // update timestamp on the model which are maintained by us for developer
+ // convenience. Then we will just continue saving the model instances.
+ if ($this->timestamps && Arr::get($options, 'timestamps', true)) {
+ $this->updateTimestamps();
+ }
+
+ // Once we have run the update operation, we will fire the "updated" event for
+ // this model instance. This will allow developers to hook into these after
+ // models are updated, giving them a chance to do any special processing.
+ $dirty = $this->getDirty();
+
+ if (count($dirty) > 0) {
+ $numRows = $this->setKeysForSaveQuery($query)->update($dirty);
+
+ $this->fireModelEvent('updated', false);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Perform a model insert operation.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param array $options
+ * @return bool
+ */
+ protected function performInsert(Builder $query, array $options = [])
+ {
+ if ($this->fireModelEvent('creating') === false) {
+ return false;
+ }
+
+ // First we'll need to create a fresh query instance and touch the creation and
+ // update timestamps on this model, which are maintained by us for developer
+ // convenience. After, we will just continue saving these model instances.
+ if ($this->timestamps && Arr::get($options, 'timestamps', true)) {
+ $this->updateTimestamps();
+ }
+
+ // If the model has an incrementing key, we can use the "insertGetId" method on
+ // the query builder, which will give us back the final inserted ID for this
+ // table from the database. Not all tables have to be incrementing though.
+ $attributes = $this->attributes;
+
+ if ($this->incrementing) {
+ $this->insertAndSetId($query, $attributes);
+ }
+
+ // If the table isn't incrementing we'll simply insert these attributes as they
+ // are. These attribute arrays must contain an "id" column previously placed
+ // there by the developer as the manually determined key for these models.
+ else {
+ $query->insert($attributes);
+ }
+
+ // We will go ahead and set the exists property to true, so that it is set when
+ // the created event is fired, just in case the developer tries to update it
+ // during the event. This will allow them to do so and run an update here.
+ $this->exists = true;
+
+ $this->wasRecentlyCreated = true;
+
+ $this->fireModelEvent('created', false);
+
+ return true;
+ }
+
+ /**
+ * Insert the given attributes and set the ID on the model.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param array $attributes
+ * @return void
+ */
+ protected function insertAndSetId(Builder $query, $attributes)
+ {
+ $id = $query->insertGetId($attributes, $keyName = $this->getKeyName());
+
+ $this->setAttribute($keyName, $id);
+ }
+
+ /**
+ * Touch the owning relations of the model.
+ *
+ * @return void
+ */
+ public function touchOwners()
+ {
+ foreach ($this->touches as $relation) {
+ $this->$relation()->touch();
+
+ if ($this->$relation instanceof self) {
+ $this->$relation->touchOwners();
+ } elseif ($this->$relation instanceof Collection) {
+ $this->$relation->each(function (Model $relation) {
+ $relation->touchOwners();
+ });
+ }
+ }
+ }
+
+ /**
+ * Determine if the model touches a given relation.
+ *
+ * @param string $relation
+ * @return bool
+ */
+ public function touches($relation)
+ {
+ return in_array($relation, $this->touches);
+ }
+
+ /**
+ * Fire the given event for the model.
+ *
+ * @param string $event
+ * @param bool $halt
+ * @return mixed
+ */
+ protected function fireModelEvent($event, $halt = true)
+ {
+ if (! isset(static::$dispatcher)) {
+ return true;
+ }
+
+ // We will append the names of the class to the event to distinguish it from
+ // other model events that are fired, allowing us to listen on each model
+ // event set individually instead of catching event for all the models.
+ $event = "eloquent.{$event}: ".get_class($this);
+
+ $method = $halt ? 'until' : 'fire';
+
+ return static::$dispatcher->$method($event, $this);
+ }
+
+ /**
+ * Set the keys for a save update query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ protected function setKeysForSaveQuery(Builder $query)
+ {
+ $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());
+
+ return $query;
+ }
+
+ /**
+ * Get the primary key value for a save query.
+ *
+ * @return mixed
+ */
+ protected function getKeyForSaveQuery()
+ {
+ if (isset($this->original[$this->getKeyName()])) {
+ return $this->original[$this->getKeyName()];
+ }
+
+ return $this->getAttribute($this->getKeyName());
+ }
+
+ /**
+ * Update the model's update timestamp.
+ *
+ * @return bool
+ */
+ public function touch()
+ {
+ if (! $this->timestamps) {
+ return false;
+ }
+
+ $this->updateTimestamps();
+
+ return $this->save();
+ }
+
+ /**
+ * Update the creation and update timestamps.
+ *
+ * @return void
+ */
+ protected function updateTimestamps()
+ {
+ $time = $this->freshTimestamp();
+
+ if (! $this->isDirty(static::UPDATED_AT)) {
+ $this->setUpdatedAt($time);
+ }
+
+ if (! $this->exists && ! $this->isDirty(static::CREATED_AT)) {
+ $this->setCreatedAt($time);
+ }
+ }
+
+ /**
+ * Set the value of the "created at" attribute.
+ *
+ * @param mixed $value
+ * @return $this
+ */
+ public function setCreatedAt($value)
+ {
+ $this->{static::CREATED_AT} = $value;
+
+ return $this;
+ }
+
+ /**
+ * Set the value of the "updated at" attribute.
+ *
+ * @param mixed $value
+ * @return $this
+ */
+ public function setUpdatedAt($value)
+ {
+ $this->{static::UPDATED_AT} = $value;
+
+ return $this;
+ }
+
+ /**
+ * Get the name of the "created at" column.
+ *
+ * @return string
+ */
+ public function getCreatedAtColumn()
+ {
+ return static::CREATED_AT;
+ }
+
+ /**
+ * Get the name of the "updated at" column.
+ *
+ * @return string
+ */
+ public function getUpdatedAtColumn()
+ {
+ return static::UPDATED_AT;
+ }
+
+ /**
+ * Get a fresh timestamp for the model.
+ *
+ * @return \Carbon\Carbon
+ */
+ public function freshTimestamp()
+ {
+ return new Carbon;
+ }
+
+ /**
+ * Get a fresh timestamp for the model.
+ *
+ * @return string
+ */
+ public function freshTimestampString()
+ {
+ return $this->fromDateTime($this->freshTimestamp());
+ }
+
+ /**
+ * Get a new query builder for the model's table.
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function newQuery()
+ {
+ $builder = $this->newQueryWithoutScopes();
+
+ foreach ($this->getGlobalScopes() as $identifier => $scope) {
+ $builder->withGlobalScope($identifier, $scope);
+ }
+
+ return $builder;
+ }
+
+ /**
+ * Get a new query instance without a given scope.
+ *
+ * @param \Illuminate\Database\Eloquent\Scope|string $scope
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function newQueryWithoutScope($scope)
+ {
+ $builder = $this->newQuery();
+
+ return $builder->withoutGlobalScope($scope);
+ }
+
+ /**
+ * Get a new query builder that doesn't have any global scopes.
+ *
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public function newQueryWithoutScopes()
+ {
+ $builder = $this->newEloquentBuilder(
+ $this->newBaseQueryBuilder()
+ );
+
+ // Once we have the query builders, we will set the model instances so the
+ // builder can easily access any information it may need from the model
+ // while it is constructing and executing various queries against it.
+ return $builder->setModel($this)->with($this->with);
+ }
+
+ /**
+ * Create a new Eloquent query builder for the model.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public function newEloquentBuilder($query)
+ {
+ return new Builder($query);
+ }
+
+ /**
+ * Get a new query builder instance for the connection.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ protected function newBaseQueryBuilder()
+ {
+ $conn = $this->getConnection();
+
+ $grammar = $conn->getQueryGrammar();
+
+ return new QueryBuilder($conn, $grammar, $conn->getPostProcessor());
+ }
+
+ /**
+ * Create a new Eloquent Collection instance.
+ *
+ * @param array $models
+ * @return \Illuminate\Database\Eloquent\Collection
+ */
+ public function newCollection(array $models = [])
+ {
+ return new Collection($models);
+ }
+
+ /**
+ * Create a new pivot model instance.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $parent
+ * @param array $attributes
+ * @param string $table
+ * @param bool $exists
+ * @return \Illuminate\Database\Eloquent\Relations\Pivot
+ */
+ public function newPivot(Model $parent, array $attributes, $table, $exists)
+ {
+ return new Pivot($parent, $attributes, $table, $exists);
+ }
+
+ /**
+ * Get the table associated with the model.
+ *
+ * @return string
+ */
+ public function getTable()
+ {
+ if (isset($this->table)) {
+ return $this->table;
+ }
+
+ return str_replace('\\', '', Str::snake(Str::plural(class_basename($this))));
+ }
+
+ /**
+ * Set the table associated with the model.
+ *
+ * @param string $table
+ * @return $this
+ */
+ public function setTable($table)
+ {
+ $this->table = $table;
+
+ return $this;
+ }
+
+ /**
+ * Get the value of the model's primary key.
+ *
+ * @return mixed
+ */
+ public function getKey()
+ {
+ return $this->getAttribute($this->getKeyName());
+ }
+
+ /**
+ * Get the queueable identity for the entity.
+ *
+ * @return mixed
+ */
+ public function getQueueableId()
+ {
+ return $this->getKey();
+ }
+
+ /**
+ * Get the primary key for the model.
+ *
+ * @return string
+ */
+ public function getKeyName()
+ {
+ return $this->primaryKey;
+ }
+
+ /**
+ * Set the primary key for the model.
+ *
+ * @param string $key
+ * @return $this
+ */
+ public function setKeyName($key)
+ {
+ $this->primaryKey = $key;
+
+ return $this;
+ }
+
+ /**
+ * Get the table qualified key name.
+ *
+ * @return string
+ */
+ public function getQualifiedKeyName()
+ {
+ return $this->getTable().'.'.$this->getKeyName();
+ }
+
+ /**
+ * Get the value of the model's route key.
+ *
+ * @return mixed
+ */
+ public function getRouteKey()
+ {
+ return $this->getAttribute($this->getRouteKeyName());
+ }
+
+ /**
+ * Get the route key for the model.
+ *
+ * @return string
+ */
+ public function getRouteKeyName()
+ {
+ return $this->getKeyName();
+ }
+
+ /**
+ * Determine if the model uses timestamps.
+ *
+ * @return bool
+ */
+ public function usesTimestamps()
+ {
+ return $this->timestamps;
+ }
+
+ /**
+ * Get the polymorphic relationship columns.
+ *
+ * @param string $name
+ * @param string $type
+ * @param string $id
+ * @return array
+ */
+ protected function getMorphs($name, $type, $id)
+ {
+ $type = $type ?: $name.'_type';
+
+ $id = $id ?: $name.'_id';
+
+ return [$type, $id];
+ }
+
+ /**
+ * Get the class name for polymorphic relations.
+ *
+ * @return string
+ */
+ public function getMorphClass()
+ {
+ $morphMap = Relation::morphMap();
+
+ $class = get_class($this);
+
+ if (! empty($morphMap) && in_array($class, $morphMap)) {
+ return array_search($class, $morphMap, true);
+ }
+
+ return $this->morphClass ?: $class;
+ }
+
+ /**
+ * Get the number of models to return per page.
+ *
+ * @return int
+ */
+ public function getPerPage()
+ {
+ return $this->perPage;
+ }
+
+ /**
+ * Set the number of models to return per page.
+ *
+ * @param int $perPage
+ * @return $this
+ */
+ public function setPerPage($perPage)
+ {
+ $this->perPage = $perPage;
+
+ return $this;
+ }
+
+ /**
+ * Get the default foreign key name for the model.
+ *
+ * @return string
+ */
+ public function getForeignKey()
+ {
+ return Str::snake(class_basename($this)).'_id';
+ }
+
+ /**
+ * Get the hidden attributes for the model.
+ *
+ * @return array
+ */
+ public function getHidden()
+ {
+ return $this->hidden;
+ }
+
+ /**
+ * Set the hidden attributes for the model.
+ *
+ * @param array $hidden
+ * @return $this
+ */
+ public function setHidden(array $hidden)
+ {
+ $this->hidden = $hidden;
+
+ return $this;
+ }
+
+ /**
+ * Add hidden attributes for the model.
+ *
+ * @param array|string|null $attributes
+ * @return void
+ */
+ public function addHidden($attributes = null)
+ {
+ $attributes = is_array($attributes) ? $attributes : func_get_args();
+
+ $this->hidden = array_merge($this->hidden, $attributes);
+ }
+
+ /**
+ * Make the given, typically hidden, attributes visible.
+ *
+ * @param array|string $attributes
+ * @return $this
+ */
+ public function makeVisible($attributes)
+ {
+ $this->hidden = array_diff($this->hidden, (array) $attributes);
+
+ return $this;
+ }
+
+ /**
+ * Make the given, typically hidden, attributes visible.
+ *
+ * @param array|string $attributes
+ * @return $this
+ *
+ * @deprecated since version 5.2. Use the "makeVisible" method directly.
+ */
+ public function withHidden($attributes)
+ {
+ return $this->makeVisible($attributes);
+ }
+
+ /**
+ * Get the visible attributes for the model.
+ *
+ * @return array
+ */
+ public function getVisible()
+ {
+ return $this->visible;
+ }
+
+ /**
+ * Set the visible attributes for the model.
+ *
+ * @param array $visible
+ * @return $this
+ */
+ public function setVisible(array $visible)
+ {
+ $this->visible = $visible;
+
+ return $this;
+ }
+
+ /**
+ * Add visible attributes for the model.
+ *
+ * @param array|string|null $attributes
+ * @return void
+ */
+ public function addVisible($attributes = null)
+ {
+ $attributes = is_array($attributes) ? $attributes : func_get_args();
+
+ $this->visible = array_merge($this->visible, $attributes);
+ }
+
+ /**
+ * Set the accessors to append to model arrays.
+ *
+ * @param array $appends
+ * @return $this
+ */
+ public function setAppends(array $appends)
+ {
+ $this->appends = $appends;
+
+ return $this;
+ }
+
+ /**
+ * Get the fillable attributes for the model.
+ *
+ * @return array
+ */
+ public function getFillable()
+ {
+ return $this->fillable;
+ }
+
+ /**
+ * Set the fillable attributes for the model.
+ *
+ * @param array $fillable
+ * @return $this
+ */
+ public function fillable(array $fillable)
+ {
+ $this->fillable = $fillable;
+
+ return $this;
+ }
+
+ /**
+ * Get the guarded attributes for the model.
+ *
+ * @return array
+ */
+ public function getGuarded()
+ {
+ return $this->guarded;
+ }
+
+ /**
+ * Set the guarded attributes for the model.
+ *
+ * @param array $guarded
+ * @return $this
+ */
+ public function guard(array $guarded)
+ {
+ $this->guarded = $guarded;
+
+ return $this;
+ }
+
+ /**
+ * Disable all mass assignable restrictions.
+ *
+ * @param bool $state
+ * @return void
+ */
+ public static function unguard($state = true)
+ {
+ static::$unguarded = $state;
+ }
+
+ /**
+ * Enable the mass assignment restrictions.
+ *
+ * @return void
+ */
+ public static function reguard()
+ {
+ static::$unguarded = false;
+ }
+
+ /**
+ * Determine if current state is "unguarded".
+ *
+ * @return bool
+ */
+ public static function isUnguarded()
+ {
+ return static::$unguarded;
+ }
+
+ /**
+ * Run the given callable while being unguarded.
+ *
+ * @param callable $callback
+ * @return mixed
+ */
+ public static function unguarded(callable $callback)
+ {
+ if (static::$unguarded) {
+ return $callback();
+ }
+
+ static::unguard();
+
+ $result = $callback();
+
+ static::reguard();
+
+ return $result;
+ }
+
+ /**
+ * Determine if the given attribute may be mass assigned.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function isFillable($key)
+ {
+ if (static::$unguarded) {
+ return true;
+ }
+
+ // If the key is in the "fillable" array, we can of course assume that it's
+ // a fillable attribute. Otherwise, we will check the guarded array when
+ // we need to determine if the attribute is black-listed on the model.
+ if (in_array($key, $this->fillable)) {
+ return true;
+ }
+
+ if ($this->isGuarded($key)) {
+ return false;
+ }
+
+ return empty($this->fillable) && ! Str::startsWith($key, '_');
+ }
+
+ /**
+ * Determine if the given key is guarded.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function isGuarded($key)
+ {
+ return in_array($key, $this->guarded) || $this->guarded == ['*'];
+ }
+
+ /**
+ * Determine if the model is totally guarded.
+ *
+ * @return bool
+ */
+ public function totallyGuarded()
+ {
+ return count($this->fillable) == 0 && $this->guarded == ['*'];
+ }
+
+ /**
+ * Remove the table name from a given key.
+ *
+ * @param string $key
+ * @return string
+ */
+ protected function removeTableFromKey($key)
+ {
+ if (! Str::contains($key, '.')) {
+ return $key;
+ }
+
+ return last(explode('.', $key));
+ }
+
+ /**
+ * Get the relationships that are touched on save.
+ *
+ * @return array
+ */
+ public function getTouchedRelations()
+ {
+ return $this->touches;
+ }
+
+ /**
+ * Set the relationships that are touched on save.
+ *
+ * @param array $touches
+ * @return $this
+ */
+ public function setTouchedRelations(array $touches)
+ {
+ $this->touches = $touches;
+
+ return $this;
+ }
+
+ /**
+ * Get the value indicating whether the IDs are incrementing.
+ *
+ * @return bool
+ */
+ public function getIncrementing()
+ {
+ return $this->incrementing;
+ }
+
+ /**
+ * Set whether IDs are incrementing.
+ *
+ * @param bool $value
+ * @return $this
+ */
+ public function setIncrementing($value)
+ {
+ $this->incrementing = $value;
+
+ return $this;
+ }
+
+ /**
+ * Convert the model instance to JSON.
+ *
+ * @param int $options
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ return json_encode($this->jsonSerialize(), $options);
+ }
+
+ /**
+ * Convert the object into something JSON serializable.
+ *
+ * @return array
+ */
+ public function jsonSerialize()
+ {
+ return $this->toArray();
+ }
+
+ /**
+ * Convert the model instance to an array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ $attributes = $this->attributesToArray();
+
+ return array_merge($attributes, $this->relationsToArray());
+ }
+
+ /**
+ * Convert the model's attributes to an array.
+ *
+ * @return array
+ */
+ public function attributesToArray()
+ {
+ $attributes = $this->getArrayableAttributes();
+
+ // If an attribute is a date, we will cast it to a string after converting it
+ // to a DateTime / Carbon instance. This is so we will get some consistent
+ // formatting while accessing attributes vs. arraying / JSONing a model.
+ foreach ($this->getDates() as $key) {
+ if (! isset($attributes[$key])) {
+ continue;
+ }
+
+ $attributes[$key] = $this->serializeDate(
+ $this->asDateTime($attributes[$key])
+ );
+ }
+
+ $mutatedAttributes = $this->getMutatedAttributes();
+
+ // We want to spin through all the mutated attributes for this model and call
+ // the mutator for the attribute. We cache off every mutated attributes so
+ // we don't have to constantly check on attributes that actually change.
+ foreach ($mutatedAttributes as $key) {
+ if (! array_key_exists($key, $attributes)) {
+ continue;
+ }
+
+ $attributes[$key] = $this->mutateAttributeForArray(
+ $key, $attributes[$key]
+ );
+ }
+
+ // Next we will handle any casts that have been setup for this model and cast
+ // the values to their appropriate type. If the attribute has a mutator we
+ // will not perform the cast on those attributes to avoid any confusion.
+ foreach ($this->getCasts() as $key => $value) {
+ if (! array_key_exists($key, $attributes) ||
+ in_array($key, $mutatedAttributes)) {
+ continue;
+ }
+
+ $attributes[$key] = $this->castAttribute(
+ $key, $attributes[$key]
+ );
+
+ if ($attributes[$key] && ($value === 'date' || $value === 'datetime')) {
+ $attributes[$key] = $this->serializeDate($attributes[$key]);
+ }
+ }
+
+ // Here we will grab all of the appended, calculated attributes to this model
+ // as these attributes are not really in the attributes array, but are run
+ // when we need to array or JSON the model for convenience to the coder.
+ foreach ($this->getArrayableAppends() as $key) {
+ $attributes[$key] = $this->mutateAttributeForArray($key, null);
+ }
+
+ return $attributes;
+ }
+
+ /**
+ * Get an attribute array of all arrayable attributes.
+ *
+ * @return array
+ */
+ protected function getArrayableAttributes()
+ {
+ return $this->getArrayableItems($this->attributes);
+ }
+
+ /**
+ * Get all of the appendable values that are arrayable.
+ *
+ * @return array
+ */
+ protected function getArrayableAppends()
+ {
+ if (! count($this->appends)) {
+ return [];
+ }
+
+ return $this->getArrayableItems(
+ array_combine($this->appends, $this->appends)
+ );
+ }
+
+ /**
+ * Get the model's relationships in array form.
+ *
+ * @return array
+ */
+ public function relationsToArray()
+ {
+ $attributes = [];
+
+ foreach ($this->getArrayableRelations() as $key => $value) {
+ // If the values implements the Arrayable interface we can just call this
+ // toArray method on the instances which will convert both models and
+ // collections to their proper array form and we'll set the values.
+ if ($value instanceof Arrayable) {
+ $relation = $value->toArray();
+ }
+
+ // If the value is null, we'll still go ahead and set it in this list of
+ // attributes since null is used to represent empty relationships if
+ // if it a has one or belongs to type relationships on the models.
+ elseif (is_null($value)) {
+ $relation = $value;
+ }
+
+ // If the relationships snake-casing is enabled, we will snake case this
+ // key so that the relation attribute is snake cased in this returned
+ // array to the developers, making this consistent with attributes.
+ if (static::$snakeAttributes) {
+ $key = Str::snake($key);
+ }
+
+ // If the relation value has been set, we will set it on this attributes
+ // list for returning. If it was not arrayable or null, we'll not set
+ // the value on the array because it is some type of invalid value.
+ if (isset($relation) || is_null($value)) {
+ $attributes[$key] = $relation;
+ }
+
+ unset($relation);
+ }
+
+ return $attributes;
+ }
+
+ /**
+ * Get an attribute array of all arrayable relations.
+ *
+ * @return array
+ */
+ protected function getArrayableRelations()
+ {
+ return $this->getArrayableItems($this->relations);
+ }
+
+ /**
+ * Get an attribute array of all arrayable values.
+ *
+ * @param array $values
+ * @return array
+ */
+ protected function getArrayableItems(array $values)
+ {
+ if (count($this->getVisible()) > 0) {
+ return array_intersect_key($values, array_flip($this->getVisible()));
+ }
+
+ return array_diff_key($values, array_flip($this->getHidden()));
+ }
+
+ /**
+ * Get an attribute from the model.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function getAttribute($key)
+ {
+ if (array_key_exists($key, $this->attributes) || $this->hasGetMutator($key)) {
+ return $this->getAttributeValue($key);
+ }
+
+ return $this->getRelationValue($key);
+ }
+
+ /**
+ * Get a plain attribute (not a relationship).
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function getAttributeValue($key)
+ {
+ $value = $this->getAttributeFromArray($key);
+
+ // If the attribute has a get mutator, we will call that then return what
+ // it returns as the value, which is useful for transforming values on
+ // retrieval from the model to a form that is more useful for usage.
+ if ($this->hasGetMutator($key)) {
+ return $this->mutateAttribute($key, $value);
+ }
+
+ // If the attribute exists within the cast array, we will convert it to
+ // an appropriate native PHP type dependant upon the associated value
+ // given with the key in the pair. Dayle made this comment line up.
+ if ($this->hasCast($key)) {
+ $value = $this->castAttribute($key, $value);
+ }
+
+ // If the attribute is listed as a date, we will convert it to a DateTime
+ // instance on retrieval, which makes it quite convenient to work with
+ // date fields without having to create a mutator for each property.
+ elseif (in_array($key, $this->getDates())) {
+ if (! is_null($value)) {
+ return $this->asDateTime($value);
+ }
+ }
+
+ return $value;
+ }
+
+ /**
+ * Get a relationship.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function getRelationValue($key)
+ {
+ // If the key already exists in the relationships array, it just means the
+ // relationship has already been loaded, so we'll just return it out of
+ // here because there is no need to query within the relations twice.
+ if ($this->relationLoaded($key)) {
+ return $this->relations[$key];
+ }
+
+ // If the "attribute" exists as a method on the model, we will just assume
+ // it is a relationship and will load and return results from the query
+ // and hydrate the relationship's value on the "relationships" array.
+ if (method_exists($this, $key)) {
+ return $this->getRelationshipFromMethod($key);
+ }
+ }
+
+ /**
+ * Get an attribute from the $attributes array.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ protected function getAttributeFromArray($key)
+ {
+ if (array_key_exists($key, $this->attributes)) {
+ return $this->attributes[$key];
+ }
+ }
+
+ /**
+ * Get a relationship value from a method.
+ *
+ * @param string $method
+ * @return mixed
+ *
+ * @throws \LogicException
+ */
+ protected function getRelationshipFromMethod($method)
+ {
+ $relations = $this->$method();
+
+ if (! $relations instanceof Relation) {
+ throw new LogicException('Relationship method must return an object of type '
+ .'Illuminate\Database\Eloquent\Relations\Relation');
+ }
+
+ return $this->relations[$method] = $relations->getResults();
+ }
+
+ /**
+ * Determine if a get mutator exists for an attribute.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function hasGetMutator($key)
+ {
+ return method_exists($this, 'get'.Str::studly($key).'Attribute');
+ }
+
+ /**
+ * Get the value of an attribute using its mutator.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return mixed
+ */
+ protected function mutateAttribute($key, $value)
+ {
+ return $this->{'get'.Str::studly($key).'Attribute'}($value);
+ }
+
+ /**
+ * Get the value of an attribute using its mutator for array conversion.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return mixed
+ */
+ protected function mutateAttributeForArray($key, $value)
+ {
+ $value = $this->mutateAttribute($key, $value);
+
+ return $value instanceof Arrayable ? $value->toArray() : $value;
+ }
+
+ /**
+ * Determine whether an attribute should be cast to a native type.
+ *
+ * @param string $key
+ * @param array|string|null $types
+ * @return bool
+ */
+ protected function hasCast($key, $types = null)
+ {
+ if (array_key_exists($key, $this->getCasts())) {
+ return $types ? in_array($this->getCastType($key), (array) $types, true) : true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the casts array.
+ *
+ * @return array
+ */
+ protected function getCasts()
+ {
+ if ($this->incrementing) {
+ return array_merge([
+ $this->getKeyName() => 'int',
+ ], $this->casts);
+ }
+
+ return $this->casts;
+ }
+
+ /**
+ * Determine whether a value is Date / DateTime castable for inbound manipulation.
+ *
+ * @param string $key
+ * @return bool
+ */
+ protected function isDateCastable($key)
+ {
+ return $this->hasCast($key, ['date', 'datetime']);
+ }
+
+ /**
+ * Determine whether a value is JSON castable for inbound manipulation.
+ *
+ * @param string $key
+ * @return bool
+ */
+ protected function isJsonCastable($key)
+ {
+ return $this->hasCast($key, ['array', 'json', 'object', 'collection']);
+ }
+
+ /**
+ * Get the type of cast for a model attribute.
+ *
+ * @param string $key
+ * @return string
+ */
+ protected function getCastType($key)
+ {
+ return trim(strtolower($this->getCasts()[$key]));
+ }
+
+ /**
+ * Cast an attribute to a native PHP type.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return mixed
+ */
+ protected function castAttribute($key, $value)
+ {
+ if (is_null($value)) {
+ return $value;
+ }
+
+ switch ($this->getCastType($key)) {
+ case 'int':
+ case 'integer':
+ return (int) $value;
+ case 'real':
+ case 'float':
+ case 'double':
+ return (float) $value;
+ case 'string':
+ return (string) $value;
+ case 'bool':
+ case 'boolean':
+ return (bool) $value;
+ case 'object':
+ return $this->fromJson($value, true);
+ case 'array':
+ case 'json':
+ return $this->fromJson($value);
+ case 'collection':
+ return new BaseCollection($this->fromJson($value));
+ case 'date':
+ case 'datetime':
+ return $this->asDateTime($value);
+ case 'timestamp':
+ return $this->asTimeStamp($value);
+ default:
+ return $value;
+ }
+ }
+
+ /**
+ * Set a given attribute on the model.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return $this
+ */
+ public function setAttribute($key, $value)
+ {
+ // First we will check for the presence of a mutator for the set operation
+ // which simply lets the developers tweak the attribute as it is set on
+ // the model, such as "json_encoding" an listing of data for storage.
+ if ($this->hasSetMutator($key)) {
+ $method = 'set'.Str::studly($key).'Attribute';
+
+ return $this->{$method}($value);
+ }
+
+ // If an attribute is listed as a "date", we'll convert it from a DateTime
+ // instance into a form proper for storage on the database tables using
+ // the connection grammar's date format. We will auto set the values.
+ elseif ($value && (in_array($key, $this->getDates()) || $this->isDateCastable($key))) {
+ $value = $this->fromDateTime($value);
+ }
+
+ if ($this->isJsonCastable($key) && ! is_null($value)) {
+ $value = $this->asJson($value);
+ }
+
+ $this->attributes[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Determine if a set mutator exists for an attribute.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function hasSetMutator($key)
+ {
+ return method_exists($this, 'set'.Str::studly($key).'Attribute');
+ }
+
+ /**
+ * Get the attributes that should be converted to dates.
+ *
+ * @return array
+ */
+ public function getDates()
+ {
+ $defaults = [static::CREATED_AT, static::UPDATED_AT];
+
+ return $this->timestamps ? array_merge($this->dates, $defaults) : $this->dates;
+ }
+
+ /**
+ * Convert a DateTime to a storable string.
+ *
+ * @param \DateTime|int $value
+ * @return string
+ */
+ public function fromDateTime($value)
+ {
+ $format = $this->getDateFormat();
+
+ $value = $this->asDateTime($value);
+
+ return $value->format($format);
+ }
+
+ /**
+ * Return a timestamp as DateTime object.
+ *
+ * @param mixed $value
+ * @return \Carbon\Carbon
+ */
+ protected function asDateTime($value)
+ {
+ // If this value is already a Carbon instance, we shall just return it as is.
+ // This prevents us having to reinstantiate a Carbon instance when we know
+ // it already is one, which wouldn't be fulfilled by the DateTime check.
+ if ($value instanceof Carbon) {
+ return $value;
+ }
+
+ // If the value is already a DateTime instance, we will just skip the rest of
+ // these checks since they will be a waste of time, and hinder performance
+ // when checking the field. We will just return the DateTime right away.
+ if ($value instanceof DateTime) {
+ return Carbon::instance($value);
+ }
+
+ // If this value is an integer, we will assume it is a UNIX timestamp's value
+ // and format a Carbon object from this timestamp. This allows flexibility
+ // when defining your date fields as they might be UNIX timestamps here.
+ if (is_numeric($value)) {
+ return Carbon::createFromTimestamp($value);
+ }
+
+ // If the value is in simply year, month, day format, we will instantiate the
+ // Carbon instances from that format. Again, this provides for simple date
+ // fields on the database, while still supporting Carbonized conversion.
+ if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $value)) {
+ return Carbon::createFromFormat('Y-m-d', $value)->startOfDay();
+ }
+
+ // Finally, we will just assume this date is in the format used by default on
+ // the database connection and use that format to create the Carbon object
+ // that is returned back out to the developers after we convert it here.
+ return Carbon::createFromFormat($this->getDateFormat(), $value);
+ }
+
+ /**
+ * Return a timestamp as unix timestamp.
+ *
+ * @param mixed $value
+ * @return int
+ */
+ protected function asTimeStamp($value)
+ {
+ return (int) $this->asDateTime($value)->timestamp;
+ }
+
+ /**
+ * Prepare a date for array / JSON serialization.
+ *
+ * @param \DateTime $date
+ * @return string
+ */
+ protected function serializeDate(DateTime $date)
+ {
+ return $date->format($this->getDateFormat());
+ }
+
+ /**
+ * Get the format for database stored dates.
+ *
+ * @return string
+ */
+ protected function getDateFormat()
+ {
+ return $this->dateFormat ?: $this->getConnection()->getQueryGrammar()->getDateFormat();
+ }
+
+ /**
+ * Set the date format used by the model.
+ *
+ * @param string $format
+ * @return $this
+ */
+ public function setDateFormat($format)
+ {
+ $this->dateFormat = $format;
+
+ return $this;
+ }
+
+ /**
+ * Encode the given value as JSON.
+ *
+ * @param mixed $value
+ * @return string
+ */
+ protected function asJson($value)
+ {
+ return json_encode($value);
+ }
+
+ /**
+ * Decode the given JSON back into an array or object.
+ *
+ * @param string $value
+ * @param bool $asObject
+ * @return mixed
+ */
+ public function fromJson($value, $asObject = false)
+ {
+ return json_decode($value, ! $asObject);
+ }
+
+ /**
+ * Clone the model into a new, non-existing instance.
+ *
+ * @param array|null $except
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function replicate(array $except = null)
+ {
+ $except = $except ?: [
+ $this->getKeyName(),
+ $this->getCreatedAtColumn(),
+ $this->getUpdatedAtColumn(),
+ ];
+
+ $attributes = Arr::except($this->attributes, $except);
+
+ with($instance = new static)->setRawAttributes($attributes);
+
+ return $instance->setRelations($this->relations);
+ }
+
+ /**
+ * Get all of the current attributes on the model.
+ *
+ * @return array
+ */
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Set the array of model attributes. No checking is done.
+ *
+ * @param array $attributes
+ * @param bool $sync
+ * @return $this
+ */
+ public function setRawAttributes(array $attributes, $sync = false)
+ {
+ $this->attributes = $attributes;
+
+ if ($sync) {
+ $this->syncOriginal();
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get the model's original attribute values.
+ *
+ * @param string|null $key
+ * @param mixed $default
+ * @return array
+ */
+ public function getOriginal($key = null, $default = null)
+ {
+ return Arr::get($this->original, $key, $default);
+ }
+
+ /**
+ * Sync the original attributes with the current.
+ *
+ * @return $this
+ */
+ public function syncOriginal()
+ {
+ $this->original = $this->attributes;
+
+ return $this;
+ }
+
+ /**
+ * Sync a single original attribute with its current value.
+ *
+ * @param string $attribute
+ * @return $this
+ */
+ public function syncOriginalAttribute($attribute)
+ {
+ $this->original[$attribute] = $this->attributes[$attribute];
+
+ return $this;
+ }
+
+ /**
+ * Determine if the model or given attribute(s) have been modified.
+ *
+ * @param array|string|null $attributes
+ * @return bool
+ */
+ public function isDirty($attributes = null)
+ {
+ $dirty = $this->getDirty();
+
+ if (is_null($attributes)) {
+ return count($dirty) > 0;
+ }
+
+ if (! is_array($attributes)) {
+ $attributes = func_get_args();
+ }
+
+ foreach ($attributes as $attribute) {
+ if (array_key_exists($attribute, $dirty)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the attributes that have been changed since last sync.
+ *
+ * @return array
+ */
+ public function getDirty()
+ {
+ $dirty = [];
+
+ foreach ($this->attributes as $key => $value) {
+ if (! array_key_exists($key, $this->original)) {
+ $dirty[$key] = $value;
+ } elseif ($value !== $this->original[$key] &&
+ ! $this->originalIsNumericallyEquivalent($key)) {
+ $dirty[$key] = $value;
+ }
+ }
+
+ return $dirty;
+ }
+
+ /**
+ * Determine if the new and old values for a given key are numerically equivalent.
+ *
+ * @param string $key
+ * @return bool
+ */
+ protected function originalIsNumericallyEquivalent($key)
+ {
+ $current = $this->attributes[$key];
+
+ $original = $this->original[$key];
+
+ return is_numeric($current) && is_numeric($original) && strcmp((string) $current, (string) $original) === 0;
+ }
+
+ /**
+ * Get all the loaded relations for the instance.
+ *
+ * @return array
+ */
+ public function getRelations()
+ {
+ return $this->relations;
+ }
+
+ /**
+ * Get a specified relationship.
+ *
+ * @param string $relation
+ * @return mixed
+ */
+ public function getRelation($relation)
+ {
+ return $this->relations[$relation];
+ }
+
+ /**
+ * Determine if the given relation is loaded.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function relationLoaded($key)
+ {
+ return array_key_exists($key, $this->relations);
+ }
+
+ /**
+ * Set the specific relationship in the model.
+ *
+ * @param string $relation
+ * @param mixed $value
+ * @return $this
+ */
+ public function setRelation($relation, $value)
+ {
+ $this->relations[$relation] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Set the entire relations array on the model.
+ *
+ * @param array $relations
+ * @return $this
+ */
+ public function setRelations(array $relations)
+ {
+ $this->relations = $relations;
+
+ return $this;
+ }
+
+ /**
+ * Get the database connection for the model.
+ *
+ * @return \Illuminate\Database\Connection
+ */
+ public function getConnection()
+ {
+ return static::resolveConnection($this->connection);
+ }
+
+ /**
+ * Get the current connection name for the model.
+ *
+ * @return string
+ */
+ public function getConnectionName()
+ {
+ return $this->connection;
+ }
+
+ /**
+ * Set the connection associated with the model.
+ *
+ * @param string $name
+ * @return $this
+ */
+ public function setConnection($name)
+ {
+ $this->connection = $name;
+
+ return $this;
+ }
+
+ /**
+ * Resolve a connection instance.
+ *
+ * @param string|null $connection
+ * @return \Illuminate\Database\Connection
+ */
+ public static function resolveConnection($connection = null)
+ {
+ return static::$resolver->connection($connection);
+ }
+
+ /**
+ * Get the connection resolver instance.
+ *
+ * @return \Illuminate\Database\ConnectionResolverInterface
+ */
+ public static function getConnectionResolver()
+ {
+ return static::$resolver;
+ }
+
+ /**
+ * Set the connection resolver instance.
+ *
+ * @param \Illuminate\Database\ConnectionResolverInterface $resolver
+ * @return void
+ */
+ public static function setConnectionResolver(Resolver $resolver)
+ {
+ static::$resolver = $resolver;
+ }
+
+ /**
+ * Unset the connection resolver for models.
+ *
+ * @return void
+ */
+ public static function unsetConnectionResolver()
+ {
+ static::$resolver = null;
+ }
+
+ /**
+ * Get the event dispatcher instance.
+ *
+ * @return \Illuminate\Contracts\Events\Dispatcher
+ */
+ public static function getEventDispatcher()
+ {
+ return static::$dispatcher;
+ }
+
+ /**
+ * Set the event dispatcher instance.
+ *
+ * @param \Illuminate\Contracts\Events\Dispatcher $dispatcher
+ * @return void
+ */
+ public static function setEventDispatcher(Dispatcher $dispatcher)
+ {
+ static::$dispatcher = $dispatcher;
+ }
+
+ /**
+ * Unset the event dispatcher for models.
+ *
+ * @return void
+ */
+ public static function unsetEventDispatcher()
+ {
+ static::$dispatcher = null;
+ }
+
+ /**
+ * Get the mutated attributes for a given instance.
+ *
+ * @return array
+ */
+ public function getMutatedAttributes()
+ {
+ $class = get_class($this);
+
+ if (! isset(static::$mutatorCache[$class])) {
+ static::cacheMutatedAttributes($class);
+ }
+
+ return static::$mutatorCache[$class];
+ }
+
+ /**
+ * Extract and cache all the mutated attributes of a class.
+ *
+ * @param string $class
+ * @return void
+ */
+ public static function cacheMutatedAttributes($class)
+ {
+ $mutatedAttributes = [];
+
+ // Here we will extract all of the mutated attributes so that we can quickly
+ // spin through them after we export models to their array form, which we
+ // need to be fast. This'll let us know the attributes that can mutate.
+ if (preg_match_all('/(?<=^|;)get([^;]+?)Attribute(;|$)/', implode(';', get_class_methods($class)), $matches)) {
+ foreach ($matches[1] as $match) {
+ if (static::$snakeAttributes) {
+ $match = Str::snake($match);
+ }
+
+ $mutatedAttributes[] = lcfirst($match);
+ }
+ }
+
+ static::$mutatorCache[$class] = $mutatedAttributes;
+ }
+
+ /**
+ * Dynamically retrieve attributes on the model.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function __get($key)
+ {
+ return $this->getAttribute($key);
+ }
+
+ /**
+ * Dynamically set attributes on the model.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this->setAttribute($key, $value);
+ }
+
+ /**
+ * Determine if the given attribute exists.
+ *
+ * @param mixed $offset
+ * @return bool
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->$offset);
+ }
+
+ /**
+ * Get the value for a given offset.
+ *
+ * @param mixed $offset
+ * @return mixed
+ */
+ public function offsetGet($offset)
+ {
+ return $this->$offset;
+ }
+
+ /**
+ * Set the value for a given offset.
+ *
+ * @param mixed $offset
+ * @param mixed $value
+ * @return void
+ */
+ public function offsetSet($offset, $value)
+ {
+ $this->$offset = $value;
+ }
+
+ /**
+ * Unset the value for a given offset.
+ *
+ * @param mixed $offset
+ * @return void
+ */
+ public function offsetUnset($offset)
+ {
+ unset($this->$offset);
+ }
+
+ /**
+ * Determine if an attribute exists on the model.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function __isset($key)
+ {
+ return (isset($this->attributes[$key]) || isset($this->relations[$key])) ||
+ ($this->hasGetMutator($key) && ! is_null($this->getAttributeValue($key)));
+ }
+
+ /**
+ * Unset an attribute on the model.
+ *
+ * @param string $key
+ * @return void
+ */
+ public function __unset($key)
+ {
+ unset($this->attributes[$key], $this->relations[$key]);
+ }
+
+ /**
+ * Handle dynamic method calls into the model.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ if (in_array($method, ['increment', 'decrement'])) {
+ return call_user_func_array([$this, $method], $parameters);
+ }
+
+ $query = $this->newQuery();
+
+ return call_user_func_array([$query, $method], $parameters);
+ }
+
+ /**
+ * Handle dynamic static method calls into the method.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public static function __callStatic($method, $parameters)
+ {
+ $instance = new static;
+
+ return call_user_func_array([$instance, $method], $parameters);
+ }
+
+ /**
+ * Convert the model to its string representation.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->toJson();
+ }
+
+ /**
+ * When a model is being unserialized, check if it needs to be booted.
+ *
+ * @return void
+ */
+ public function __wakeup()
+ {
+ $this->bootIfNotBooted();
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/ModelNotFoundException.php b/vendor/illuminate/database/Eloquent/ModelNotFoundException.php
new file mode 100755
index 00000000..102683aa
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/ModelNotFoundException.php
@@ -0,0 +1,40 @@
+model = $model;
+
+ $this->message = "No query results for model [{$model}].";
+
+ return $this;
+ }
+
+ /**
+ * Get the affected Eloquent model.
+ *
+ * @return string
+ */
+ public function getModel()
+ {
+ return $this->model;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/QueueEntityResolver.php b/vendor/illuminate/database/Eloquent/QueueEntityResolver.php
new file mode 100644
index 00000000..0e630c79
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/QueueEntityResolver.php
@@ -0,0 +1,27 @@
+find($id);
+
+ if ($instance) {
+ return $instance;
+ }
+
+ throw new EntityNotFoundException($type, $id);
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php b/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php
new file mode 100755
index 00000000..5fa26a4f
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php
@@ -0,0 +1,306 @@
+otherKey = $otherKey;
+ $this->relation = $relation;
+ $this->foreignKey = $foreignKey;
+
+ parent::__construct($query, $parent);
+ }
+
+ /**
+ * Get the results of the relationship.
+ *
+ * @return mixed
+ */
+ public function getResults()
+ {
+ return $this->query->first();
+ }
+
+ /**
+ * Set the base constraints on the relation query.
+ *
+ * @return void
+ */
+ public function addConstraints()
+ {
+ if (static::$constraints) {
+ // For belongs to relationships, which are essentially the inverse of has one
+ // or has many relationships, we need to actually query on the primary key
+ // of the related models matching on the foreign key that's on a parent.
+ $table = $this->related->getTable();
+
+ $this->query->where($table.'.'.$this->otherKey, '=', $this->parent->{$this->foreignKey});
+ }
+ }
+
+ /**
+ * Add the constraints for a relationship count query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Database\Eloquent\Builder $parent
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getRelationCountQuery(Builder $query, Builder $parent)
+ {
+ if ($parent->getQuery()->from == $query->getQuery()->from) {
+ return $this->getRelationCountQueryForSelfRelation($query, $parent);
+ }
+
+ $query->select(new Expression('count(*)'));
+
+ $otherKey = $this->wrap($query->getModel()->getTable().'.'.$this->otherKey);
+
+ return $query->where($this->getQualifiedForeignKey(), '=', new Expression($otherKey));
+ }
+
+ /**
+ * Add the constraints for a relationship count query on the same table.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Database\Eloquent\Builder $parent
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getRelationCountQueryForSelfRelation(Builder $query, Builder $parent)
+ {
+ $query->select(new Expression('count(*)'));
+
+ $query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash());
+
+ $key = $this->wrap($this->getQualifiedForeignKey());
+
+ return $query->where($hash.'.'.$query->getModel()->getKeyName(), '=', new Expression($key));
+ }
+
+ /**
+ * Get a relationship join table hash.
+ *
+ * @return string
+ */
+ public function getRelationCountHash()
+ {
+ return 'self_'.md5(microtime(true));
+ }
+
+ /**
+ * Set the constraints for an eager load of the relation.
+ *
+ * @param array $models
+ * @return void
+ */
+ public function addEagerConstraints(array $models)
+ {
+ // We'll grab the primary key name of the related models since it could be set to
+ // a non-standard name and not "id". We will then construct the constraint for
+ // our eagerly loading query so it returns the proper models from execution.
+ $key = $this->related->getTable().'.'.$this->otherKey;
+
+ $this->query->whereIn($key, $this->getEagerModelKeys($models));
+ }
+
+ /**
+ * Gather the keys from an array of related models.
+ *
+ * @param array $models
+ * @return array
+ */
+ protected function getEagerModelKeys(array $models)
+ {
+ $keys = [];
+
+ // First we need to gather all of the keys from the parent models so we know what
+ // to query for via the eager loading query. We will add them to an array then
+ // execute a "where in" statement to gather up all of those related records.
+ foreach ($models as $model) {
+ if (! is_null($value = $model->{$this->foreignKey})) {
+ $keys[] = $value;
+ }
+ }
+
+ // If there are no keys that were not null we will just return an array with 0 in
+ // it so the query doesn't fail, but will not return any results, which should
+ // be what this developer is expecting in a case where this happens to them.
+ if (count($keys) == 0) {
+ return [0];
+ }
+
+ return array_values(array_unique($keys));
+ }
+
+ /**
+ * Initialize the relation on a set of models.
+ *
+ * @param array $models
+ * @param string $relation
+ * @return array
+ */
+ public function initRelation(array $models, $relation)
+ {
+ foreach ($models as $model) {
+ $model->setRelation($relation, null);
+ }
+
+ return $models;
+ }
+
+ /**
+ * Match the eagerly loaded results to their parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ public function match(array $models, Collection $results, $relation)
+ {
+ $foreign = $this->foreignKey;
+
+ $other = $this->otherKey;
+
+ // First we will get to build a dictionary of the child models by their primary
+ // key of the relationship, then we can easily match the children back onto
+ // the parents using that dictionary and the primary key of the children.
+ $dictionary = [];
+
+ foreach ($results as $result) {
+ $dictionary[$result->getAttribute($other)] = $result;
+ }
+
+ // Once we have the dictionary constructed, we can loop through all the parents
+ // and match back onto their children using these keys of the dictionary and
+ // the primary key of the children to map them onto the correct instances.
+ foreach ($models as $model) {
+ if (isset($dictionary[$model->$foreign])) {
+ $model->setRelation($relation, $dictionary[$model->$foreign]);
+ }
+ }
+
+ return $models;
+ }
+
+ /**
+ * Associate the model instance to the given parent.
+ *
+ * @param \Illuminate\Database\Eloquent\Model|int $model
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function associate($model)
+ {
+ $otherKey = ($model instanceof Model ? $model->getAttribute($this->otherKey) : $model);
+
+ $this->parent->setAttribute($this->foreignKey, $otherKey);
+
+ if ($model instanceof Model) {
+ $this->parent->setRelation($this->relation, $model);
+ }
+
+ return $this->parent;
+ }
+
+ /**
+ * Dissociate previously associated model from the given parent.
+ *
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function dissociate()
+ {
+ $this->parent->setAttribute($this->foreignKey, null);
+
+ return $this->parent->setRelation($this->relation, null);
+ }
+
+ /**
+ * Update the parent model on the relationship.
+ *
+ * @param array $attributes
+ * @return mixed
+ */
+ public function update(array $attributes)
+ {
+ $instance = $this->getResults();
+
+ return $instance->fill($attributes)->save();
+ }
+
+ /**
+ * Get the foreign key of the relationship.
+ *
+ * @return string
+ */
+ public function getForeignKey()
+ {
+ return $this->foreignKey;
+ }
+
+ /**
+ * Get the fully qualified foreign key of the relationship.
+ *
+ * @return string
+ */
+ public function getQualifiedForeignKey()
+ {
+ return $this->parent->getTable().'.'.$this->foreignKey;
+ }
+
+ /**
+ * Get the associated key of the relationship.
+ *
+ * @return string
+ */
+ public function getOtherKey()
+ {
+ return $this->otherKey;
+ }
+
+ /**
+ * Get the fully qualified associated key of the relationship.
+ *
+ * @return string
+ */
+ public function getQualifiedOtherKeyName()
+ {
+ return $this->related->getTable().'.'.$this->otherKey;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php b/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php
new file mode 100755
index 00000000..83ef871f
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php
@@ -0,0 +1,1251 @@
+table = $table;
+ $this->otherKey = $otherKey;
+ $this->foreignKey = $foreignKey;
+ $this->relationName = $relationName;
+
+ parent::__construct($query, $parent);
+ }
+
+ /**
+ * Get the results of the relationship.
+ *
+ * @return mixed
+ */
+ public function getResults()
+ {
+ return $this->get();
+ }
+
+ /**
+ * Set a where clause for a pivot table column.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param mixed $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
+ */
+ public function wherePivot($column, $operator = null, $value = null, $boolean = 'and')
+ {
+ $this->pivotWheres[] = func_get_args();
+
+ return $this->where($this->table.'.'.$column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Set an or where clause for a pivot table column.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
+ */
+ public function orWherePivot($column, $operator = null, $value = null)
+ {
+ return $this->wherePivot($column, $operator, $value, 'or');
+ }
+
+ /**
+ * Execute the query and get the first result.
+ *
+ * @param array $columns
+ * @return mixed
+ */
+ public function first($columns = ['*'])
+ {
+ $results = $this->take(1)->get($columns);
+
+ return count($results) > 0 ? $results->first() : null;
+ }
+
+ /**
+ * Execute the query and get the first result or throw an exception.
+ *
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model|static
+ *
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ */
+ public function firstOrFail($columns = ['*'])
+ {
+ if (! is_null($model = $this->first($columns))) {
+ return $model;
+ }
+
+ throw new ModelNotFoundException;
+ }
+
+ /**
+ * Execute the query as a "select" statement.
+ *
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Collection
+ */
+ public function get($columns = ['*'])
+ {
+ // First we'll add the proper select columns onto the query so it is run with
+ // the proper columns. Then, we will get the results and hydrate out pivot
+ // models with the result of those columns as a separate model relation.
+ $columns = $this->query->getQuery()->columns ? [] : $columns;
+
+ $select = $this->getSelectColumns($columns);
+
+ $models = $this->query->addSelect($select)->getModels();
+
+ $this->hydratePivotRelation($models);
+
+ // If we actually found models we will also eager load any relationships that
+ // have been specified as needing to be eager loaded. This will solve the
+ // n + 1 query problem for the developer and also increase performance.
+ if (count($models) > 0) {
+ $models = $this->query->eagerLoadRelations($models);
+ }
+
+ return $this->related->newCollection($models);
+ }
+
+ /**
+ * Get a paginator for the "select" statement.
+ *
+ * @param int $perPage
+ * @param array $columns
+ * @param string $pageName
+ * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+ */
+ public function paginate($perPage = null, $columns = ['*'], $pageName = 'page')
+ {
+ $this->query->addSelect($this->getSelectColumns($columns));
+
+ $paginator = $this->query->paginate($perPage, $columns, $pageName);
+
+ $this->hydratePivotRelation($paginator->items());
+
+ return $paginator;
+ }
+
+ /**
+ * Paginate the given query into a simple paginator.
+ *
+ * @param int $perPage
+ * @param array $columns
+ * @return \Illuminate\Contracts\Pagination\Paginator
+ */
+ public function simplePaginate($perPage = null, $columns = ['*'])
+ {
+ $this->query->addSelect($this->getSelectColumns($columns));
+
+ $paginator = $this->query->simplePaginate($perPage, $columns);
+
+ $this->hydratePivotRelation($paginator->items());
+
+ return $paginator;
+ }
+
+ /**
+ * Chunk the results of the query.
+ *
+ * @param int $count
+ * @param callable $callback
+ * @return void
+ */
+ public function chunk($count, callable $callback)
+ {
+ $this->query->addSelect($this->getSelectColumns());
+
+ $this->query->chunk($count, function ($results) use ($callback) {
+ $this->hydratePivotRelation($results->all());
+
+ call_user_func($callback, $results);
+ });
+ }
+
+ /**
+ * Hydrate the pivot table relationship on the models.
+ *
+ * @param array $models
+ * @return void
+ */
+ protected function hydratePivotRelation(array $models)
+ {
+ // To hydrate the pivot relationship, we will just gather the pivot attributes
+ // and create a new Pivot model, which is basically a dynamic model that we
+ // will set the attributes, table, and connections on so it they be used.
+ foreach ($models as $model) {
+ $pivot = $this->newExistingPivot($this->cleanPivotAttributes($model));
+
+ $model->setRelation('pivot', $pivot);
+ }
+ }
+
+ /**
+ * Get the pivot attributes from a model.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $model
+ * @return array
+ */
+ protected function cleanPivotAttributes(Model $model)
+ {
+ $values = [];
+
+ foreach ($model->getAttributes() as $key => $value) {
+ // To get the pivots attributes we will just take any of the attributes which
+ // begin with "pivot_" and add those to this arrays, as well as unsetting
+ // them from the parent's models since they exist in a different table.
+ if (strpos($key, 'pivot_') === 0) {
+ $values[substr($key, 6)] = $value;
+
+ unset($model->$key);
+ }
+ }
+
+ return $values;
+ }
+
+ /**
+ * Set the base constraints on the relation query.
+ *
+ * @return void
+ */
+ public function addConstraints()
+ {
+ $this->setJoin();
+
+ if (static::$constraints) {
+ $this->setWhere();
+ }
+ }
+
+ /**
+ * Add the constraints for a relationship count query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Database\Eloquent\Builder $parent
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getRelationCountQuery(Builder $query, Builder $parent)
+ {
+ if ($parent->getQuery()->from == $query->getQuery()->from) {
+ return $this->getRelationCountQueryForSelfJoin($query, $parent);
+ }
+
+ $this->setJoin($query);
+
+ return parent::getRelationCountQuery($query, $parent);
+ }
+
+ /**
+ * Add the constraints for a relationship count query on the same table.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Database\Eloquent\Builder $parent
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getRelationCountQueryForSelfJoin(Builder $query, Builder $parent)
+ {
+ $query->select(new Expression('count(*)'));
+
+ $query->from($this->table.' as '.$hash = $this->getRelationCountHash());
+
+ $key = $this->wrap($this->getQualifiedParentKeyName());
+
+ return $query->where($hash.'.'.$this->foreignKey, '=', new Expression($key));
+ }
+
+ /**
+ * Get a relationship join table hash.
+ *
+ * @return string
+ */
+ public function getRelationCountHash()
+ {
+ return 'self_'.md5(microtime(true));
+ }
+
+ /**
+ * Set the select clause for the relation query.
+ *
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
+ */
+ protected function getSelectColumns(array $columns = ['*'])
+ {
+ if ($columns == ['*']) {
+ $columns = [$this->related->getTable().'.*'];
+ }
+
+ return array_merge($columns, $this->getAliasedPivotColumns());
+ }
+
+ /**
+ * Get the pivot columns for the relation.
+ *
+ * @return array
+ */
+ protected function getAliasedPivotColumns()
+ {
+ $defaults = [$this->foreignKey, $this->otherKey];
+
+ // We need to alias all of the pivot columns with the "pivot_" prefix so we
+ // can easily extract them out of the models and put them into the pivot
+ // relationships when they are retrieved and hydrated into the models.
+ $columns = [];
+
+ foreach (array_merge($defaults, $this->pivotColumns) as $column) {
+ $columns[] = $this->table.'.'.$column.' as pivot_'.$column;
+ }
+
+ return array_unique($columns);
+ }
+
+ /**
+ * Determine whether the given column is defined as a pivot column.
+ *
+ * @param string $column
+ * @return bool
+ */
+ protected function hasPivotColumn($column)
+ {
+ return in_array($column, $this->pivotColumns);
+ }
+
+ /**
+ * Set the join clause for the relation query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder|null $query
+ * @return $this
+ */
+ protected function setJoin($query = null)
+ {
+ $query = $query ?: $this->query;
+
+ // We need to join to the intermediate table on the related model's primary
+ // key column with the intermediate table's foreign key for the related
+ // model instance. Then we can set the "where" for the parent models.
+ $baseTable = $this->related->getTable();
+
+ $key = $baseTable.'.'.$this->related->getKeyName();
+
+ $query->join($this->table, $key, '=', $this->getOtherKey());
+
+ return $this;
+ }
+
+ /**
+ * Set the where clause for the relation query.
+ *
+ * @return $this
+ */
+ protected function setWhere()
+ {
+ $foreign = $this->getForeignKey();
+
+ $this->query->where($foreign, '=', $this->parent->getKey());
+
+ return $this;
+ }
+
+ /**
+ * Set the constraints for an eager load of the relation.
+ *
+ * @param array $models
+ * @return void
+ */
+ public function addEagerConstraints(array $models)
+ {
+ $this->query->whereIn($this->getForeignKey(), $this->getKeys($models));
+ }
+
+ /**
+ * Initialize the relation on a set of models.
+ *
+ * @param array $models
+ * @param string $relation
+ * @return array
+ */
+ public function initRelation(array $models, $relation)
+ {
+ foreach ($models as $model) {
+ $model->setRelation($relation, $this->related->newCollection());
+ }
+
+ return $models;
+ }
+
+ /**
+ * Match the eagerly loaded results to their parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ public function match(array $models, Collection $results, $relation)
+ {
+ $dictionary = $this->buildDictionary($results);
+
+ // Once we have an array dictionary of child objects we can easily match the
+ // children back to their parent using the dictionary and the keys on the
+ // the parent models. Then we will return the hydrated models back out.
+ foreach ($models as $model) {
+ if (isset($dictionary[$key = $model->getKey()])) {
+ $collection = $this->related->newCollection($dictionary[$key]);
+
+ $model->setRelation($relation, $collection);
+ }
+ }
+
+ return $models;
+ }
+
+ /**
+ * Build model dictionary keyed by the relation's foreign key.
+ *
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @return array
+ */
+ protected function buildDictionary(Collection $results)
+ {
+ $foreign = $this->foreignKey;
+
+ // First we will build a dictionary of child models keyed by the foreign key
+ // of the relation so that we will easily and quickly match them to their
+ // parents without having a possibly slow inner loops for every models.
+ $dictionary = [];
+
+ foreach ($results as $result) {
+ $dictionary[$result->pivot->$foreign][] = $result;
+ }
+
+ return $dictionary;
+ }
+
+ /**
+ * Touch all of the related models for the relationship.
+ *
+ * E.g.: Touch all roles associated with this user.
+ *
+ * @return void
+ */
+ public function touch()
+ {
+ $key = $this->getRelated()->getKeyName();
+
+ $columns = $this->getRelatedFreshUpdate();
+
+ // If we actually have IDs for the relation, we will run the query to update all
+ // the related model's timestamps, to make sure these all reflect the changes
+ // to the parent models. This will help us keep any caching synced up here.
+ $ids = $this->getRelatedIds();
+
+ if (count($ids) > 0) {
+ $this->getRelated()->newQuery()->whereIn($key, $ids)->update($columns);
+ }
+ }
+
+ /**
+ * Get all of the IDs for the related models.
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ public function getRelatedIds()
+ {
+ $related = $this->getRelated();
+
+ $fullKey = $related->getQualifiedKeyName();
+
+ return $this->getQuery()->select($fullKey)->pluck($related->getKeyName());
+ }
+
+ /**
+ * Save a new model and attach it to the parent model.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $model
+ * @param array $joining
+ * @param bool $touch
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function save(Model $model, array $joining = [], $touch = true)
+ {
+ $model->save(['touch' => false]);
+
+ $this->attach($model->getKey(), $joining, $touch);
+
+ return $model;
+ }
+
+ /**
+ * Save an array of new models and attach them to the parent model.
+ *
+ * @param \Illuminate\Support\Collection|array $models
+ * @param array $joinings
+ * @return array
+ */
+ public function saveMany($models, array $joinings = [])
+ {
+ foreach ($models as $key => $model) {
+ $this->save($model, (array) Arr::get($joinings, $key), false);
+ }
+
+ $this->touchIfTouching();
+
+ return $models;
+ }
+
+ /**
+ * Find a related model by its primary key.
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null
+ */
+ public function find($id, $columns = ['*'])
+ {
+ if (is_array($id)) {
+ return $this->findMany($id, $columns);
+ }
+
+ $this->where($this->getRelated()->getQualifiedKeyName(), '=', $id);
+
+ return $this->first($columns);
+ }
+
+ /**
+ * Find multiple related models by their primary keys.
+ *
+ * @param mixed $ids
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Collection
+ */
+ public function findMany($ids, $columns = ['*'])
+ {
+ if (empty($ids)) {
+ return $this->getRelated()->newCollection();
+ }
+
+ $this->whereIn($this->getRelated()->getQualifiedKeyName(), $ids);
+
+ return $this->get($columns);
+ }
+
+ /**
+ * Find a related model by its primary key or throw an exception.
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection
+ *
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ */
+ public function findOrFail($id, $columns = ['*'])
+ {
+ $result = $this->find($id, $columns);
+
+ if (is_array($id)) {
+ if (count($result) == count(array_unique($id))) {
+ return $result;
+ }
+ } elseif (! is_null($result)) {
+ return $result;
+ }
+
+ throw (new ModelNotFoundException)->setModel(get_class($this->parent));
+ }
+
+ /**
+ * Find a related model by its primary key or return new instance of the related model.
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model
+ */
+ public function findOrNew($id, $columns = ['*'])
+ {
+ if (is_null($instance = $this->find($id, $columns))) {
+ $instance = $this->getRelated()->newInstance();
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Get the first related model record matching the attributes or instantiate it.
+ *
+ * @param array $attributes
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function firstOrNew(array $attributes)
+ {
+ if (is_null($instance = $this->where($attributes)->first())) {
+ $instance = $this->related->newInstance($attributes);
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Get the first related record matching the attributes or create it.
+ *
+ * @param array $attributes
+ * @param array $joining
+ * @param bool $touch
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function firstOrCreate(array $attributes, array $joining = [], $touch = true)
+ {
+ if (is_null($instance = $this->where($attributes)->first())) {
+ $instance = $this->create($attributes, $joining, $touch);
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Create or update a related record matching the attributes, and fill it with values.
+ *
+ * @param array $attributes
+ * @param array $values
+ * @param array $joining
+ * @param bool $touch
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function updateOrCreate(array $attributes, array $values = [], array $joining = [], $touch = true)
+ {
+ if (is_null($instance = $this->where($attributes)->first())) {
+ return $this->create($values, $joining, $touch);
+ }
+
+ $instance->fill($values);
+
+ $instance->save(['touch' => false]);
+
+ return $instance;
+ }
+
+ /**
+ * Create a new instance of the related model.
+ *
+ * @param array $attributes
+ * @param array $joining
+ * @param bool $touch
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function create(array $attributes, array $joining = [], $touch = true)
+ {
+ $instance = $this->related->newInstance($attributes);
+
+ // Once we save the related model, we need to attach it to the base model via
+ // through intermediate table so we'll use the existing "attach" method to
+ // accomplish this which will insert the record and any more attributes.
+ $instance->save(['touch' => false]);
+
+ $this->attach($instance->getKey(), $joining, $touch);
+
+ return $instance;
+ }
+
+ /**
+ * Create an array of new instances of the related models.
+ *
+ * @param array $records
+ * @param array $joinings
+ * @return array
+ */
+ public function createMany(array $records, array $joinings = [])
+ {
+ $instances = [];
+
+ foreach ($records as $key => $record) {
+ $instances[] = $this->create($record, (array) Arr::get($joinings, $key), false);
+ }
+
+ $this->touchIfTouching();
+
+ return $instances;
+ }
+
+ /**
+ * Sync the intermediate tables with a list of IDs or collection of models.
+ *
+ * @param \Illuminate\Database\Eloquent\Collection|array $ids
+ * @param bool $detaching
+ * @return array
+ */
+ public function sync($ids, $detaching = true)
+ {
+ $changes = [
+ 'attached' => [], 'detached' => [], 'updated' => [],
+ ];
+
+ if ($ids instanceof Collection) {
+ $ids = $ids->modelKeys();
+ }
+
+ // First we need to attach any of the associated models that are not currently
+ // in this joining table. We'll spin through the given IDs, checking to see
+ // if they exist in the array of current ones, and if not we will insert.
+ $current = $this->newPivotQuery()->pluck($this->otherKey);
+
+ $records = $this->formatSyncList($ids);
+
+ $detach = array_diff($current, array_keys($records));
+
+ // Next, we will take the differences of the currents and given IDs and detach
+ // all of the entities that exist in the "current" array but are not in the
+ // the array of the IDs given to the method which will complete the sync.
+ if ($detaching && count($detach) > 0) {
+ $this->detach($detach);
+
+ $changes['detached'] = (array) array_map(function ($v) {
+ return is_numeric($v) ? (int) $v : (string) $v;
+ }, $detach);
+ }
+
+ // Now we are finally ready to attach the new records. Note that we'll disable
+ // touching until after the entire operation is complete so we don't fire a
+ // ton of touch operations until we are totally done syncing the records.
+ $changes = array_merge(
+ $changes, $this->attachNew($records, $current, false)
+ );
+
+ if (count($changes['attached']) || count($changes['updated'])) {
+ $this->touchIfTouching();
+ }
+
+ return $changes;
+ }
+
+ /**
+ * Format the sync list so that it is keyed by ID.
+ *
+ * @param array $records
+ * @return array
+ */
+ protected function formatSyncList(array $records)
+ {
+ $results = [];
+
+ foreach ($records as $id => $attributes) {
+ if (! is_array($attributes)) {
+ list($id, $attributes) = [$attributes, []];
+ }
+
+ $results[$id] = $attributes;
+ }
+
+ return $results;
+ }
+
+ /**
+ * Attach all of the IDs that aren't in the current array.
+ *
+ * @param array $records
+ * @param array $current
+ * @param bool $touch
+ * @return array
+ */
+ protected function attachNew(array $records, array $current, $touch = true)
+ {
+ $changes = ['attached' => [], 'updated' => []];
+
+ foreach ($records as $id => $attributes) {
+ // If the ID is not in the list of existing pivot IDs, we will insert a new pivot
+ // record, otherwise, we will just update this existing record on this joining
+ // table, so that the developers will easily update these records pain free.
+ if (! in_array($id, $current)) {
+ $this->attach($id, $attributes, $touch);
+
+ $changes['attached'][] = is_numeric($id) ? (int) $id : (string) $id;
+ }
+
+ // Now we'll try to update an existing pivot record with the attributes that were
+ // given to the method. If the model is actually updated we will add it to the
+ // list of updated pivot records so we return them back out to the consumer.
+ elseif (count($attributes) > 0 &&
+ $this->updateExistingPivot($id, $attributes, $touch)) {
+ $changes['updated'][] = is_numeric($id) ? (int) $id : (string) $id;
+ }
+ }
+
+ return $changes;
+ }
+
+ /**
+ * Update an existing pivot record on the table.
+ *
+ * @param mixed $id
+ * @param array $attributes
+ * @param bool $touch
+ * @return int
+ */
+ public function updateExistingPivot($id, array $attributes, $touch = true)
+ {
+ if (in_array($this->updatedAt(), $this->pivotColumns)) {
+ $attributes = $this->setTimestampsOnAttach($attributes, true);
+ }
+
+ $updated = $this->newPivotStatementForId($id)->update($attributes);
+
+ if ($touch) {
+ $this->touchIfTouching();
+ }
+
+ return $updated;
+ }
+
+ /**
+ * Attach a model to the parent.
+ *
+ * @param mixed $id
+ * @param array $attributes
+ * @param bool $touch
+ * @return void
+ */
+ public function attach($id, array $attributes = [], $touch = true)
+ {
+ if ($id instanceof Model) {
+ $id = $id->getKey();
+ }
+
+ $query = $this->newPivotStatement();
+
+ $query->insert($this->createAttachRecords((array) $id, $attributes));
+
+ if ($touch) {
+ $this->touchIfTouching();
+ }
+ }
+
+ /**
+ * Create an array of records to insert into the pivot table.
+ *
+ * @param array $ids
+ * @param array $attributes
+ * @return array
+ */
+ protected function createAttachRecords($ids, array $attributes)
+ {
+ $records = [];
+
+ $timed = ($this->hasPivotColumn($this->createdAt()) ||
+ $this->hasPivotColumn($this->updatedAt()));
+
+ // To create the attachment records, we will simply spin through the IDs given
+ // and create a new record to insert for each ID. Each ID may actually be a
+ // key in the array, with extra attributes to be placed in other columns.
+ foreach ($ids as $key => $value) {
+ $records[] = $this->attacher($key, $value, $attributes, $timed);
+ }
+
+ return $records;
+ }
+
+ /**
+ * Create a full attachment record payload.
+ *
+ * @param int $key
+ * @param mixed $value
+ * @param array $attributes
+ * @param bool $timed
+ * @return array
+ */
+ protected function attacher($key, $value, $attributes, $timed)
+ {
+ list($id, $extra) = $this->getAttachId($key, $value, $attributes);
+
+ // To create the attachment records, we will simply spin through the IDs given
+ // and create a new record to insert for each ID. Each ID may actually be a
+ // key in the array, with extra attributes to be placed in other columns.
+ $record = $this->createAttachRecord($id, $timed);
+
+ return array_merge($record, $extra);
+ }
+
+ /**
+ * Get the attach record ID and extra attributes.
+ *
+ * @param mixed $key
+ * @param mixed $value
+ * @param array $attributes
+ * @return array
+ */
+ protected function getAttachId($key, $value, array $attributes)
+ {
+ if (is_array($value)) {
+ return [$key, array_merge($value, $attributes)];
+ }
+
+ return [$value, $attributes];
+ }
+
+ /**
+ * Create a new pivot attachment record.
+ *
+ * @param int $id
+ * @param bool $timed
+ * @return array
+ */
+ protected function createAttachRecord($id, $timed)
+ {
+ $record[$this->foreignKey] = $this->parent->getKey();
+
+ $record[$this->otherKey] = $id;
+
+ // If the record needs to have creation and update timestamps, we will make
+ // them by calling the parent model's "freshTimestamp" method which will
+ // provide us with a fresh timestamp in this model's preferred format.
+ if ($timed) {
+ $record = $this->setTimestampsOnAttach($record);
+ }
+
+ return $record;
+ }
+
+ /**
+ * Set the creation and update timestamps on an attach record.
+ *
+ * @param array $record
+ * @param bool $exists
+ * @return array
+ */
+ protected function setTimestampsOnAttach(array $record, $exists = false)
+ {
+ $fresh = $this->parent->freshTimestamp();
+
+ if (! $exists && $this->hasPivotColumn($this->createdAt())) {
+ $record[$this->createdAt()] = $fresh;
+ }
+
+ if ($this->hasPivotColumn($this->updatedAt())) {
+ $record[$this->updatedAt()] = $fresh;
+ }
+
+ return $record;
+ }
+
+ /**
+ * Detach models from the relationship.
+ *
+ * @param int|array $ids
+ * @param bool $touch
+ * @return int
+ */
+ public function detach($ids = [], $touch = true)
+ {
+ if ($ids instanceof Model) {
+ $ids = (array) $ids->getKey();
+ }
+
+ $query = $this->newPivotQuery();
+
+ // If associated IDs were passed to the method we will only delete those
+ // associations, otherwise all of the association ties will be broken.
+ // We'll return the numbers of affected rows when we do the deletes.
+ $ids = (array) $ids;
+
+ if (count($ids) > 0) {
+ $query->whereIn($this->otherKey, (array) $ids);
+ }
+
+ // Once we have all of the conditions set on the statement, we are ready
+ // to run the delete on the pivot table. Then, if the touch parameter
+ // is true, we will go ahead and touch all related models to sync.
+ $results = $query->delete();
+
+ if ($touch) {
+ $this->touchIfTouching();
+ }
+
+ return $results;
+ }
+
+ /**
+ * If we're touching the parent model, touch.
+ *
+ * @return void
+ */
+ public function touchIfTouching()
+ {
+ if ($this->touchingParent()) {
+ $this->getParent()->touch();
+ }
+
+ if ($this->getParent()->touches($this->relationName)) {
+ $this->touch();
+ }
+ }
+
+ /**
+ * Determine if we should touch the parent on sync.
+ *
+ * @return bool
+ */
+ protected function touchingParent()
+ {
+ return $this->getRelated()->touches($this->guessInverseRelation());
+ }
+
+ /**
+ * Attempt to guess the name of the inverse of the relation.
+ *
+ * @return string
+ */
+ protected function guessInverseRelation()
+ {
+ return Str::camel(Str::plural(class_basename($this->getParent())));
+ }
+
+ /**
+ * Create a new query builder for the pivot table.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ protected function newPivotQuery()
+ {
+ $query = $this->newPivotStatement();
+
+ foreach ($this->pivotWheres as $whereArgs) {
+ call_user_func_array([$query, 'where'], $whereArgs);
+ }
+
+ return $query->where($this->foreignKey, $this->parent->getKey());
+ }
+
+ /**
+ * Get a new plain query builder for the pivot table.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public function newPivotStatement()
+ {
+ return $this->query->getQuery()->newQuery()->from($this->table);
+ }
+
+ /**
+ * Get a new pivot statement for a given "other" ID.
+ *
+ * @param mixed $id
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public function newPivotStatementForId($id)
+ {
+ return $this->newPivotQuery()->where($this->otherKey, $id);
+ }
+
+ /**
+ * Create a new pivot model instance.
+ *
+ * @param array $attributes
+ * @param bool $exists
+ * @return \Illuminate\Database\Eloquent\Relations\Pivot
+ */
+ public function newPivot(array $attributes = [], $exists = false)
+ {
+ $pivot = $this->related->newPivot($this->parent, $attributes, $this->table, $exists);
+
+ return $pivot->setPivotKeys($this->foreignKey, $this->otherKey);
+ }
+
+ /**
+ * Create a new existing pivot model instance.
+ *
+ * @param array $attributes
+ * @return \Illuminate\Database\Eloquent\Relations\Pivot
+ */
+ public function newExistingPivot(array $attributes = [])
+ {
+ return $this->newPivot($attributes, true);
+ }
+
+ /**
+ * Set the columns on the pivot table to retrieve.
+ *
+ * @param array|mixed $columns
+ * @return $this
+ */
+ public function withPivot($columns)
+ {
+ $columns = is_array($columns) ? $columns : func_get_args();
+
+ $this->pivotColumns = array_merge($this->pivotColumns, $columns);
+
+ return $this;
+ }
+
+ /**
+ * Specify that the pivot table has creation and update timestamps.
+ *
+ * @param mixed $createdAt
+ * @param mixed $updatedAt
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
+ */
+ public function withTimestamps($createdAt = null, $updatedAt = null)
+ {
+ $this->pivotCreatedAt = $createdAt;
+ $this->pivotUpdatedAt = $updatedAt;
+
+ return $this->withPivot($this->createdAt(), $this->updatedAt());
+ }
+
+ /**
+ * Get the name of the "created at" column.
+ *
+ * @return string
+ */
+ public function createdAt()
+ {
+ return $this->pivotCreatedAt ?: $this->parent->getCreatedAtColumn();
+ }
+
+ /**
+ * Get the name of the "updated at" column.
+ *
+ * @return string
+ */
+ public function updatedAt()
+ {
+ return $this->pivotUpdatedAt ?: $this->parent->getUpdatedAtColumn();
+ }
+
+ /**
+ * Get the related model's updated at column name.
+ *
+ * @return string
+ */
+ public function getRelatedFreshUpdate()
+ {
+ return [$this->related->getUpdatedAtColumn() => $this->related->freshTimestamp()];
+ }
+
+ /**
+ * Get the key for comparing against the parent key in "has" query.
+ *
+ * @return string
+ */
+ public function getHasCompareKey()
+ {
+ return $this->getForeignKey();
+ }
+
+ /**
+ * Get the fully qualified foreign key for the relation.
+ *
+ * @return string
+ */
+ public function getForeignKey()
+ {
+ return $this->table.'.'.$this->foreignKey;
+ }
+
+ /**
+ * Get the fully qualified "other key" for the relation.
+ *
+ * @return string
+ */
+ public function getOtherKey()
+ {
+ return $this->table.'.'.$this->otherKey;
+ }
+
+ /**
+ * Get the intermediate table for the relationship.
+ *
+ * @return string
+ */
+ public function getTable()
+ {
+ return $this->table;
+ }
+
+ /**
+ * Get the relationship name for the relationship.
+ *
+ * @return string
+ */
+ public function getRelationName()
+ {
+ return $this->relationName;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/HasMany.php b/vendor/illuminate/database/Eloquent/Relations/HasMany.php
new file mode 100755
index 00000000..6149e475
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/HasMany.php
@@ -0,0 +1,47 @@
+query->get();
+ }
+
+ /**
+ * Initialize the relation on a set of models.
+ *
+ * @param array $models
+ * @param string $relation
+ * @return array
+ */
+ public function initRelation(array $models, $relation)
+ {
+ foreach ($models as $model) {
+ $model->setRelation($relation, $this->related->newCollection());
+ }
+
+ return $models;
+ }
+
+ /**
+ * Match the eagerly loaded results to their parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ public function match(array $models, Collection $results, $relation)
+ {
+ return $this->matchMany($models, $results, $relation);
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php b/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php
new file mode 100644
index 00000000..8f8decce
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php
@@ -0,0 +1,409 @@
+localKey = $localKey;
+ $this->firstKey = $firstKey;
+ $this->secondKey = $secondKey;
+ $this->farParent = $farParent;
+
+ parent::__construct($query, $parent);
+ }
+
+ /**
+ * Set the base constraints on the relation query.
+ *
+ * @return void
+ */
+ public function addConstraints()
+ {
+ $parentTable = $this->parent->getTable();
+
+ $localValue = $this->farParent[$this->localKey];
+
+ $this->setJoin();
+
+ if (static::$constraints) {
+ $this->query->where($parentTable.'.'.$this->firstKey, '=', $localValue);
+ }
+ }
+
+ /**
+ * Add the constraints for a relationship count query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Database\Eloquent\Builder $parent
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getRelationCountQuery(Builder $query, Builder $parent)
+ {
+ $parentTable = $this->parent->getTable();
+
+ $this->setJoin($query);
+
+ $query->select(new Expression('count(*)'));
+
+ $key = $this->wrap($parentTable.'.'.$this->firstKey);
+
+ return $query->where($this->getHasCompareKey(), '=', new Expression($key));
+ }
+
+ /**
+ * Set the join clause on the query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder|null $query
+ * @return void
+ */
+ protected function setJoin(Builder $query = null)
+ {
+ $query = $query ?: $this->query;
+
+ $foreignKey = $this->related->getTable().'.'.$this->secondKey;
+
+ $query->join($this->parent->getTable(), $this->getQualifiedParentKeyName(), '=', $foreignKey);
+
+ if ($this->parentSoftDeletes()) {
+ $query->whereNull($this->parent->getQualifiedDeletedAtColumn());
+ }
+ }
+
+ /**
+ * Determine whether close parent of the relation uses Soft Deletes.
+ *
+ * @return bool
+ */
+ public function parentSoftDeletes()
+ {
+ return in_array(SoftDeletes::class, class_uses_recursive(get_class($this->parent)));
+ }
+
+ /**
+ * Set the constraints for an eager load of the relation.
+ *
+ * @param array $models
+ * @return void
+ */
+ public function addEagerConstraints(array $models)
+ {
+ $table = $this->parent->getTable();
+
+ $this->query->whereIn($table.'.'.$this->firstKey, $this->getKeys($models));
+ }
+
+ /**
+ * Initialize the relation on a set of models.
+ *
+ * @param array $models
+ * @param string $relation
+ * @return array
+ */
+ public function initRelation(array $models, $relation)
+ {
+ foreach ($models as $model) {
+ $model->setRelation($relation, $this->related->newCollection());
+ }
+
+ return $models;
+ }
+
+ /**
+ * Match the eagerly loaded results to their parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ public function match(array $models, Collection $results, $relation)
+ {
+ $dictionary = $this->buildDictionary($results);
+
+ // Once we have the dictionary we can simply spin through the parent models to
+ // link them up with their children using the keyed dictionary to make the
+ // matching very convenient and easy work. Then we'll just return them.
+ foreach ($models as $model) {
+ $key = $model->getKey();
+
+ if (isset($dictionary[$key])) {
+ $value = $this->related->newCollection($dictionary[$key]);
+
+ $model->setRelation($relation, $value);
+ }
+ }
+
+ return $models;
+ }
+
+ /**
+ * Build model dictionary keyed by the relation's foreign key.
+ *
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @return array
+ */
+ protected function buildDictionary(Collection $results)
+ {
+ $dictionary = [];
+
+ $foreign = $this->firstKey;
+
+ // First we will create a dictionary of models keyed by the foreign key of the
+ // relationship as this will allow us to quickly access all of the related
+ // models without having to do nested looping which will be quite slow.
+ foreach ($results as $result) {
+ $dictionary[$result->{$foreign}][] = $result;
+ }
+
+ return $dictionary;
+ }
+
+ /**
+ * Get the results of the relationship.
+ *
+ * @return mixed
+ */
+ public function getResults()
+ {
+ return $this->get();
+ }
+
+ /**
+ * Execute the query and get the first related model.
+ *
+ * @param array $columns
+ * @return mixed
+ */
+ public function first($columns = ['*'])
+ {
+ $results = $this->take(1)->get($columns);
+
+ return count($results) > 0 ? $results->first() : null;
+ }
+
+ /**
+ * Execute the query and get the first result or throw an exception.
+ *
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model|static
+ *
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ */
+ public function firstOrFail($columns = ['*'])
+ {
+ if (! is_null($model = $this->first($columns))) {
+ return $model;
+ }
+
+ throw new ModelNotFoundException;
+ }
+
+ /**
+ * Find a related model by its primary key.
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null
+ */
+ public function find($id, $columns = ['*'])
+ {
+ if (is_array($id)) {
+ return $this->findMany($id, $columns);
+ }
+
+ $this->where($this->getRelated()->getQualifiedKeyName(), '=', $id);
+
+ return $this->first($columns);
+ }
+
+ /**
+ * Find multiple related models by their primary keys.
+ *
+ * @param mixed $ids
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Collection
+ */
+ public function findMany($ids, $columns = ['*'])
+ {
+ if (empty($ids)) {
+ return $this->getRelated()->newCollection();
+ }
+
+ $this->whereIn($this->getRelated()->getQualifiedKeyName(), $ids);
+
+ return $this->get($columns);
+ }
+
+ /**
+ * Find a related model by its primary key or throw an exception.
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection
+ *
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ */
+ public function findOrFail($id, $columns = ['*'])
+ {
+ $result = $this->find($id, $columns);
+
+ if (is_array($id)) {
+ if (count($result) == count(array_unique($id))) {
+ return $result;
+ }
+ } elseif (! is_null($result)) {
+ return $result;
+ }
+
+ throw (new ModelNotFoundException)->setModel(get_class($this->parent));
+ }
+
+ /**
+ * Execute the query as a "select" statement.
+ *
+ * @param array $columns
+ * @return \Illuminate\Database\Eloquent\Collection
+ */
+ public function get($columns = ['*'])
+ {
+ // First we'll add the proper select columns onto the query so it is run with
+ // the proper columns. Then, we will get the results and hydrate out pivot
+ // models with the result of those columns as a separate model relation.
+ $columns = $this->query->getQuery()->columns ? [] : $columns;
+
+ $select = $this->getSelectColumns($columns);
+
+ $models = $this->query->addSelect($select)->getModels();
+
+ // If we actually found models we will also eager load any relationships that
+ // have been specified as needing to be eager loaded. This will solve the
+ // n + 1 query problem for the developer and also increase performance.
+ if (count($models) > 0) {
+ $models = $this->query->eagerLoadRelations($models);
+ }
+
+ return $this->related->newCollection($models);
+ }
+
+ /**
+ * Set the select clause for the relation query.
+ *
+ * @param array $columns
+ * @return array
+ */
+ protected function getSelectColumns(array $columns = ['*'])
+ {
+ if ($columns == ['*']) {
+ $columns = [$this->related->getTable().'.*'];
+ }
+
+ return array_merge($columns, [$this->parent->getTable().'.'.$this->firstKey]);
+ }
+
+ /**
+ * Get a paginator for the "select" statement.
+ *
+ * @param int $perPage
+ * @param array $columns
+ * @param string $pageName
+ * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+ */
+ public function paginate($perPage = null, $columns = ['*'], $pageName = 'page')
+ {
+ $this->query->addSelect($this->getSelectColumns($columns));
+
+ return $this->query->paginate($perPage, $columns, $pageName);
+ }
+
+ /**
+ * Paginate the given query into a simple paginator.
+ *
+ * @param int $perPage
+ * @param array $columns
+ * @return \Illuminate\Contracts\Pagination\Paginator
+ */
+ public function simplePaginate($perPage = null, $columns = ['*'])
+ {
+ $this->query->addSelect($this->getSelectColumns($columns));
+
+ return $this->query->simplePaginate($perPage, $columns);
+ }
+
+ /**
+ * Get the key for comparing against the parent key in "has" query.
+ *
+ * @return string
+ */
+ public function getHasCompareKey()
+ {
+ return $this->farParent->getQualifiedKeyName();
+ }
+
+ /**
+ * Get the qualified foreign key on the related model.
+ *
+ * @return string
+ */
+ public function getForeignKey()
+ {
+ return $this->related->getTable().'.'.$this->secondKey;
+ }
+
+ /**
+ * Get the qualified foreign key on the "through" model.
+ *
+ * @return string
+ */
+ public function getThroughKey()
+ {
+ return $this->parent->getTable().'.'.$this->firstKey;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/HasOne.php b/vendor/illuminate/database/Eloquent/Relations/HasOne.php
new file mode 100755
index 00000000..52ad2a61
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/HasOne.php
@@ -0,0 +1,47 @@
+query->first();
+ }
+
+ /**
+ * Initialize the relation on a set of models.
+ *
+ * @param array $models
+ * @param string $relation
+ * @return array
+ */
+ public function initRelation(array $models, $relation)
+ {
+ foreach ($models as $model) {
+ $model->setRelation($relation, null);
+ }
+
+ return $models;
+ }
+
+ /**
+ * Match the eagerly loaded results to their parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ public function match(array $models, Collection $results, $relation)
+ {
+ return $this->matchOne($models, $results, $relation);
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php b/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php
new file mode 100755
index 00000000..82830997
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php
@@ -0,0 +1,403 @@
+localKey = $localKey;
+ $this->foreignKey = $foreignKey;
+
+ parent::__construct($query, $parent);
+ }
+
+ /**
+ * Set the base constraints on the relation query.
+ *
+ * @return void
+ */
+ public function addConstraints()
+ {
+ if (static::$constraints) {
+ $this->query->where($this->foreignKey, '=', $this->getParentKey());
+
+ $this->query->whereNotNull($this->foreignKey);
+ }
+ }
+
+ /**
+ * Add the constraints for a relationship count query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Database\Eloquent\Builder $parent
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getRelationCountQuery(Builder $query, Builder $parent)
+ {
+ if ($parent->getQuery()->from == $query->getQuery()->from) {
+ return $this->getRelationCountQueryForSelfRelation($query, $parent);
+ }
+
+ return parent::getRelationCountQuery($query, $parent);
+ }
+
+ /**
+ * Add the constraints for a relationship count query on the same table.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Database\Eloquent\Builder $parent
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getRelationCountQueryForSelfRelation(Builder $query, Builder $parent)
+ {
+ $query->select(new Expression('count(*)'));
+
+ $query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash());
+
+ $key = $this->wrap($this->getQualifiedParentKeyName());
+
+ return $query->where($hash.'.'.$this->getPlainForeignKey(), '=', new Expression($key));
+ }
+
+ /**
+ * Get a relationship join table hash.
+ *
+ * @return string
+ */
+ public function getRelationCountHash()
+ {
+ return 'self_'.md5(microtime(true));
+ }
+
+ /**
+ * Set the constraints for an eager load of the relation.
+ *
+ * @param array $models
+ * @return void
+ */
+ public function addEagerConstraints(array $models)
+ {
+ $this->query->whereIn($this->foreignKey, $this->getKeys($models, $this->localKey));
+ }
+
+ /**
+ * Match the eagerly loaded results to their single parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ public function matchOne(array $models, Collection $results, $relation)
+ {
+ return $this->matchOneOrMany($models, $results, $relation, 'one');
+ }
+
+ /**
+ * Match the eagerly loaded results to their many parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ public function matchMany(array $models, Collection $results, $relation)
+ {
+ return $this->matchOneOrMany($models, $results, $relation, 'many');
+ }
+
+ /**
+ * Match the eagerly loaded results to their many parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @param string $type
+ * @return array
+ */
+ protected function matchOneOrMany(array $models, Collection $results, $relation, $type)
+ {
+ $dictionary = $this->buildDictionary($results);
+
+ // Once we have the dictionary we can simply spin through the parent models to
+ // link them up with their children using the keyed dictionary to make the
+ // matching very convenient and easy work. Then we'll just return them.
+ foreach ($models as $model) {
+ $key = $model->getAttribute($this->localKey);
+
+ if (isset($dictionary[$key])) {
+ $value = $this->getRelationValue($dictionary, $key, $type);
+
+ $model->setRelation($relation, $value);
+ }
+ }
+
+ return $models;
+ }
+
+ /**
+ * Get the value of a relationship by one or many type.
+ *
+ * @param array $dictionary
+ * @param string $key
+ * @param string $type
+ * @return mixed
+ */
+ protected function getRelationValue(array $dictionary, $key, $type)
+ {
+ $value = $dictionary[$key];
+
+ return $type == 'one' ? reset($value) : $this->related->newCollection($value);
+ }
+
+ /**
+ * Build model dictionary keyed by the relation's foreign key.
+ *
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @return array
+ */
+ protected function buildDictionary(Collection $results)
+ {
+ $dictionary = [];
+
+ $foreign = $this->getPlainForeignKey();
+
+ // First we will create a dictionary of models keyed by the foreign key of the
+ // relationship as this will allow us to quickly access all of the related
+ // models without having to do nested looping which will be quite slow.
+ foreach ($results as $result) {
+ $dictionary[$result->{$foreign}][] = $result;
+ }
+
+ return $dictionary;
+ }
+
+ /**
+ * Attach a model instance to the parent model.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $model
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function save(Model $model)
+ {
+ $model->setAttribute($this->getPlainForeignKey(), $this->getParentKey());
+
+ return $model->save() ? $model : false;
+ }
+
+ /**
+ * Attach a collection of models to the parent instance.
+ *
+ * @param \Illuminate\Database\Eloquent\Collection|array $models
+ * @return \Illuminate\Database\Eloquent\Collection|array
+ */
+ public function saveMany($models)
+ {
+ foreach ($models as $model) {
+ $this->save($model);
+ }
+
+ return $models;
+ }
+
+ /**
+ * Find a model by its primary key or return new instance of the related model.
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model
+ */
+ public function findOrNew($id, $columns = ['*'])
+ {
+ if (is_null($instance = $this->find($id, $columns))) {
+ $instance = $this->related->newInstance();
+
+ $instance->setAttribute($this->getPlainForeignKey(), $this->getParentKey());
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Get the first related model record matching the attributes or instantiate it.
+ *
+ * @param array $attributes
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function firstOrNew(array $attributes)
+ {
+ if (is_null($instance = $this->where($attributes)->first())) {
+ $instance = $this->related->newInstance($attributes);
+
+ $instance->setAttribute($this->getPlainForeignKey(), $this->getParentKey());
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Get the first related record matching the attributes or create it.
+ *
+ * @param array $attributes
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function firstOrCreate(array $attributes)
+ {
+ if (is_null($instance = $this->where($attributes)->first())) {
+ $instance = $this->create($attributes);
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Create or update a related record matching the attributes, and fill it with values.
+ *
+ * @param array $attributes
+ * @param array $values
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function updateOrCreate(array $attributes, array $values = [])
+ {
+ $instance = $this->firstOrNew($attributes);
+
+ $instance->fill($values);
+
+ $instance->save();
+
+ return $instance;
+ }
+
+ /**
+ * Create a new instance of the related model.
+ *
+ * @param array $attributes
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function create(array $attributes)
+ {
+ // Here we will set the raw attributes to avoid hitting the "fill" method so
+ // that we do not have to worry about a mass accessor rules blocking sets
+ // on the models. Otherwise, some of these attributes will not get set.
+ $instance = $this->related->newInstance($attributes);
+
+ $instance->setAttribute($this->getPlainForeignKey(), $this->getParentKey());
+
+ $instance->save();
+
+ return $instance;
+ }
+
+ /**
+ * Create an array of new instances of the related model.
+ *
+ * @param array $records
+ * @return array
+ */
+ public function createMany(array $records)
+ {
+ $instances = [];
+
+ foreach ($records as $record) {
+ $instances[] = $this->create($record);
+ }
+
+ return $instances;
+ }
+
+ /**
+ * Perform an update on all the related models.
+ *
+ * @param array $attributes
+ * @return int
+ */
+ public function update(array $attributes)
+ {
+ if ($this->related->usesTimestamps()) {
+ $attributes[$this->relatedUpdatedAt()] = $this->related->freshTimestampString();
+ }
+
+ return $this->query->update($attributes);
+ }
+
+ /**
+ * Get the key for comparing against the parent key in "has" query.
+ *
+ * @return string
+ */
+ public function getHasCompareKey()
+ {
+ return $this->getForeignKey();
+ }
+
+ /**
+ * Get the foreign key for the relationship.
+ *
+ * @return string
+ */
+ public function getForeignKey()
+ {
+ return $this->foreignKey;
+ }
+
+ /**
+ * Get the plain foreign key.
+ *
+ * @return string
+ */
+ public function getPlainForeignKey()
+ {
+ $segments = explode('.', $this->getForeignKey());
+
+ return $segments[count($segments) - 1];
+ }
+
+ /**
+ * Get the key value of the parent's local key.
+ *
+ * @return mixed
+ */
+ public function getParentKey()
+ {
+ return $this->parent->getAttribute($this->localKey);
+ }
+
+ /**
+ * Get the fully qualified parent key name.
+ *
+ * @return string
+ */
+ public function getQualifiedParentKeyName()
+ {
+ return $this->parent->getTable().'.'.$this->localKey;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphMany.php
new file mode 100755
index 00000000..e2a5c5a3
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphMany.php
@@ -0,0 +1,47 @@
+query->get();
+ }
+
+ /**
+ * Initialize the relation on a set of models.
+ *
+ * @param array $models
+ * @param string $relation
+ * @return array
+ */
+ public function initRelation(array $models, $relation)
+ {
+ foreach ($models as $model) {
+ $model->setRelation($relation, $this->related->newCollection());
+ }
+
+ return $models;
+ }
+
+ /**
+ * Match the eagerly loaded results to their parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ public function match(array $models, Collection $results, $relation)
+ {
+ return $this->matchMany($models, $results, $relation);
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphOne.php b/vendor/illuminate/database/Eloquent/Relations/MorphOne.php
new file mode 100755
index 00000000..339a68c3
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphOne.php
@@ -0,0 +1,47 @@
+query->first();
+ }
+
+ /**
+ * Initialize the relation on a set of models.
+ *
+ * @param array $models
+ * @param string $relation
+ * @return array
+ */
+ public function initRelation(array $models, $relation)
+ {
+ foreach ($models as $model) {
+ $model->setRelation($relation, null);
+ }
+
+ return $models;
+ }
+
+ /**
+ * Match the eagerly loaded results to their parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ public function match(array $models, Collection $results, $relation)
+ {
+ return $this->matchOne($models, $results, $relation);
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php
new file mode 100755
index 00000000..658452cb
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php
@@ -0,0 +1,233 @@
+morphType = $type;
+
+ $this->morphClass = $parent->getMorphClass();
+
+ parent::__construct($query, $parent, $id, $localKey);
+ }
+
+ /**
+ * Set the base constraints on the relation query.
+ *
+ * @return void
+ */
+ public function addConstraints()
+ {
+ if (static::$constraints) {
+ parent::addConstraints();
+
+ $this->query->where($this->morphType, $this->morphClass);
+ }
+ }
+
+ /**
+ * Get the relationship count query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Database\Eloquent\Builder $parent
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getRelationCountQuery(Builder $query, Builder $parent)
+ {
+ $query = parent::getRelationCountQuery($query, $parent);
+
+ return $query->where($this->morphType, $this->morphClass);
+ }
+
+ /**
+ * Set the constraints for an eager load of the relation.
+ *
+ * @param array $models
+ * @return void
+ */
+ public function addEagerConstraints(array $models)
+ {
+ parent::addEagerConstraints($models);
+
+ $this->query->where($this->morphType, $this->morphClass);
+ }
+
+ /**
+ * Attach a model instance to the parent model.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $model
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function save(Model $model)
+ {
+ $model->setAttribute($this->getPlainMorphType(), $this->morphClass);
+
+ return parent::save($model);
+ }
+
+ /**
+ * Find a related model by its primary key or return new instance of the related model.
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model
+ */
+ public function findOrNew($id, $columns = ['*'])
+ {
+ if (is_null($instance = $this->find($id, $columns))) {
+ $instance = $this->related->newInstance();
+
+ // When saving a polymorphic relationship, we need to set not only the foreign
+ // key, but also the foreign key type, which is typically the class name of
+ // the parent model. This makes the polymorphic item unique in the table.
+ $this->setForeignAttributesForCreate($instance);
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Get the first related model record matching the attributes or instantiate it.
+ *
+ * @param array $attributes
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function firstOrNew(array $attributes)
+ {
+ if (is_null($instance = $this->where($attributes)->first())) {
+ $instance = $this->related->newInstance($attributes);
+
+ // When saving a polymorphic relationship, we need to set not only the foreign
+ // key, but also the foreign key type, which is typically the class name of
+ // the parent model. This makes the polymorphic item unique in the table.
+ $this->setForeignAttributesForCreate($instance);
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Get the first related record matching the attributes or create it.
+ *
+ * @param array $attributes
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function firstOrCreate(array $attributes)
+ {
+ if (is_null($instance = $this->where($attributes)->first())) {
+ $instance = $this->create($attributes);
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Create or update a related record matching the attributes, and fill it with values.
+ *
+ * @param array $attributes
+ * @param array $values
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function updateOrCreate(array $attributes, array $values = [])
+ {
+ $instance = $this->firstOrNew($attributes);
+
+ $instance->fill($values);
+
+ $instance->save();
+
+ return $instance;
+ }
+
+ /**
+ * Create a new instance of the related model.
+ *
+ * @param array $attributes
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function create(array $attributes)
+ {
+ $instance = $this->related->newInstance($attributes);
+
+ // When saving a polymorphic relationship, we need to set not only the foreign
+ // key, but also the foreign key type, which is typically the class name of
+ // the parent model. This makes the polymorphic item unique in the table.
+ $this->setForeignAttributesForCreate($instance);
+
+ $instance->save();
+
+ return $instance;
+ }
+
+ /**
+ * Set the foreign ID and type for creating a related model.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $model
+ * @return void
+ */
+ protected function setForeignAttributesForCreate(Model $model)
+ {
+ $model->{$this->getPlainForeignKey()} = $this->getParentKey();
+
+ $model->{last(explode('.', $this->morphType))} = $this->morphClass;
+ }
+
+ /**
+ * Get the foreign key "type" name.
+ *
+ * @return string
+ */
+ public function getMorphType()
+ {
+ return $this->morphType;
+ }
+
+ /**
+ * Get the plain morph type name without the table.
+ *
+ * @return string
+ */
+ public function getPlainMorphType()
+ {
+ return last(explode('.', $this->morphType));
+ }
+
+ /**
+ * Get the class name of the parent model.
+ *
+ * @return string
+ */
+ public function getMorphClass()
+ {
+ return $this->morphClass;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php b/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php
new file mode 100644
index 00000000..b7a2f341
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php
@@ -0,0 +1,79 @@
+where($this->morphType, $this->morphClass);
+
+ return parent::setKeysForSaveQuery($query);
+ }
+
+ /**
+ * Delete the pivot model record from the database.
+ *
+ * @return int
+ */
+ public function delete()
+ {
+ $query = $this->getDeleteQuery();
+
+ $query->where($this->morphType, $this->morphClass);
+
+ return $query->delete();
+ }
+
+ /**
+ * Set the morph type for the pivot.
+ *
+ * @param string $morphType
+ * @return $this
+ */
+ public function setMorphType($morphType)
+ {
+ $this->morphType = $morphType;
+
+ return $this;
+ }
+
+ /**
+ * Set the morph class for the pivot.
+ *
+ * @param string $morphClass
+ * @return \Illuminate\Database\Eloquent\Relations\MorphPivot
+ */
+ public function setMorphClass($morphClass)
+ {
+ $this->morphClass = $morphClass;
+
+ return $this;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphTo.php b/vendor/illuminate/database/Eloquent/Relations/MorphTo.php
new file mode 100644
index 00000000..06a488d6
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphTo.php
@@ -0,0 +1,269 @@
+morphType = $type;
+
+ parent::__construct($query, $parent, $foreignKey, $otherKey, $relation);
+ }
+
+ /**
+ * Get the results of the relationship.
+ *
+ * @return mixed
+ */
+ public function getResults()
+ {
+ if (! $this->otherKey) {
+ return;
+ }
+
+ return $this->query->first();
+ }
+
+ /**
+ * Set the constraints for an eager load of the relation.
+ *
+ * @param array $models
+ * @return void
+ */
+ public function addEagerConstraints(array $models)
+ {
+ $this->buildDictionary($this->models = Collection::make($models));
+ }
+
+ /**
+ * Build a dictionary with the models.
+ *
+ * @param \Illuminate\Database\Eloquent\Collection $models
+ * @return void
+ */
+ protected function buildDictionary(Collection $models)
+ {
+ foreach ($models as $model) {
+ if ($model->{$this->morphType}) {
+ $this->dictionary[$model->{$this->morphType}][$model->{$this->foreignKey}][] = $model;
+ }
+ }
+ }
+
+ /**
+ * Match the eagerly loaded results to their parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ public function match(array $models, Collection $results, $relation)
+ {
+ return $models;
+ }
+
+ /**
+ * Associate the model instance to the given parent.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $model
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function associate($model)
+ {
+ $this->parent->setAttribute($this->foreignKey, $model->getKey());
+
+ $this->parent->setAttribute($this->morphType, $model->getMorphClass());
+
+ return $this->parent->setRelation($this->relation, $model);
+ }
+
+ /**
+ * Dissociate previously associated model from the given parent.
+ *
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function dissociate()
+ {
+ $this->parent->setAttribute($this->foreignKey, null);
+
+ $this->parent->setAttribute($this->morphType, null);
+
+ return $this->parent->setRelation($this->relation, null);
+ }
+
+ /**
+ * Get the results of the relationship.
+ *
+ * Called via eager load method of Eloquent query builder.
+ *
+ * @return mixed
+ */
+ public function getEager()
+ {
+ foreach (array_keys($this->dictionary) as $type) {
+ $this->matchToMorphParents($type, $this->getResultsByType($type));
+ }
+
+ return $this->models;
+ }
+
+ /**
+ * Match the results for a given type to their parents.
+ *
+ * @param string $type
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @return void
+ */
+ protected function matchToMorphParents($type, Collection $results)
+ {
+ foreach ($results as $result) {
+ if (isset($this->dictionary[$type][$result->getKey()])) {
+ foreach ($this->dictionary[$type][$result->getKey()] as $model) {
+ $model->setRelation($this->relation, $result);
+ }
+ }
+ }
+ }
+
+ /**
+ * Get all of the relation results for a type.
+ *
+ * @param string $type
+ * @return \Illuminate\Database\Eloquent\Collection
+ */
+ protected function getResultsByType($type)
+ {
+ $instance = $this->createModelByType($type);
+
+ $key = $instance->getTable().'.'.$instance->getKeyName();
+
+ $query = $instance->newQuery();
+
+ $query = $this->useWithTrashed($query);
+
+ return $query->whereIn($key, $this->gatherKeysByType($type)->all())->get();
+ }
+
+ /**
+ * Gather all of the foreign keys for a given type.
+ *
+ * @param string $type
+ * @return array
+ */
+ protected function gatherKeysByType($type)
+ {
+ $foreign = $this->foreignKey;
+
+ return collect($this->dictionary[$type])->map(function ($models) use ($foreign) {
+ return head($models)->{$foreign};
+
+ })->values()->unique();
+ }
+
+ /**
+ * Create a new model instance by type.
+ *
+ * @param string $type
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function createModelByType($type)
+ {
+ $class = $this->parent->getActualClassNameForMorph($type);
+
+ return new $class;
+ }
+
+ /**
+ * Get the foreign key "type" name.
+ *
+ * @return string
+ */
+ public function getMorphType()
+ {
+ return $this->morphType;
+ }
+
+ /**
+ * Get the dictionary used by the relationship.
+ *
+ * @return array
+ */
+ public function getDictionary()
+ {
+ return $this->dictionary;
+ }
+
+ /**
+ * Fetch soft-deleted model instances with query.
+ *
+ * @return $this
+ */
+ public function withTrashed()
+ {
+ $this->withTrashed = true;
+
+ $this->query = $this->useWithTrashed($this->query);
+
+ return $this;
+ }
+
+ /**
+ * Return trashed models with query if told so.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ protected function useWithTrashed(Builder $query)
+ {
+ if ($this->withTrashed && $query->getMacro('withTrashed') !== null) {
+ return $query->withTrashed();
+ }
+
+ return $query;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php
new file mode 100644
index 00000000..373005da
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php
@@ -0,0 +1,160 @@
+inverse = $inverse;
+ $this->morphType = $name.'_type';
+ $this->morphClass = $inverse ? $query->getModel()->getMorphClass() : $parent->getMorphClass();
+
+ parent::__construct($query, $parent, $table, $foreignKey, $otherKey, $relationName);
+ }
+
+ /**
+ * Set the where clause for the relation query.
+ *
+ * @return $this
+ */
+ protected function setWhere()
+ {
+ parent::setWhere();
+
+ $this->query->where($this->table.'.'.$this->morphType, $this->morphClass);
+
+ return $this;
+ }
+
+ /**
+ * Add the constraints for a relationship count query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Database\Eloquent\Builder $parent
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getRelationCountQuery(Builder $query, Builder $parent)
+ {
+ $query = parent::getRelationCountQuery($query, $parent);
+
+ return $query->where($this->table.'.'.$this->morphType, $this->morphClass);
+ }
+
+ /**
+ * Set the constraints for an eager load of the relation.
+ *
+ * @param array $models
+ * @return void
+ */
+ public function addEagerConstraints(array $models)
+ {
+ parent::addEagerConstraints($models);
+
+ $this->query->where($this->table.'.'.$this->morphType, $this->morphClass);
+ }
+
+ /**
+ * Create a new pivot attachment record.
+ *
+ * @param int $id
+ * @param bool $timed
+ * @return array
+ */
+ protected function createAttachRecord($id, $timed)
+ {
+ $record = parent::createAttachRecord($id, $timed);
+
+ return Arr::add($record, $this->morphType, $this->morphClass);
+ }
+
+ /**
+ * Create a new query builder for the pivot table.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ protected function newPivotQuery()
+ {
+ $query = parent::newPivotQuery();
+
+ return $query->where($this->morphType, $this->morphClass);
+ }
+
+ /**
+ * Create a new pivot model instance.
+ *
+ * @param array $attributes
+ * @param bool $exists
+ * @return \Illuminate\Database\Eloquent\Relations\Pivot
+ */
+ public function newPivot(array $attributes = [], $exists = false)
+ {
+ $pivot = new MorphPivot($this->parent, $attributes, $this->table, $exists);
+
+ $pivot->setPivotKeys($this->foreignKey, $this->otherKey)
+ ->setMorphType($this->morphType)
+ ->setMorphClass($this->morphClass);
+
+ return $pivot;
+ }
+
+ /**
+ * Get the foreign key "type" name.
+ *
+ * @return string
+ */
+ public function getMorphType()
+ {
+ return $this->morphType;
+ }
+
+ /**
+ * Get the class name of the parent model.
+ *
+ * @return string
+ */
+ public function getMorphClass()
+ {
+ return $this->morphClass;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/Pivot.php b/vendor/illuminate/database/Eloquent/Relations/Pivot.php
new file mode 100755
index 00000000..4d802792
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/Pivot.php
@@ -0,0 +1,174 @@
+setTable($table);
+
+ $this->setConnection($parent->getConnectionName());
+
+ $this->forceFill($attributes);
+
+ $this->syncOriginal();
+
+ // We store off the parent instance so we will access the timestamp column names
+ // for the model, since the pivot model timestamps aren't easily configurable
+ // from the developer's point of view. We can use the parents to get these.
+ $this->parent = $parent;
+
+ $this->exists = $exists;
+
+ $this->timestamps = $this->hasTimestampAttributes();
+ }
+
+ /**
+ * Set the keys for a save update query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ protected function setKeysForSaveQuery(Builder $query)
+ {
+ $query->where($this->foreignKey, $this->getAttribute($this->foreignKey));
+
+ return $query->where($this->otherKey, $this->getAttribute($this->otherKey));
+ }
+
+ /**
+ * Delete the pivot model record from the database.
+ *
+ * @return int
+ */
+ public function delete()
+ {
+ return $this->getDeleteQuery()->delete();
+ }
+
+ /**
+ * Get the query builder for a delete operation on the pivot.
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ protected function getDeleteQuery()
+ {
+ $foreign = $this->getAttribute($this->foreignKey);
+
+ $query = $this->newQuery()->where($this->foreignKey, $foreign);
+
+ return $query->where($this->otherKey, $this->getAttribute($this->otherKey));
+ }
+
+ /**
+ * Get the foreign key column name.
+ *
+ * @return string
+ */
+ public function getForeignKey()
+ {
+ return $this->foreignKey;
+ }
+
+ /**
+ * Get the "other key" column name.
+ *
+ * @return string
+ */
+ public function getOtherKey()
+ {
+ return $this->otherKey;
+ }
+
+ /**
+ * Set the key names for the pivot model instance.
+ *
+ * @param string $foreignKey
+ * @param string $otherKey
+ * @return $this
+ */
+ public function setPivotKeys($foreignKey, $otherKey)
+ {
+ $this->foreignKey = $foreignKey;
+
+ $this->otherKey = $otherKey;
+
+ return $this;
+ }
+
+ /**
+ * Determine if the pivot model has timestamp attributes.
+ *
+ * @return bool
+ */
+ public function hasTimestampAttributes()
+ {
+ return array_key_exists($this->getCreatedAtColumn(), $this->attributes);
+ }
+
+ /**
+ * Get the name of the "created at" column.
+ *
+ * @return string
+ */
+ public function getCreatedAtColumn()
+ {
+ return $this->parent->getCreatedAtColumn();
+ }
+
+ /**
+ * Get the name of the "updated at" column.
+ *
+ * @return string
+ */
+ public function getUpdatedAtColumn()
+ {
+ return $this->parent->getUpdatedAtColumn();
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/Relation.php b/vendor/illuminate/database/Eloquent/Relations/Relation.php
new file mode 100755
index 00000000..4d942a9a
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/Relation.php
@@ -0,0 +1,339 @@
+query = $query;
+ $this->parent = $parent;
+ $this->related = $query->getModel();
+
+ $this->addConstraints();
+ }
+
+ /**
+ * Set the base constraints on the relation query.
+ *
+ * @return void
+ */
+ abstract public function addConstraints();
+
+ /**
+ * Set the constraints for an eager load of the relation.
+ *
+ * @param array $models
+ * @return void
+ */
+ abstract public function addEagerConstraints(array $models);
+
+ /**
+ * Initialize the relation on a set of models.
+ *
+ * @param array $models
+ * @param string $relation
+ * @return array
+ */
+ abstract public function initRelation(array $models, $relation);
+
+ /**
+ * Match the eagerly loaded results to their parents.
+ *
+ * @param array $models
+ * @param \Illuminate\Database\Eloquent\Collection $results
+ * @param string $relation
+ * @return array
+ */
+ abstract public function match(array $models, Collection $results, $relation);
+
+ /**
+ * Get the results of the relationship.
+ *
+ * @return mixed
+ */
+ abstract public function getResults();
+
+ /**
+ * Get the relationship for eager loading.
+ *
+ * @return \Illuminate\Database\Eloquent\Collection
+ */
+ public function getEager()
+ {
+ return $this->get();
+ }
+
+ /**
+ * Touch all of the related models for the relationship.
+ *
+ * @return void
+ */
+ public function touch()
+ {
+ $column = $this->getRelated()->getUpdatedAtColumn();
+
+ $this->rawUpdate([$column => $this->getRelated()->freshTimestampString()]);
+ }
+
+ /**
+ * Run a raw update against the base query.
+ *
+ * @param array $attributes
+ * @return int
+ */
+ public function rawUpdate(array $attributes = [])
+ {
+ return $this->query->update($attributes);
+ }
+
+ /**
+ * Add the constraints for a relationship count query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Database\Eloquent\Builder $parent
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getRelationCountQuery(Builder $query, Builder $parent)
+ {
+ $query->select(new Expression('count(*)'));
+
+ $key = $this->wrap($this->getQualifiedParentKeyName());
+
+ return $query->where($this->getHasCompareKey(), '=', new Expression($key));
+ }
+
+ /**
+ * Run a callback with constraints disabled on the relation.
+ *
+ * @param \Closure $callback
+ * @return mixed
+ */
+ public static function noConstraints(Closure $callback)
+ {
+ $previous = static::$constraints;
+
+ static::$constraints = false;
+
+ // When resetting the relation where clause, we want to shift the first element
+ // off of the bindings, leaving only the constraints that the developers put
+ // as "extra" on the relationships, and not original relation constraints.
+ try {
+ $results = call_user_func($callback);
+ } finally {
+ static::$constraints = $previous;
+ }
+
+ return $results;
+ }
+
+ /**
+ * Get all of the primary keys for an array of models.
+ *
+ * @param array $models
+ * @param string $key
+ * @return array
+ */
+ protected function getKeys(array $models, $key = null)
+ {
+ return array_unique(array_values(array_map(function ($value) use ($key) {
+ return $key ? $value->getAttribute($key) : $value->getKey();
+
+ }, $models)));
+ }
+
+ /**
+ * Get the underlying query for the relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function getQuery()
+ {
+ return $this->query;
+ }
+
+ /**
+ * Get the base query builder driving the Eloquent builder.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public function getBaseQuery()
+ {
+ return $this->query->getQuery();
+ }
+
+ /**
+ * Get the parent model of the relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function getParent()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Get the fully qualified parent key name.
+ *
+ * @return string
+ */
+ public function getQualifiedParentKeyName()
+ {
+ return $this->parent->getQualifiedKeyName();
+ }
+
+ /**
+ * Get the related model of the relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Model
+ */
+ public function getRelated()
+ {
+ return $this->related;
+ }
+
+ /**
+ * Get the name of the "created at" column.
+ *
+ * @return string
+ */
+ public function createdAt()
+ {
+ return $this->parent->getCreatedAtColumn();
+ }
+
+ /**
+ * Get the name of the "updated at" column.
+ *
+ * @return string
+ */
+ public function updatedAt()
+ {
+ return $this->parent->getUpdatedAtColumn();
+ }
+
+ /**
+ * Get the name of the related model's "updated at" column.
+ *
+ * @return string
+ */
+ public function relatedUpdatedAt()
+ {
+ return $this->related->getUpdatedAtColumn();
+ }
+
+ /**
+ * Wrap the given value with the parent query's grammar.
+ *
+ * @param string $value
+ * @return string
+ */
+ public function wrap($value)
+ {
+ return $this->parent->newQueryWithoutScopes()->getQuery()->getGrammar()->wrap($value);
+ }
+
+ /**
+ * Set or get the morph map for polymorphic relations.
+ *
+ * @param array|null $map
+ * @param bool $merge
+ * @return array
+ */
+ public static function morphMap(array $map = null, $merge = true)
+ {
+ $map = static::buildMorphMapFromModels($map);
+
+ if (is_array($map)) {
+ static::$morphMap = $merge ? array_merge(static::$morphMap, $map) : $map;
+ }
+
+ return static::$morphMap;
+ }
+
+ /**
+ * Builds a table-keyed array from model class names.
+ *
+ * @param string[]|null $models
+ * @return array|null
+ */
+ protected static function buildMorphMapFromModels(array $models = null)
+ {
+ if (is_null($models) || Arr::isAssoc($models)) {
+ return $models;
+ }
+
+ $tables = array_map(function ($model) {
+ return (new $model)->getTable();
+ }, $models);
+
+ return array_combine($tables, $models);
+ }
+
+ /**
+ * Handle dynamic method calls to the relationship.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ $result = call_user_func_array([$this->query, $method], $parameters);
+
+ if ($result === $this->query) {
+ return $this;
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/Scope.php b/vendor/illuminate/database/Eloquent/Scope.php
new file mode 100644
index 00000000..63cba6a5
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Scope.php
@@ -0,0 +1,15 @@
+forceDeleting = true;
+
+ $this->delete();
+
+ $this->forceDeleting = false;
+ }
+
+ /**
+ * Perform the actual delete query on this model instance.
+ *
+ * @return mixed
+ */
+ protected function performDeleteOnModel()
+ {
+ if ($this->forceDeleting) {
+ return $this->newQueryWithoutScopes()->where($this->getKeyName(), $this->getKey())->forceDelete();
+ }
+
+ return $this->runSoftDelete();
+ }
+
+ /**
+ * Perform the actual delete query on this model instance.
+ *
+ * @return void
+ */
+ protected function runSoftDelete()
+ {
+ $query = $this->newQueryWithoutScopes()->where($this->getKeyName(), $this->getKey());
+
+ $this->{$this->getDeletedAtColumn()} = $time = $this->freshTimestamp();
+
+ $query->update([$this->getDeletedAtColumn() => $this->fromDateTime($time)]);
+ }
+
+ /**
+ * Restore a soft-deleted model instance.
+ *
+ * @return bool|null
+ */
+ public function restore()
+ {
+ // If the restoring event does not return false, we will proceed with this
+ // restore operation. Otherwise, we bail out so the developer will stop
+ // the restore totally. We will clear the deleted timestamp and save.
+ if ($this->fireModelEvent('restoring') === false) {
+ return false;
+ }
+
+ $this->{$this->getDeletedAtColumn()} = null;
+
+ // Once we have saved the model, we will fire the "restored" event so this
+ // developer will do anything they need to after a restore operation is
+ // totally finished. Then we will return the result of the save call.
+ $this->exists = true;
+
+ $result = $this->save();
+
+ $this->fireModelEvent('restored', false);
+
+ return $result;
+ }
+
+ /**
+ * Determine if the model instance has been soft-deleted.
+ *
+ * @return bool
+ */
+ public function trashed()
+ {
+ return ! is_null($this->{$this->getDeletedAtColumn()});
+ }
+
+ /**
+ * Get a new query builder that includes soft deletes.
+ *
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public static function withTrashed()
+ {
+ return (new static)->newQueryWithoutScope(new SoftDeletingScope);
+ }
+
+ /**
+ * Get a new query builder that only includes soft deletes.
+ *
+ * @return \Illuminate\Database\Eloquent\Builder|static
+ */
+ public static function onlyTrashed()
+ {
+ $instance = new static;
+
+ $column = $instance->getQualifiedDeletedAtColumn();
+
+ return $instance->newQueryWithoutScope(new SoftDeletingScope)->whereNotNull($column);
+ }
+
+ /**
+ * Register a restoring model event with the dispatcher.
+ *
+ * @param \Closure|string $callback
+ * @return void
+ */
+ public static function restoring($callback)
+ {
+ static::registerModelEvent('restoring', $callback);
+ }
+
+ /**
+ * Register a restored model event with the dispatcher.
+ *
+ * @param \Closure|string $callback
+ * @return void
+ */
+ public static function restored($callback)
+ {
+ static::registerModelEvent('restored', $callback);
+ }
+
+ /**
+ * Get the name of the "deleted at" column.
+ *
+ * @return string
+ */
+ public function getDeletedAtColumn()
+ {
+ return defined('static::DELETED_AT') ? static::DELETED_AT : 'deleted_at';
+ }
+
+ /**
+ * Get the fully qualified "deleted at" column.
+ *
+ * @return string
+ */
+ public function getQualifiedDeletedAtColumn()
+ {
+ return $this->getTable().'.'.$this->getDeletedAtColumn();
+ }
+}
diff --git a/vendor/illuminate/database/Eloquent/SoftDeletingScope.php b/vendor/illuminate/database/Eloquent/SoftDeletingScope.php
new file mode 100644
index 00000000..69bd63f1
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/SoftDeletingScope.php
@@ -0,0 +1,123 @@
+whereNull($model->getQualifiedDeletedAtColumn());
+
+ $this->extend($builder);
+ }
+
+ /**
+ * Extend the query builder with the needed functions.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $builder
+ * @return void
+ */
+ public function extend(Builder $builder)
+ {
+ foreach ($this->extensions as $extension) {
+ $this->{"add{$extension}"}($builder);
+ }
+
+ $builder->onDelete(function (Builder $builder) {
+ $column = $this->getDeletedAtColumn($builder);
+
+ return $builder->update([
+ $column => $builder->getModel()->freshTimestampString(),
+ ]);
+ });
+ }
+
+ /**
+ * Get the "deleted at" column for the builder.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $builder
+ * @return string
+ */
+ protected function getDeletedAtColumn(Builder $builder)
+ {
+ if (count($builder->getQuery()->joins) > 0) {
+ return $builder->getModel()->getQualifiedDeletedAtColumn();
+ } else {
+ return $builder->getModel()->getDeletedAtColumn();
+ }
+ }
+
+ /**
+ * Add the force delete extension to the builder.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $builder
+ * @return void
+ */
+ protected function addForceDelete(Builder $builder)
+ {
+ $builder->macro('forceDelete', function (Builder $builder) {
+ return $builder->getQuery()->delete();
+ });
+ }
+
+ /**
+ * Add the restore extension to the builder.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $builder
+ * @return void
+ */
+ protected function addRestore(Builder $builder)
+ {
+ $builder->macro('restore', function (Builder $builder) {
+ $builder->withTrashed();
+
+ return $builder->update([$builder->getModel()->getDeletedAtColumn() => null]);
+ });
+ }
+
+ /**
+ * Add the with-trashed extension to the builder.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $builder
+ * @return void
+ */
+ protected function addWithTrashed(Builder $builder)
+ {
+ $builder->macro('withTrashed', function (Builder $builder) {
+ return $builder->withoutGlobalScope($this);
+ });
+ }
+
+ /**
+ * Add the only-trashed extension to the builder.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $builder
+ * @return void
+ */
+ protected function addOnlyTrashed(Builder $builder)
+ {
+ $builder->macro('onlyTrashed', function (Builder $builder) {
+ $model = $builder->getModel();
+
+ $builder->withoutGlobalScope($this)->whereNotNull(
+ $model->getQualifiedDeletedAtColumn()
+ );
+
+ return $builder;
+ });
+ }
+}
diff --git a/vendor/illuminate/database/Events/ConnectionEvent.php b/vendor/illuminate/database/Events/ConnectionEvent.php
new file mode 100644
index 00000000..818c7850
--- /dev/null
+++ b/vendor/illuminate/database/Events/ConnectionEvent.php
@@ -0,0 +1,32 @@
+connection = $connection;
+ $this->connectionName = $connection->getName();
+ }
+}
diff --git a/vendor/illuminate/database/Events/QueryExecuted.php b/vendor/illuminate/database/Events/QueryExecuted.php
new file mode 100644
index 00000000..3fe8d148
--- /dev/null
+++ b/vendor/illuminate/database/Events/QueryExecuted.php
@@ -0,0 +1,58 @@
+sql = $sql;
+ $this->time = $time;
+ $this->bindings = $bindings;
+ $this->connection = $connection;
+ $this->connectionName = $connection->getName();
+ }
+}
diff --git a/vendor/illuminate/database/Events/TransactionBeginning.php b/vendor/illuminate/database/Events/TransactionBeginning.php
new file mode 100644
index 00000000..3287b5c8
--- /dev/null
+++ b/vendor/illuminate/database/Events/TransactionBeginning.php
@@ -0,0 +1,8 @@
+isExpression($table)) {
+ return $this->getValue($table);
+ }
+
+ return $this->wrap($this->tablePrefix.$table, true);
+ }
+
+ /**
+ * Wrap a value in keyword identifiers.
+ *
+ * @param string|\Illuminate\Database\Query\Expression $value
+ * @param bool $prefixAlias
+ * @return string
+ */
+ public function wrap($value, $prefixAlias = false)
+ {
+ if ($this->isExpression($value)) {
+ return $this->getValue($value);
+ }
+
+ // If the value being wrapped has a column alias we will need to separate out
+ // the pieces so we can wrap each of the segments of the expression on it
+ // own, and then joins them both back together with the "as" connector.
+ if (strpos(strtolower($value), ' as ') !== false) {
+ $segments = explode(' ', $value);
+
+ if ($prefixAlias) {
+ $segments[2] = $this->tablePrefix.$segments[2];
+ }
+
+ return $this->wrap($segments[0]).' as '.$this->wrapValue($segments[2]);
+ }
+
+ $wrapped = [];
+
+ $segments = explode('.', $value);
+
+ // If the value is not an aliased table expression, we'll just wrap it like
+ // normal, so if there is more than one segment, we will wrap the first
+ // segments as if it was a table and the rest as just regular values.
+ foreach ($segments as $key => $segment) {
+ if ($key == 0 && count($segments) > 1) {
+ $wrapped[] = $this->wrapTable($segment);
+ } else {
+ $wrapped[] = $this->wrapValue($segment);
+ }
+ }
+
+ return implode('.', $wrapped);
+ }
+
+ /**
+ * Wrap a single string in keyword identifiers.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function wrapValue($value)
+ {
+ if ($value === '*') {
+ return $value;
+ }
+
+ return '"'.str_replace('"', '""', $value).'"';
+ }
+
+ /**
+ * Convert an array of column names into a delimited string.
+ *
+ * @param array $columns
+ * @return string
+ */
+ public function columnize(array $columns)
+ {
+ return implode(', ', array_map([$this, 'wrap'], $columns));
+ }
+
+ /**
+ * Create query parameter place-holders for an array.
+ *
+ * @param array $values
+ * @return string
+ */
+ public function parameterize(array $values)
+ {
+ return implode(', ', array_map([$this, 'parameter'], $values));
+ }
+
+ /**
+ * Get the appropriate query parameter place-holder for a value.
+ *
+ * @param mixed $value
+ * @return string
+ */
+ public function parameter($value)
+ {
+ return $this->isExpression($value) ? $this->getValue($value) : '?';
+ }
+
+ /**
+ * Get the value of a raw expression.
+ *
+ * @param \Illuminate\Database\Query\Expression $expression
+ * @return string
+ */
+ public function getValue($expression)
+ {
+ return $expression->getValue();
+ }
+
+ /**
+ * Determine if the given value is a raw expression.
+ *
+ * @param mixed $value
+ * @return bool
+ */
+ public function isExpression($value)
+ {
+ return $value instanceof Expression;
+ }
+
+ /**
+ * Get the format for database stored dates.
+ *
+ * @return string
+ */
+ public function getDateFormat()
+ {
+ return 'Y-m-d H:i:s';
+ }
+
+ /**
+ * Get the grammar's table prefix.
+ *
+ * @return string
+ */
+ public function getTablePrefix()
+ {
+ return $this->tablePrefix;
+ }
+
+ /**
+ * Set the grammar's table prefix.
+ *
+ * @param string $prefix
+ * @return $this
+ */
+ public function setTablePrefix($prefix)
+ {
+ $this->tablePrefix = $prefix;
+
+ return $this;
+ }
+}
diff --git a/vendor/illuminate/database/MigrationServiceProvider.php b/vendor/illuminate/database/MigrationServiceProvider.php
new file mode 100755
index 00000000..bc0abebf
--- /dev/null
+++ b/vendor/illuminate/database/MigrationServiceProvider.php
@@ -0,0 +1,221 @@
+registerRepository();
+
+ // Once we have registered the migrator instance we will go ahead and register
+ // all of the migration related commands that are used by the "Artisan" CLI
+ // so that they may be easily accessed for registering with the consoles.
+ $this->registerMigrator();
+
+ $this->registerCreator();
+
+ $this->registerCommands();
+ }
+
+ /**
+ * Register the migration repository service.
+ *
+ * @return void
+ */
+ protected function registerRepository()
+ {
+ $this->app->singleton('migration.repository', function ($app) {
+ $table = $app['config']['database.migrations'];
+
+ return new DatabaseMigrationRepository($app['db'], $table);
+ });
+ }
+
+ /**
+ * Register the migrator service.
+ *
+ * @return void
+ */
+ protected function registerMigrator()
+ {
+ // The migrator is responsible for actually running and rollback the migration
+ // files in the application. We'll pass in our database connection resolver
+ // so the migrator can resolve any of these connections when it needs to.
+ $this->app->singleton('migrator', function ($app) {
+ $repository = $app['migration.repository'];
+
+ return new Migrator($repository, $app['db'], $app['files']);
+ });
+ }
+
+ /**
+ * Register the migration creator.
+ *
+ * @return void
+ */
+ protected function registerCreator()
+ {
+ $this->app->singleton('migration.creator', function ($app) {
+ return new MigrationCreator($app['files']);
+ });
+ }
+
+ /**
+ * Register all of the migration commands.
+ *
+ * @return void
+ */
+ protected function registerCommands()
+ {
+ $commands = ['Migrate', 'Rollback', 'Reset', 'Refresh', 'Install', 'Make', 'Status'];
+
+ // We'll simply spin through the list of commands that are migration related
+ // and register each one of them with an application container. They will
+ // be resolved in the Artisan start file and registered on the console.
+ foreach ($commands as $command) {
+ $this->{'register'.$command.'Command'}();
+ }
+
+ // Once the commands are registered in the application IoC container we will
+ // register them with the Artisan start event so that these are available
+ // when the Artisan application actually starts up and is getting used.
+ $this->commands(
+ 'command.migrate', 'command.migrate.make',
+ 'command.migrate.install', 'command.migrate.rollback',
+ 'command.migrate.reset', 'command.migrate.refresh',
+ 'command.migrate.status'
+ );
+ }
+
+ /**
+ * Register the "migrate" migration command.
+ *
+ * @return void
+ */
+ protected function registerMigrateCommand()
+ {
+ $this->app->singleton('command.migrate', function ($app) {
+ return new MigrateCommand($app['migrator']);
+ });
+ }
+
+ /**
+ * Register the "rollback" migration command.
+ *
+ * @return void
+ */
+ protected function registerRollbackCommand()
+ {
+ $this->app->singleton('command.migrate.rollback', function ($app) {
+ return new RollbackCommand($app['migrator']);
+ });
+ }
+
+ /**
+ * Register the "reset" migration command.
+ *
+ * @return void
+ */
+ protected function registerResetCommand()
+ {
+ $this->app->singleton('command.migrate.reset', function ($app) {
+ return new ResetCommand($app['migrator']);
+ });
+ }
+
+ /**
+ * Register the "refresh" migration command.
+ *
+ * @return void
+ */
+ protected function registerRefreshCommand()
+ {
+ $this->app->singleton('command.migrate.refresh', function () {
+ return new RefreshCommand;
+ });
+ }
+
+ /**
+ * Register the "make" migration command.
+ *
+ * @return void
+ */
+ protected function registerMakeCommand()
+ {
+ $this->app->singleton('command.migrate.make', function ($app) {
+ // Once we have the migration creator registered, we will create the command
+ // and inject the creator. The creator is responsible for the actual file
+ // creation of the migrations, and may be extended by these developers.
+ $creator = $app['migration.creator'];
+
+ $composer = $app['composer'];
+
+ return new MigrateMakeCommand($creator, $composer);
+ });
+ }
+
+ /**
+ * Register the "status" migration command.
+ *
+ * @return void
+ */
+ protected function registerStatusCommand()
+ {
+ $this->app->singleton('command.migrate.status', function ($app) {
+ return new StatusCommand($app['migrator']);
+ });
+ }
+
+ /**
+ * Register the "install" migration command.
+ *
+ * @return void
+ */
+ protected function registerInstallCommand()
+ {
+ $this->app->singleton('command.migrate.install', function ($app) {
+ return new InstallCommand($app['migration.repository']);
+ });
+ }
+
+ /**
+ * Get the services provided by the provider.
+ *
+ * @return array
+ */
+ public function provides()
+ {
+ return [
+ 'migrator', 'migration.repository', 'command.migrate',
+ 'command.migrate.rollback', 'command.migrate.reset',
+ 'command.migrate.refresh', 'command.migrate.install',
+ 'command.migrate.status', 'migration.creator',
+ 'command.migrate.make',
+ ];
+ }
+}
diff --git a/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php b/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php
new file mode 100755
index 00000000..d7b6aa98
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php
@@ -0,0 +1,184 @@
+table = $table;
+ $this->resolver = $resolver;
+ }
+
+ /**
+ * Get the ran migrations.
+ *
+ * @return array
+ */
+ public function getRan()
+ {
+ return $this->table()
+ ->orderBy('batch', 'asc')
+ ->orderBy('migration', 'asc')
+ ->pluck('migration');
+ }
+
+ /**
+ * Get the last migration batch.
+ *
+ * @return array
+ */
+ public function getLast()
+ {
+ $query = $this->table()->where('batch', $this->getLastBatchNumber());
+
+ return $query->orderBy('migration', 'desc')->get();
+ }
+
+ /**
+ * Log that a migration was run.
+ *
+ * @param string $file
+ * @param int $batch
+ * @return void
+ */
+ public function log($file, $batch)
+ {
+ $record = ['migration' => $file, 'batch' => $batch];
+
+ $this->table()->insert($record);
+ }
+
+ /**
+ * Remove a migration from the log.
+ *
+ * @param object $migration
+ * @return void
+ */
+ public function delete($migration)
+ {
+ $this->table()->where('migration', $migration->migration)->delete();
+ }
+
+ /**
+ * Get the next migration batch number.
+ *
+ * @return int
+ */
+ public function getNextBatchNumber()
+ {
+ return $this->getLastBatchNumber() + 1;
+ }
+
+ /**
+ * Get the last migration batch number.
+ *
+ * @return int
+ */
+ public function getLastBatchNumber()
+ {
+ return $this->table()->max('batch');
+ }
+
+ /**
+ * Create the migration repository data store.
+ *
+ * @return void
+ */
+ public function createRepository()
+ {
+ $schema = $this->getConnection()->getSchemaBuilder();
+
+ $schema->create($this->table, function ($table) {
+ // The migrations table is responsible for keeping track of which of the
+ // migrations have actually run for the application. We'll create the
+ // table to hold the migration file's path as well as the batch ID.
+ $table->string('migration');
+
+ $table->integer('batch');
+ });
+ }
+
+ /**
+ * Determine if the migration repository exists.
+ *
+ * @return bool
+ */
+ public function repositoryExists()
+ {
+ $schema = $this->getConnection()->getSchemaBuilder();
+
+ return $schema->hasTable($this->table);
+ }
+
+ /**
+ * Get a query builder for the migration table.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ protected function table()
+ {
+ return $this->getConnection()->table($this->table);
+ }
+
+ /**
+ * Get the connection resolver instance.
+ *
+ * @return \Illuminate\Database\ConnectionResolverInterface
+ */
+ public function getConnectionResolver()
+ {
+ return $this->resolver;
+ }
+
+ /**
+ * Resolve the database connection instance.
+ *
+ * @return \Illuminate\Database\Connection
+ */
+ public function getConnection()
+ {
+ return $this->resolver->connection($this->connection);
+ }
+
+ /**
+ * Set the information source to gather data.
+ *
+ * @param string $name
+ * @return void
+ */
+ public function setSource($name)
+ {
+ $this->connection = $name;
+ }
+}
diff --git a/vendor/illuminate/database/Migrations/Migration.php b/vendor/illuminate/database/Migrations/Migration.php
new file mode 100755
index 00000000..699154c9
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/Migration.php
@@ -0,0 +1,23 @@
+connection;
+ }
+}
diff --git a/vendor/illuminate/database/Migrations/MigrationCreator.php b/vendor/illuminate/database/Migrations/MigrationCreator.php
new file mode 100755
index 00000000..beacfe16
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/MigrationCreator.php
@@ -0,0 +1,181 @@
+files = $files;
+ }
+
+ /**
+ * Create a new migration at the given path.
+ *
+ * @param string $name
+ * @param string $path
+ * @param string $table
+ * @param bool $create
+ * @return string
+ */
+ public function create($name, $path, $table = null, $create = false)
+ {
+ $path = $this->getPath($name, $path);
+
+ // First we will get the stub file for the migration, which serves as a type
+ // of template for the migration. Once we have those we will populate the
+ // various place-holders, save the file, and run the post create event.
+ $stub = $this->getStub($table, $create);
+
+ $this->files->put($path, $this->populateStub($name, $stub, $table));
+
+ $this->firePostCreateHooks();
+
+ return $path;
+ }
+
+ /**
+ * Get the migration stub file.
+ *
+ * @param string $table
+ * @param bool $create
+ * @return string
+ */
+ protected function getStub($table, $create)
+ {
+ if (is_null($table)) {
+ return $this->files->get($this->getStubPath().'/blank.stub');
+ }
+
+ // We also have stubs for creating new tables and modifying existing tables
+ // to save the developer some typing when they are creating a new tables
+ // or modifying existing tables. We'll grab the appropriate stub here.
+ else {
+ $stub = $create ? 'create.stub' : 'update.stub';
+
+ return $this->files->get($this->getStubPath()."/{$stub}");
+ }
+ }
+
+ /**
+ * Populate the place-holders in the migration stub.
+ *
+ * @param string $name
+ * @param string $stub
+ * @param string $table
+ * @return string
+ */
+ protected function populateStub($name, $stub, $table)
+ {
+ $stub = str_replace('DummyClass', $this->getClassName($name), $stub);
+
+ // Here we will replace the table place-holders with the table specified by
+ // the developer, which is useful for quickly creating a tables creation
+ // or update migration from the console instead of typing it manually.
+ if (! is_null($table)) {
+ $stub = str_replace('DummyTable', $table, $stub);
+ }
+
+ return $stub;
+ }
+
+ /**
+ * Get the class name of a migration name.
+ *
+ * @param string $name
+ * @return string
+ */
+ protected function getClassName($name)
+ {
+ return Str::studly($name);
+ }
+
+ /**
+ * Fire the registered post create hooks.
+ *
+ * @return void
+ */
+ protected function firePostCreateHooks()
+ {
+ foreach ($this->postCreate as $callback) {
+ call_user_func($callback);
+ }
+ }
+
+ /**
+ * Register a post migration create hook.
+ *
+ * @param \Closure $callback
+ * @return void
+ */
+ public function afterCreate(Closure $callback)
+ {
+ $this->postCreate[] = $callback;
+ }
+
+ /**
+ * Get the full path name to the migration.
+ *
+ * @param string $name
+ * @param string $path
+ * @return string
+ */
+ protected function getPath($name, $path)
+ {
+ return $path.'/'.$this->getDatePrefix().'_'.$name.'.php';
+ }
+
+ /**
+ * Get the date prefix for the migration.
+ *
+ * @return string
+ */
+ protected function getDatePrefix()
+ {
+ return date('Y_m_d_His');
+ }
+
+ /**
+ * Get the path to the stubs.
+ *
+ * @return string
+ */
+ public function getStubPath()
+ {
+ return __DIR__.'/stubs';
+ }
+
+ /**
+ * Get the filesystem instance.
+ *
+ * @return \Illuminate\Filesystem\Filesystem
+ */
+ public function getFilesystem()
+ {
+ return $this->files;
+ }
+}
diff --git a/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php b/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php
new file mode 100755
index 00000000..5450a7af
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php
@@ -0,0 +1,66 @@
+files = $files;
+ $this->resolver = $resolver;
+ $this->repository = $repository;
+ }
+
+ /**
+ * Run the outstanding migrations at a given path.
+ *
+ * @param string $path
+ * @param array $options
+ * @return void
+ */
+ public function run($path, array $options = [])
+ {
+ $this->notes = [];
+
+ $files = $this->getMigrationFiles($path);
+
+ // Once we grab all of the migration files for the path, we will compare them
+ // against the migrations that have already been run for this package then
+ // run each of the outstanding migrations against a database connection.
+ $ran = $this->repository->getRan();
+
+ $migrations = array_diff($files, $ran);
+
+ $this->requireFiles($path, $migrations);
+
+ $this->runMigrationList($migrations, $options);
+ }
+
+ /**
+ * Run an array of migrations.
+ *
+ * @param array $migrations
+ * @param array $options
+ * @return void
+ */
+ public function runMigrationList($migrations, array $options = [])
+ {
+ // First we will just make sure that there are any migrations to run. If there
+ // aren't, we will just make a note of it to the developer so they're aware
+ // that all of the migrations have been run against this database system.
+ if (count($migrations) == 0) {
+ $this->note('Nothing to migrate.');
+
+ return;
+ }
+
+ $batch = $this->repository->getNextBatchNumber();
+
+ $pretend = Arr::get($options, 'pretend', false);
+
+ $step = Arr::get($options, 'step', false);
+
+ // Once we have the array of migrations, we will spin through them and run the
+ // migrations "up" so the changes are made to the databases. We'll then log
+ // that the migration was run so we don't repeat it next time we execute.
+ foreach ($migrations as $file) {
+ $this->runUp($file, $batch, $pretend);
+
+ // If we are stepping through the migrations, then we will increment the
+ // batch value for each individual migration that is run. That way we
+ // can run "artisan migrate:rollback" and undo them one at a time.
+ if ($step) {
+ $batch++;
+ }
+ }
+ }
+
+ /**
+ * Run "up" a migration instance.
+ *
+ * @param string $file
+ * @param int $batch
+ * @param bool $pretend
+ * @return void
+ */
+ protected function runUp($file, $batch, $pretend)
+ {
+ // First we will resolve a "real" instance of the migration class from this
+ // migration file name. Once we have the instances we can run the actual
+ // command such as "up" or "down", or we can just simulate the action.
+ $migration = $this->resolve($file);
+
+ if ($pretend) {
+ return $this->pretendToRun($migration, 'up');
+ }
+
+ $migration->up();
+
+ // Once we have run a migrations class, we will log that it was run in this
+ // repository so that we don't try to run it next time we do a migration
+ // in the application. A migration repository keeps the migrate order.
+ $this->repository->log($file, $batch);
+
+ $this->note("Migrated: $file");
+ }
+
+ /**
+ * Rollback the last migration operation.
+ *
+ * @param bool $pretend
+ * @return int
+ */
+ public function rollback($pretend = false)
+ {
+ $this->notes = [];
+
+ // We want to pull in the last batch of migrations that ran on the previous
+ // migration operation. We'll then reverse those migrations and run each
+ // of them "down" to reverse the last migration "operation" which ran.
+ $migrations = $this->repository->getLast();
+
+ $count = count($migrations);
+
+ if ($count === 0) {
+ $this->note('Nothing to rollback.');
+ } else {
+ // We need to reverse these migrations so that they are "downed" in reverse
+ // to what they run on "up". It lets us backtrack through the migrations
+ // and properly reverse the entire database schema operation that ran.
+ foreach ($migrations as $migration) {
+ $this->runDown((object) $migration, $pretend);
+ }
+ }
+
+ return $count;
+ }
+
+ /**
+ * Rolls all of the currently applied migrations back.
+ *
+ * @param bool $pretend
+ * @return int
+ */
+ public function reset($pretend = false)
+ {
+ $this->notes = [];
+
+ $migrations = array_reverse($this->repository->getRan());
+
+ $count = count($migrations);
+
+ if ($count === 0) {
+ $this->note('Nothing to rollback.');
+ } else {
+ foreach ($migrations as $migration) {
+ $this->runDown((object) ['migration' => $migration], $pretend);
+ }
+ }
+
+ return $count;
+ }
+
+ /**
+ * Run "down" a migration instance.
+ *
+ * @param object $migration
+ * @param bool $pretend
+ * @return void
+ */
+ protected function runDown($migration, $pretend)
+ {
+ $file = $migration->migration;
+
+ // First we will get the file name of the migration so we can resolve out an
+ // instance of the migration. Once we get an instance we can either run a
+ // pretend execution of the migration or we can run the real migration.
+ $instance = $this->resolve($file);
+
+ if ($pretend) {
+ return $this->pretendToRun($instance, 'down');
+ }
+
+ $instance->down();
+
+ // Once we have successfully run the migration "down" we will remove it from
+ // the migration repository so it will be considered to have not been run
+ // by the application then will be able to fire by any later operation.
+ $this->repository->delete($migration);
+
+ $this->note("Rolled back: $file");
+ }
+
+ /**
+ * Get all of the migration files in a given path.
+ *
+ * @param string $path
+ * @return array
+ */
+ public function getMigrationFiles($path)
+ {
+ $files = $this->files->glob($path.'/*_*.php');
+
+ // Once we have the array of files in the directory we will just remove the
+ // extension and take the basename of the file which is all we need when
+ // finding the migrations that haven't been run against the databases.
+ if ($files === false) {
+ return [];
+ }
+
+ $files = array_map(function ($file) {
+ return str_replace('.php', '', basename($file));
+
+ }, $files);
+
+ // Once we have all of the formatted file names we will sort them and since
+ // they all start with a timestamp this should give us the migrations in
+ // the order they were actually created by the application developers.
+ sort($files);
+
+ return $files;
+ }
+
+ /**
+ * Require in all the migration files in a given path.
+ *
+ * @param string $path
+ * @param array $files
+ * @return void
+ */
+ public function requireFiles($path, array $files)
+ {
+ foreach ($files as $file) {
+ $this->files->requireOnce($path.'/'.$file.'.php');
+ }
+ }
+
+ /**
+ * Pretend to run the migrations.
+ *
+ * @param object $migration
+ * @param string $method
+ * @return void
+ */
+ protected function pretendToRun($migration, $method)
+ {
+ foreach ($this->getQueries($migration, $method) as $query) {
+ $name = get_class($migration);
+
+ $this->note("{$name}: {$query['query']}");
+ }
+ }
+
+ /**
+ * Get all of the queries that would be run for a migration.
+ *
+ * @param object $migration
+ * @param string $method
+ * @return array
+ */
+ protected function getQueries($migration, $method)
+ {
+ $connection = $migration->getConnection();
+
+ // Now that we have the connections we can resolve it and pretend to run the
+ // queries against the database returning the array of raw SQL statements
+ // that would get fired against the database system for this migration.
+ $db = $this->resolveConnection($connection);
+
+ return $db->pretend(function () use ($migration, $method) {
+ $migration->$method();
+ });
+ }
+
+ /**
+ * Resolve a migration instance from a file.
+ *
+ * @param string $file
+ * @return object
+ */
+ public function resolve($file)
+ {
+ $file = implode('_', array_slice(explode('_', $file), 4));
+
+ $class = Str::studly($file);
+
+ return new $class;
+ }
+
+ /**
+ * Raise a note event for the migrator.
+ *
+ * @param string $message
+ * @return void
+ */
+ protected function note($message)
+ {
+ $this->notes[] = $message;
+ }
+
+ /**
+ * Get the notes for the last operation.
+ *
+ * @return array
+ */
+ public function getNotes()
+ {
+ return $this->notes;
+ }
+
+ /**
+ * Resolve the database connection instance.
+ *
+ * @param string $connection
+ * @return \Illuminate\Database\Connection
+ */
+ public function resolveConnection($connection)
+ {
+ return $this->resolver->connection($connection);
+ }
+
+ /**
+ * Set the default connection name.
+ *
+ * @param string $name
+ * @return void
+ */
+ public function setConnection($name)
+ {
+ if (! is_null($name)) {
+ $this->resolver->setDefaultConnection($name);
+ }
+
+ $this->repository->setSource($name);
+
+ $this->connection = $name;
+ }
+
+ /**
+ * Get the migration repository instance.
+ *
+ * @return \Illuminate\Database\Migrations\MigrationRepositoryInterface
+ */
+ public function getRepository()
+ {
+ return $this->repository;
+ }
+
+ /**
+ * Determine if the migration repository exists.
+ *
+ * @return bool
+ */
+ public function repositoryExists()
+ {
+ return $this->repository->repositoryExists();
+ }
+
+ /**
+ * Get the file system instance.
+ *
+ * @return \Illuminate\Filesystem\Filesystem
+ */
+ public function getFilesystem()
+ {
+ return $this->files;
+ }
+}
diff --git a/vendor/illuminate/database/Migrations/stubs/blank.stub b/vendor/illuminate/database/Migrations/stubs/blank.stub
new file mode 100755
index 00000000..4ff5ee58
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/stubs/blank.stub
@@ -0,0 +1,27 @@
+increments('id');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::drop('DummyTable');
+ }
+}
diff --git a/vendor/illuminate/database/Migrations/stubs/update.stub b/vendor/illuminate/database/Migrations/stubs/update.stub
new file mode 100755
index 00000000..8114a812
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/stubs/update.stub
@@ -0,0 +1,31 @@
+schemaGrammar)) {
+ $this->useDefaultSchemaGrammar();
+ }
+
+ return new MySqlBuilder($this);
+ }
+
+ /**
+ * Get the default query grammar instance.
+ *
+ * @return \Illuminate\Database\Query\Grammars\MySqlGrammar
+ */
+ protected function getDefaultQueryGrammar()
+ {
+ return $this->withTablePrefix(new QueryGrammar);
+ }
+
+ /**
+ * Get the default schema grammar instance.
+ *
+ * @return \Illuminate\Database\Schema\Grammars\MySqlGrammar
+ */
+ protected function getDefaultSchemaGrammar()
+ {
+ return $this->withTablePrefix(new SchemaGrammar);
+ }
+
+ /**
+ * Get the default post processor instance.
+ *
+ * @return \Illuminate\Database\Query\Processors\MySqlProcessor
+ */
+ protected function getDefaultPostProcessor()
+ {
+ return new MySqlProcessor;
+ }
+
+ /**
+ * Get the Doctrine DBAL driver.
+ *
+ * @return \Doctrine\DBAL\Driver\PDOMySql\Driver
+ */
+ protected function getDoctrineDriver()
+ {
+ return new DoctrineDriver;
+ }
+}
diff --git a/vendor/illuminate/database/PostgresConnection.php b/vendor/illuminate/database/PostgresConnection.php
new file mode 100755
index 00000000..f12ec893
--- /dev/null
+++ b/vendor/illuminate/database/PostgresConnection.php
@@ -0,0 +1,51 @@
+withTablePrefix(new QueryGrammar);
+ }
+
+ /**
+ * Get the default schema grammar instance.
+ *
+ * @return \Illuminate\Database\Schema\Grammars\PostgresGrammar
+ */
+ protected function getDefaultSchemaGrammar()
+ {
+ return $this->withTablePrefix(new SchemaGrammar);
+ }
+
+ /**
+ * Get the default post processor instance.
+ *
+ * @return \Illuminate\Database\Query\Processors\PostgresProcessor
+ */
+ protected function getDefaultPostProcessor()
+ {
+ return new PostgresProcessor;
+ }
+
+ /**
+ * Get the Doctrine DBAL driver.
+ *
+ * @return \Doctrine\DBAL\Driver\PDOPgSql\Driver
+ */
+ protected function getDoctrineDriver()
+ {
+ return new DoctrineDriver;
+ }
+}
diff --git a/vendor/illuminate/database/Query/Builder.php b/vendor/illuminate/database/Query/Builder.php
new file mode 100755
index 00000000..a7a8a03b
--- /dev/null
+++ b/vendor/illuminate/database/Query/Builder.php
@@ -0,0 +1,2094 @@
+ [],
+ 'join' => [],
+ 'where' => [],
+ 'having' => [],
+ 'order' => [],
+ 'union' => [],
+ ];
+
+ /**
+ * An aggregate function and column to be run.
+ *
+ * @var array
+ */
+ public $aggregate;
+
+ /**
+ * The columns that should be returned.
+ *
+ * @var array
+ */
+ public $columns;
+
+ /**
+ * Indicates if the query returns distinct results.
+ *
+ * @var bool
+ */
+ public $distinct = false;
+
+ /**
+ * The table which the query is targeting.
+ *
+ * @var string
+ */
+ public $from;
+
+ /**
+ * The table joins for the query.
+ *
+ * @var array
+ */
+ public $joins;
+
+ /**
+ * The where constraints for the query.
+ *
+ * @var array
+ */
+ public $wheres;
+
+ /**
+ * The groupings for the query.
+ *
+ * @var array
+ */
+ public $groups;
+
+ /**
+ * The having constraints for the query.
+ *
+ * @var array
+ */
+ public $havings;
+
+ /**
+ * The orderings for the query.
+ *
+ * @var array
+ */
+ public $orders;
+
+ /**
+ * The maximum number of records to return.
+ *
+ * @var int
+ */
+ public $limit;
+
+ /**
+ * The number of records to skip.
+ *
+ * @var int
+ */
+ public $offset;
+
+ /**
+ * The query union statements.
+ *
+ * @var array
+ */
+ public $unions;
+
+ /**
+ * The maximum number of union records to return.
+ *
+ * @var int
+ */
+ public $unionLimit;
+
+ /**
+ * The number of union records to skip.
+ *
+ * @var int
+ */
+ public $unionOffset;
+
+ /**
+ * The orderings for the union query.
+ *
+ * @var array
+ */
+ public $unionOrders;
+
+ /**
+ * Indicates whether row locking is being used.
+ *
+ * @var string|bool
+ */
+ public $lock;
+
+ /**
+ * The field backups currently in use.
+ *
+ * @var array
+ */
+ protected $backups = [];
+
+ /**
+ * The binding backups currently in use.
+ *
+ * @var array
+ */
+ protected $bindingBackups = [];
+
+ /**
+ * All of the available clause operators.
+ *
+ * @var array
+ */
+ protected $operators = [
+ '=', '<', '>', '<=', '>=', '<>', '!=',
+ 'like', 'like binary', 'not like', 'between', 'ilike',
+ '&', '|', '^', '<<', '>>',
+ 'rlike', 'regexp', 'not regexp',
+ '~', '~*', '!~', '!~*', 'similar to',
+ 'not similar to',
+ ];
+
+ /**
+ * Whether use write pdo for select.
+ *
+ * @var bool
+ */
+ protected $useWritePdo = false;
+
+ /**
+ * Create a new query builder instance.
+ *
+ * @param \Illuminate\Database\ConnectionInterface $connection
+ * @param \Illuminate\Database\Query\Grammars\Grammar $grammar
+ * @param \Illuminate\Database\Query\Processors\Processor $processor
+ * @return void
+ */
+ public function __construct(ConnectionInterface $connection,
+ Grammar $grammar,
+ Processor $processor)
+ {
+ $this->grammar = $grammar;
+ $this->processor = $processor;
+ $this->connection = $connection;
+ }
+
+ /**
+ * Set the columns to be selected.
+ *
+ * @param array|mixed $columns
+ * @return $this
+ */
+ public function select($columns = ['*'])
+ {
+ $this->columns = is_array($columns) ? $columns : func_get_args();
+
+ return $this;
+ }
+
+ /**
+ * Add a new "raw" select expression to the query.
+ *
+ * @param string $expression
+ * @param array $bindings
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function selectRaw($expression, array $bindings = [])
+ {
+ $this->addSelect(new Expression($expression));
+
+ if ($bindings) {
+ $this->addBinding($bindings, 'select');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a subselect expression to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+ * @param string $as
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function selectSub($query, $as)
+ {
+ if ($query instanceof Closure) {
+ $callback = $query;
+
+ $callback($query = $this->newQuery());
+ }
+
+ if ($query instanceof self) {
+ $bindings = $query->getBindings();
+
+ $query = $query->toSql();
+ } elseif (is_string($query)) {
+ $bindings = [];
+ } else {
+ throw new InvalidArgumentException;
+ }
+
+ return $this->selectRaw('('.$query.') as '.$this->grammar->wrap($as), $bindings);
+ }
+
+ /**
+ * Add a new select column to the query.
+ *
+ * @param array|mixed $column
+ * @return $this
+ */
+ public function addSelect($column)
+ {
+ $column = is_array($column) ? $column : func_get_args();
+
+ $this->columns = array_merge((array) $this->columns, $column);
+
+ return $this;
+ }
+
+ /**
+ * Force the query to only return distinct results.
+ *
+ * @return $this
+ */
+ public function distinct()
+ {
+ $this->distinct = true;
+
+ return $this;
+ }
+
+ /**
+ * Set the table which the query is targeting.
+ *
+ * @param string $table
+ * @return $this
+ */
+ public function from($table)
+ {
+ $this->from = $table;
+
+ return $this;
+ }
+
+ /**
+ * Add a join clause to the query.
+ *
+ * @param string $table
+ * @param string $one
+ * @param string $operator
+ * @param string $two
+ * @param string $type
+ * @param bool $where
+ * @return $this
+ */
+ public function join($table, $one, $operator = null, $two = null, $type = 'inner', $where = false)
+ {
+ // If the first "column" of the join is really a Closure instance the developer
+ // is trying to build a join with a complex "on" clause containing more than
+ // one condition, so we'll add the join and call a Closure with the query.
+ if ($one instanceof Closure) {
+ $join = new JoinClause($type, $table);
+
+ call_user_func($one, $join);
+
+ $this->joins[] = $join;
+
+ $this->addBinding($join->bindings, 'join');
+ }
+
+ // If the column is simply a string, we can assume the join simply has a basic
+ // "on" clause with a single condition. So we will just build the join with
+ // this simple join clauses attached to it. There is not a join callback.
+ else {
+ $join = new JoinClause($type, $table);
+
+ $this->joins[] = $join->on(
+ $one, $operator, $two, 'and', $where
+ );
+
+ $this->addBinding($join->bindings, 'join');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a "join where" clause to the query.
+ *
+ * @param string $table
+ * @param string $one
+ * @param string $operator
+ * @param string $two
+ * @param string $type
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function joinWhere($table, $one, $operator, $two, $type = 'inner')
+ {
+ return $this->join($table, $one, $operator, $two, $type, true);
+ }
+
+ /**
+ * Add a left join to the query.
+ *
+ * @param string $table
+ * @param string $first
+ * @param string $operator
+ * @param string $second
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function leftJoin($table, $first, $operator = null, $second = null)
+ {
+ return $this->join($table, $first, $operator, $second, 'left');
+ }
+
+ /**
+ * Add a "join where" clause to the query.
+ *
+ * @param string $table
+ * @param string $one
+ * @param string $operator
+ * @param string $two
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function leftJoinWhere($table, $one, $operator, $two)
+ {
+ return $this->joinWhere($table, $one, $operator, $two, 'left');
+ }
+
+ /**
+ * Add a right join to the query.
+ *
+ * @param string $table
+ * @param string $first
+ * @param string $operator
+ * @param string $second
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function rightJoin($table, $first, $operator = null, $second = null)
+ {
+ return $this->join($table, $first, $operator, $second, 'right');
+ }
+
+ /**
+ * Add a "right join where" clause to the query.
+ *
+ * @param string $table
+ * @param string $one
+ * @param string $operator
+ * @param string $two
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function rightJoinWhere($table, $one, $operator, $two)
+ {
+ return $this->joinWhere($table, $one, $operator, $two, 'right');
+ }
+
+ /**
+ * Add a basic where clause to the query.
+ *
+ * @param string|array|\Closure $column
+ * @param string $operator
+ * @param mixed $value
+ * @param string $boolean
+ * @return $this
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function where($column, $operator = null, $value = null, $boolean = 'and')
+ {
+ // If the column is an array, we will assume it is an array of key-value pairs
+ // and can add them each as a where clause. We will maintain the boolean we
+ // received when the method was called and pass it into the nested where.
+ if (is_array($column)) {
+ return $this->whereNested(function ($query) use ($column) {
+ foreach ($column as $key => $value) {
+ $query->where($key, '=', $value);
+ }
+ }, $boolean);
+ }
+
+ // Here we will make some assumptions about the operator. If only 2 values are
+ // passed to the method, we will assume that the operator is an equals sign
+ // and keep going. Otherwise, we'll require the operator to be passed in.
+ if (func_num_args() == 2) {
+ list($value, $operator) = [$operator, '='];
+ } elseif ($this->invalidOperatorAndValue($operator, $value)) {
+ throw new InvalidArgumentException('Illegal operator and value combination.');
+ }
+
+ // If the columns is actually a Closure instance, we will assume the developer
+ // wants to begin a nested where statement which is wrapped in parenthesis.
+ // We'll add that Closure to the query then return back out immediately.
+ if ($column instanceof Closure) {
+ return $this->whereNested($column, $boolean);
+ }
+
+ // If the given operator is not found in the list of valid operators we will
+ // assume that the developer is just short-cutting the '=' operators and
+ // we will set the operators to '=' and set the values appropriately.
+ if (! in_array(strtolower($operator), $this->operators, true)) {
+ list($value, $operator) = [$operator, '='];
+ }
+
+ // If the value is a Closure, it means the developer is performing an entire
+ // sub-select within the query and we will need to compile the sub-select
+ // within the where clause to get the appropriate query record results.
+ if ($value instanceof Closure) {
+ return $this->whereSub($column, $operator, $value, $boolean);
+ }
+
+ // If the value is "null", we will just assume the developer wants to add a
+ // where null clause to the query. So, we will allow a short-cut here to
+ // that method for convenience so the developer doesn't have to check.
+ if (is_null($value)) {
+ return $this->whereNull($column, $boolean, $operator != '=');
+ }
+
+ // Now that we are working with just a simple query we can put the elements
+ // in our array and add the query binding to our array of bindings that
+ // will be bound to each SQL statements when it is finally executed.
+ $type = 'Basic';
+
+ $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean');
+
+ if (! $value instanceof Expression) {
+ $this->addBinding($value, 'where');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add an "or where" clause to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhere($column, $operator = null, $value = null)
+ {
+ return $this->where($column, $operator, $value, 'or');
+ }
+
+ /**
+ * Determine if the given operator and value combination is legal.
+ *
+ * @param string $operator
+ * @param mixed $value
+ * @return bool
+ */
+ protected function invalidOperatorAndValue($operator, $value)
+ {
+ $isOperator = in_array($operator, $this->operators);
+
+ return $isOperator && $operator != '=' && is_null($value);
+ }
+
+ /**
+ * Add a raw where clause to the query.
+ *
+ * @param string $sql
+ * @param array $bindings
+ * @param string $boolean
+ * @return $this
+ */
+ public function whereRaw($sql, array $bindings = [], $boolean = 'and')
+ {
+ $type = 'raw';
+
+ $this->wheres[] = compact('type', 'sql', 'boolean');
+
+ $this->addBinding($bindings, 'where');
+
+ return $this;
+ }
+
+ /**
+ * Add a raw or where clause to the query.
+ *
+ * @param string $sql
+ * @param array $bindings
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhereRaw($sql, array $bindings = [])
+ {
+ return $this->whereRaw($sql, $bindings, 'or');
+ }
+
+ /**
+ * Add a where between statement to the query.
+ *
+ * @param string $column
+ * @param array $values
+ * @param string $boolean
+ * @param bool $not
+ * @return $this
+ */
+ public function whereBetween($column, array $values, $boolean = 'and', $not = false)
+ {
+ $type = 'between';
+
+ $this->wheres[] = compact('column', 'type', 'boolean', 'not');
+
+ $this->addBinding($values, 'where');
+
+ return $this;
+ }
+
+ /**
+ * Add an or where between statement to the query.
+ *
+ * @param string $column
+ * @param array $values
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhereBetween($column, array $values)
+ {
+ return $this->whereBetween($column, $values, 'or');
+ }
+
+ /**
+ * Add a where not between statement to the query.
+ *
+ * @param string $column
+ * @param array $values
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function whereNotBetween($column, array $values, $boolean = 'and')
+ {
+ return $this->whereBetween($column, $values, $boolean, true);
+ }
+
+ /**
+ * Add an or where not between statement to the query.
+ *
+ * @param string $column
+ * @param array $values
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhereNotBetween($column, array $values)
+ {
+ return $this->whereNotBetween($column, $values, 'or');
+ }
+
+ /**
+ * Add a nested where statement to the query.
+ *
+ * @param \Closure $callback
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function whereNested(Closure $callback, $boolean = 'and')
+ {
+ $query = $this->forNestedWhere();
+
+ call_user_func($callback, $query);
+
+ return $this->addNestedWhereQuery($query, $boolean);
+ }
+
+ /**
+ * Create a new query instance for nested where condition.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public function forNestedWhere()
+ {
+ $query = $this->newQuery();
+
+ return $query->from($this->from);
+ }
+
+ /**
+ * Add another query builder as a nested where to the query builder.
+ *
+ * @param \Illuminate\Database\Query\Builder|static $query
+ * @param string $boolean
+ * @return $this
+ */
+ public function addNestedWhereQuery($query, $boolean = 'and')
+ {
+ if (count($query->wheres)) {
+ $type = 'Nested';
+
+ $this->wheres[] = compact('type', 'query', 'boolean');
+
+ $this->addBinding($query->getBindings(), 'where');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a full sub-select to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param \Closure $callback
+ * @param string $boolean
+ * @return $this
+ */
+ protected function whereSub($column, $operator, Closure $callback, $boolean)
+ {
+ $type = 'Sub';
+
+ $query = $this->newQuery();
+
+ // Once we have the query instance we can simply execute it so it can add all
+ // of the sub-select's conditions to itself, and then we can cache it off
+ // in the array of where clauses for the "main" parent query instance.
+ call_user_func($callback, $query);
+
+ $this->wheres[] = compact('type', 'column', 'operator', 'query', 'boolean');
+
+ $this->addBinding($query->getBindings(), 'where');
+
+ return $this;
+ }
+
+ /**
+ * Add an exists clause to the query.
+ *
+ * @param \Closure $callback
+ * @param string $boolean
+ * @param bool $not
+ * @return $this
+ */
+ public function whereExists(Closure $callback, $boolean = 'and', $not = false)
+ {
+ $type = $not ? 'NotExists' : 'Exists';
+
+ $query = $this->newQuery();
+
+ // Similar to the sub-select clause, we will create a new query instance so
+ // the developer may cleanly specify the entire exists query and we will
+ // compile the whole thing in the grammar and insert it into the SQL.
+ call_user_func($callback, $query);
+
+ $this->wheres[] = compact('type', 'operator', 'query', 'boolean');
+
+ $this->addBinding($query->getBindings(), 'where');
+
+ return $this;
+ }
+
+ /**
+ * Add an or exists clause to the query.
+ *
+ * @param \Closure $callback
+ * @param bool $not
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhereExists(Closure $callback, $not = false)
+ {
+ return $this->whereExists($callback, 'or', $not);
+ }
+
+ /**
+ * Add a where not exists clause to the query.
+ *
+ * @param \Closure $callback
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function whereNotExists(Closure $callback, $boolean = 'and')
+ {
+ return $this->whereExists($callback, $boolean, true);
+ }
+
+ /**
+ * Add a where not exists clause to the query.
+ *
+ * @param \Closure $callback
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhereNotExists(Closure $callback)
+ {
+ return $this->orWhereExists($callback, true);
+ }
+
+ /**
+ * Add a "where in" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $values
+ * @param string $boolean
+ * @param bool $not
+ * @return $this
+ */
+ public function whereIn($column, $values, $boolean = 'and', $not = false)
+ {
+ $type = $not ? 'NotIn' : 'In';
+
+ if ($values instanceof static) {
+ return $this->whereInExistingQuery(
+ $column, $values, $boolean, $not
+ );
+ }
+
+ // If the value of the where in clause is actually a Closure, we will assume that
+ // the developer is using a full sub-select for this "in" statement, and will
+ // execute those Closures, then we can re-construct the entire sub-selects.
+ if ($values instanceof Closure) {
+ return $this->whereInSub($column, $values, $boolean, $not);
+ }
+
+ if ($values instanceof Arrayable) {
+ $values = $values->toArray();
+ }
+
+ $this->wheres[] = compact('type', 'column', 'values', 'boolean');
+
+ $this->addBinding($values, 'where');
+
+ return $this;
+ }
+
+ /**
+ * Add an "or where in" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $values
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhereIn($column, $values)
+ {
+ return $this->whereIn($column, $values, 'or');
+ }
+
+ /**
+ * Add a "where not in" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $values
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function whereNotIn($column, $values, $boolean = 'and')
+ {
+ return $this->whereIn($column, $values, $boolean, true);
+ }
+
+ /**
+ * Add an "or where not in" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $values
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhereNotIn($column, $values)
+ {
+ return $this->whereNotIn($column, $values, 'or');
+ }
+
+ /**
+ * Add a where in with a sub-select to the query.
+ *
+ * @param string $column
+ * @param \Closure $callback
+ * @param string $boolean
+ * @param bool $not
+ * @return $this
+ */
+ protected function whereInSub($column, Closure $callback, $boolean, $not)
+ {
+ $type = $not ? 'NotInSub' : 'InSub';
+
+ // To create the exists sub-select, we will actually create a query and call the
+ // provided callback with the query so the developer may set any of the query
+ // conditions they want for the in clause, then we'll put it in this array.
+ call_user_func($callback, $query = $this->newQuery());
+
+ $this->wheres[] = compact('type', 'column', 'query', 'boolean');
+
+ $this->addBinding($query->getBindings(), 'where');
+
+ return $this;
+ }
+
+ /**
+ * Add a external sub-select to the query.
+ *
+ * @param string $column
+ * @param \Illuminate\Database\Query\Builder|static $query
+ * @param string $boolean
+ * @param bool $not
+ * @return $this
+ */
+ protected function whereInExistingQuery($column, $query, $boolean, $not)
+ {
+ $type = $not ? 'NotInSub' : 'InSub';
+
+ $this->wheres[] = compact('type', 'column', 'query', 'boolean');
+
+ $this->addBinding($query->getBindings(), 'where');
+
+ return $this;
+ }
+
+ /**
+ * Add a "where null" clause to the query.
+ *
+ * @param string $column
+ * @param string $boolean
+ * @param bool $not
+ * @return $this
+ */
+ public function whereNull($column, $boolean = 'and', $not = false)
+ {
+ $type = $not ? 'NotNull' : 'Null';
+
+ $this->wheres[] = compact('type', 'column', 'boolean');
+
+ return $this;
+ }
+
+ /**
+ * Add an "or where null" clause to the query.
+ *
+ * @param string $column
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhereNull($column)
+ {
+ return $this->whereNull($column, 'or');
+ }
+
+ /**
+ * Add a "where not null" clause to the query.
+ *
+ * @param string $column
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function whereNotNull($column, $boolean = 'and')
+ {
+ return $this->whereNull($column, $boolean, true);
+ }
+
+ /**
+ * Add an "or where not null" clause to the query.
+ *
+ * @param string $column
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhereNotNull($column)
+ {
+ return $this->whereNotNull($column, 'or');
+ }
+
+ /**
+ * Add a "where date" statement to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param int $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function whereDate($column, $operator, $value, $boolean = 'and')
+ {
+ return $this->addDateBasedWhere('Date', $column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add a "where day" statement to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param int $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function whereDay($column, $operator, $value, $boolean = 'and')
+ {
+ return $this->addDateBasedWhere('Day', $column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add a "where month" statement to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param int $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function whereMonth($column, $operator, $value, $boolean = 'and')
+ {
+ return $this->addDateBasedWhere('Month', $column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add a "where year" statement to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param int $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function whereYear($column, $operator, $value, $boolean = 'and')
+ {
+ return $this->addDateBasedWhere('Year', $column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add a date based (year, month, day) statement to the query.
+ *
+ * @param string $type
+ * @param string $column
+ * @param string $operator
+ * @param int $value
+ * @param string $boolean
+ * @return $this
+ */
+ protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and')
+ {
+ $this->wheres[] = compact('column', 'type', 'boolean', 'operator', 'value');
+
+ $this->addBinding($value, 'where');
+
+ return $this;
+ }
+
+ /**
+ * Handles dynamic "where" clauses to the query.
+ *
+ * @param string $method
+ * @param string $parameters
+ * @return $this
+ */
+ public function dynamicWhere($method, $parameters)
+ {
+ $finder = substr($method, 5);
+
+ $segments = preg_split('/(And|Or)(?=[A-Z])/', $finder, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+ // The connector variable will determine which connector will be used for the
+ // query condition. We will change it as we come across new boolean values
+ // in the dynamic method strings, which could contain a number of these.
+ $connector = 'and';
+
+ $index = 0;
+
+ foreach ($segments as $segment) {
+ // If the segment is not a boolean connector, we can assume it is a column's name
+ // and we will add it to the query as a new constraint as a where clause, then
+ // we can keep iterating through the dynamic method string's segments again.
+ if ($segment != 'And' && $segment != 'Or') {
+ $this->addDynamic($segment, $connector, $parameters, $index);
+
+ $index++;
+ }
+
+ // Otherwise, we will store the connector so we know how the next where clause we
+ // find in the query should be connected to the previous ones, meaning we will
+ // have the proper boolean connector to connect the next where clause found.
+ else {
+ $connector = $segment;
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a single dynamic where clause statement to the query.
+ *
+ * @param string $segment
+ * @param string $connector
+ * @param array $parameters
+ * @param int $index
+ * @return void
+ */
+ protected function addDynamic($segment, $connector, $parameters, $index)
+ {
+ // Once we have parsed out the columns and formatted the boolean operators we
+ // are ready to add it to this query as a where clause just like any other
+ // clause on the query. Then we'll increment the parameter index values.
+ $bool = strtolower($connector);
+
+ $this->where(Str::snake($segment), '=', $parameters[$index], $bool);
+ }
+
+ /**
+ * Add a "group by" clause to the query.
+ *
+ * @param array|string $column,...
+ * @return $this
+ */
+ public function groupBy()
+ {
+ foreach (func_get_args() as $arg) {
+ $this->groups = array_merge((array) $this->groups, is_array($arg) ? $arg : [$arg]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a "having" clause to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param string $value
+ * @param string $boolean
+ * @return $this
+ */
+ public function having($column, $operator = null, $value = null, $boolean = 'and')
+ {
+ $type = 'basic';
+
+ $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean');
+
+ if (! $value instanceof Expression) {
+ $this->addBinding($value, 'having');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a "or having" clause to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param string $value
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orHaving($column, $operator = null, $value = null)
+ {
+ return $this->having($column, $operator, $value, 'or');
+ }
+
+ /**
+ * Add a raw having clause to the query.
+ *
+ * @param string $sql
+ * @param array $bindings
+ * @param string $boolean
+ * @return $this
+ */
+ public function havingRaw($sql, array $bindings = [], $boolean = 'and')
+ {
+ $type = 'raw';
+
+ $this->havings[] = compact('type', 'sql', 'boolean');
+
+ $this->addBinding($bindings, 'having');
+
+ return $this;
+ }
+
+ /**
+ * Add a raw or having clause to the query.
+ *
+ * @param string $sql
+ * @param array $bindings
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orHavingRaw($sql, array $bindings = [])
+ {
+ return $this->havingRaw($sql, $bindings, 'or');
+ }
+
+ /**
+ * Add an "order by" clause to the query.
+ *
+ * @param string $column
+ * @param string $direction
+ * @return $this
+ */
+ public function orderBy($column, $direction = 'asc')
+ {
+ $property = $this->unions ? 'unionOrders' : 'orders';
+ $direction = strtolower($direction) == 'asc' ? 'asc' : 'desc';
+
+ $this->{$property}[] = compact('column', 'direction');
+
+ return $this;
+ }
+
+ /**
+ * Add an "order by" clause for a timestamp to the query.
+ *
+ * @param string $column
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function latest($column = 'created_at')
+ {
+ return $this->orderBy($column, 'desc');
+ }
+
+ /**
+ * Add an "order by" clause for a timestamp to the query.
+ *
+ * @param string $column
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function oldest($column = 'created_at')
+ {
+ return $this->orderBy($column, 'asc');
+ }
+
+ /**
+ * Add a raw "order by" clause to the query.
+ *
+ * @param string $sql
+ * @param array $bindings
+ * @return $this
+ */
+ public function orderByRaw($sql, $bindings = [])
+ {
+ $property = $this->unions ? 'unionOrders' : 'orders';
+
+ $type = 'raw';
+
+ $this->{$property}[] = compact('type', 'sql');
+
+ $this->addBinding($bindings, 'order');
+
+ return $this;
+ }
+
+ /**
+ * Set the "offset" value of the query.
+ *
+ * @param int $value
+ * @return $this
+ */
+ public function offset($value)
+ {
+ $property = $this->unions ? 'unionOffset' : 'offset';
+
+ $this->$property = max(0, $value);
+
+ return $this;
+ }
+
+ /**
+ * Alias to set the "offset" value of the query.
+ *
+ * @param int $value
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function skip($value)
+ {
+ return $this->offset($value);
+ }
+
+ /**
+ * Set the "limit" value of the query.
+ *
+ * @param int $value
+ * @return $this
+ */
+ public function limit($value)
+ {
+ $property = $this->unions ? 'unionLimit' : 'limit';
+
+ if ($value >= 0) {
+ $this->$property = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Alias to set the "limit" value of the query.
+ *
+ * @param int $value
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function take($value)
+ {
+ return $this->limit($value);
+ }
+
+ /**
+ * Set the limit and offset for a given page.
+ *
+ * @param int $page
+ * @param int $perPage
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function forPage($page, $perPage = 15)
+ {
+ return $this->skip(($page - 1) * $perPage)->take($perPage);
+ }
+
+ /**
+ * Add a union statement to the query.
+ *
+ * @param \Illuminate\Database\Query\Builder|\Closure $query
+ * @param bool $all
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function union($query, $all = false)
+ {
+ if ($query instanceof Closure) {
+ call_user_func($query, $query = $this->newQuery());
+ }
+
+ $this->unions[] = compact('query', 'all');
+
+ $this->addBinding($query->getBindings(), 'union');
+
+ return $this;
+ }
+
+ /**
+ * Add a union all statement to the query.
+ *
+ * @param \Illuminate\Database\Query\Builder|\Closure $query
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function unionAll($query)
+ {
+ return $this->union($query, true);
+ }
+
+ /**
+ * Lock the selected rows in the table.
+ *
+ * @param bool $value
+ * @return $this
+ */
+ public function lock($value = true)
+ {
+ $this->lock = $value;
+
+ if ($this->lock) {
+ $this->useWritePdo();
+ }
+
+ return $this;
+ }
+
+ /**
+ * Lock the selected rows in the table for updating.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public function lockForUpdate()
+ {
+ return $this->lock(true);
+ }
+
+ /**
+ * Share lock the selected rows in the table.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public function sharedLock()
+ {
+ return $this->lock(false);
+ }
+
+ /**
+ * Get the SQL representation of the query.
+ *
+ * @return string
+ */
+ public function toSql()
+ {
+ return $this->grammar->compileSelect($this);
+ }
+
+ /**
+ * Execute a query for a single record by ID.
+ *
+ * @param int $id
+ * @param array $columns
+ * @return mixed|static
+ */
+ public function find($id, $columns = ['*'])
+ {
+ return $this->where('id', '=', $id)->first($columns);
+ }
+
+ /**
+ * Get a single column's value from the first result of a query.
+ *
+ * @param string $column
+ * @return mixed
+ */
+ public function value($column)
+ {
+ $result = (array) $this->first([$column]);
+
+ return count($result) > 0 ? reset($result) : null;
+ }
+
+ /**
+ * Execute the query and get the first result.
+ *
+ * @param array $columns
+ * @return mixed|static
+ */
+ public function first($columns = ['*'])
+ {
+ $results = $this->take(1)->get($columns);
+
+ return count($results) > 0 ? reset($results) : null;
+ }
+
+ /**
+ * Execute the query as a "select" statement.
+ *
+ * @param array $columns
+ * @return array|static[]
+ */
+ public function get($columns = ['*'])
+ {
+ $original = $this->columns;
+
+ if (is_null($original)) {
+ $this->columns = $columns;
+ }
+
+ $results = $this->processor->processSelect($this, $this->runSelect());
+
+ $this->columns = $original;
+
+ return $results;
+ }
+
+ /**
+ * Run the query as a "select" statement against the connection.
+ *
+ * @return array
+ */
+ protected function runSelect()
+ {
+ return $this->connection->select($this->toSql(), $this->getBindings(), ! $this->useWritePdo);
+ }
+
+ /**
+ * Paginate the given query into a simple paginator.
+ *
+ * @param int $perPage
+ * @param array $columns
+ * @param string $pageName
+ * @param int|null $page
+ * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+ */
+ public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null)
+ {
+ $page = $page ?: Paginator::resolveCurrentPage($pageName);
+
+ $total = $this->getCountForPagination($columns);
+
+ $results = $this->forPage($page, $perPage)->get($columns);
+
+ return new LengthAwarePaginator($results, $total, $perPage, $page, [
+ 'path' => Paginator::resolveCurrentPath(),
+ 'pageName' => $pageName,
+ ]);
+ }
+
+ /**
+ * Get a paginator only supporting simple next and previous links.
+ *
+ * This is more efficient on larger data-sets, etc.
+ *
+ * @param int $perPage
+ * @param array $columns
+ * @param string $pageName
+ * @return \Illuminate\Contracts\Pagination\Paginator
+ */
+ public function simplePaginate($perPage = 15, $columns = ['*'], $pageName = 'page')
+ {
+ $page = Paginator::resolveCurrentPage($pageName);
+
+ $this->skip(($page - 1) * $perPage)->take($perPage + 1);
+
+ return new Paginator($this->get($columns), $perPage, $page, [
+ 'path' => Paginator::resolveCurrentPath(),
+ 'pageName' => $pageName,
+ ]);
+ }
+
+ /**
+ * Get the count of the total records for the paginator.
+ *
+ * @param array $columns
+ * @return int
+ */
+ public function getCountForPagination($columns = ['*'])
+ {
+ $this->backupFieldsForCount();
+
+ $this->aggregate = ['function' => 'count', 'columns' => $this->clearSelectAliases($columns)];
+
+ $results = $this->get();
+
+ $this->aggregate = null;
+
+ $this->restoreFieldsForCount();
+
+ if (isset($this->groups)) {
+ return count($results);
+ }
+
+ return isset($results[0]) ? (int) array_change_key_case((array) $results[0])['aggregate'] : 0;
+ }
+
+ /**
+ * Backup some fields for the pagination count.
+ *
+ * @return void
+ */
+ protected function backupFieldsForCount()
+ {
+ foreach (['orders', 'limit', 'offset', 'columns'] as $field) {
+ $this->backups[$field] = $this->{$field};
+
+ $this->{$field} = null;
+ }
+
+ foreach (['order', 'select'] as $key) {
+ $this->bindingBackups[$key] = $this->bindings[$key];
+
+ $this->bindings[$key] = [];
+ }
+ }
+
+ /**
+ * Remove the column aliases since they will break count queries.
+ *
+ * @param array $columns
+ * @return array
+ */
+ protected function clearSelectAliases(array $columns)
+ {
+ return array_map(function ($column) {
+ return is_string($column) && ($aliasPosition = strpos(strtolower($column), ' as ')) !== false
+ ? substr($column, 0, $aliasPosition) : $column;
+ }, $columns);
+ }
+
+ /**
+ * Restore some fields after the pagination count.
+ *
+ * @return void
+ */
+ protected function restoreFieldsForCount()
+ {
+ foreach (['orders', 'limit', 'offset', 'columns'] as $field) {
+ $this->{$field} = $this->backups[$field];
+ }
+
+ foreach (['order', 'select'] as $key) {
+ $this->bindings[$key] = $this->bindingBackups[$key];
+ }
+
+ $this->backups = [];
+ $this->bindingBackups = [];
+ }
+
+ /**
+ * Chunk the results of the query.
+ *
+ * @param int $count
+ * @param callable $callback
+ * @return bool
+ */
+ public function chunk($count, callable $callback)
+ {
+ $results = $this->forPage($page = 1, $count)->get();
+
+ while (count($results) > 0) {
+ // On each chunk result set, we will pass them to the callback and then let the
+ // developer take care of everything within the callback, which allows us to
+ // keep the memory low for spinning through large result sets for working.
+ if (call_user_func($callback, $results) === false) {
+ return false;
+ }
+
+ $page++;
+
+ $results = $this->forPage($page, $count)->get();
+ }
+
+ return true;
+ }
+
+ /**
+ * Get an array with the values of a given column.
+ *
+ * @param string $column
+ * @param string|null $key
+ * @return array
+ */
+ public function pluck($column, $key = null)
+ {
+ $results = $this->get(is_null($key) ? [$column] : [$column, $key]);
+
+ // If the columns are qualified with a table or have an alias, we cannot use
+ // those directly in the "pluck" operations since the results from the DB
+ // are only keyed by the column itself. We'll strip the table out here.
+ return Arr::pluck(
+ $results,
+ $this->stripeTableForPluck($column),
+ $this->stripeTableForPluck($key)
+ );
+ }
+
+ /**
+ * Alias for the "pluck" method.
+ *
+ * @param string $column
+ * @param string|null $key
+ * @return array
+ *
+ * @deprecated since version 5.2. Use the "pluck" method directly.
+ */
+ public function lists($column, $key = null)
+ {
+ return $this->pluck($column, $key);
+ }
+
+ /**
+ * Strip off the table name or alias from a column identifier.
+ *
+ * @param string $column
+ * @return string|null
+ */
+ protected function stripeTableForPluck($column)
+ {
+ return is_null($column) ? $column : last(preg_split('~\.| ~', $column));
+ }
+
+ /**
+ * Concatenate values of a given column as a string.
+ *
+ * @param string $column
+ * @param string $glue
+ * @return string
+ */
+ public function implode($column, $glue = '')
+ {
+ return implode($glue, $this->pluck($column));
+ }
+
+ /**
+ * Determine if any rows exist for the current query.
+ *
+ * @return bool
+ */
+ public function exists()
+ {
+ $sql = $this->grammar->compileExists($this);
+
+ $results = $this->connection->select($sql, $this->getBindings(), ! $this->useWritePdo);
+
+ if (isset($results[0])) {
+ $results = (array) $results[0];
+
+ return (bool) $results['exists'];
+ }
+
+ return false;
+ }
+
+ /**
+ * Retrieve the "count" result of the query.
+ *
+ * @param string $columns
+ * @return int
+ */
+ public function count($columns = '*')
+ {
+ if (! is_array($columns)) {
+ $columns = [$columns];
+ }
+
+ return (int) $this->aggregate(__FUNCTION__, $columns);
+ }
+
+ /**
+ * Retrieve the minimum value of a given column.
+ *
+ * @param string $column
+ * @return float|int
+ */
+ public function min($column)
+ {
+ return $this->aggregate(__FUNCTION__, [$column]);
+ }
+
+ /**
+ * Retrieve the maximum value of a given column.
+ *
+ * @param string $column
+ * @return float|int
+ */
+ public function max($column)
+ {
+ return $this->aggregate(__FUNCTION__, [$column]);
+ }
+
+ /**
+ * Retrieve the sum of the values of a given column.
+ *
+ * @param string $column
+ * @return float|int
+ */
+ public function sum($column)
+ {
+ $result = $this->aggregate(__FUNCTION__, [$column]);
+
+ return $result ?: 0;
+ }
+
+ /**
+ * Retrieve the average of the values of a given column.
+ *
+ * @param string $column
+ * @return float|int
+ */
+ public function avg($column)
+ {
+ return $this->aggregate(__FUNCTION__, [$column]);
+ }
+
+ /**
+ * Alias for the "avg" method.
+ *
+ * @param string $column
+ * @return float|int
+ */
+ public function average($column)
+ {
+ return $this->avg($column);
+ }
+
+ /**
+ * Execute an aggregate function on the database.
+ *
+ * @param string $function
+ * @param array $columns
+ * @return float|int
+ */
+ public function aggregate($function, $columns = ['*'])
+ {
+ $this->aggregate = compact('function', 'columns');
+
+ $previousColumns = $this->columns;
+
+ // We will also back up the select bindings since the select clause will be
+ // removed when performing the aggregate function. Once the query is run
+ // we will add the bindings back onto this query so they can get used.
+ $previousSelectBindings = $this->bindings['select'];
+
+ $this->bindings['select'] = [];
+
+ $results = $this->get($columns);
+
+ // Once we have executed the query, we will reset the aggregate property so
+ // that more select queries can be executed against the database without
+ // the aggregate value getting in the way when the grammar builds it.
+ $this->aggregate = null;
+
+ $this->columns = $previousColumns;
+
+ $this->bindings['select'] = $previousSelectBindings;
+
+ if (isset($results[0])) {
+ $result = array_change_key_case((array) $results[0]);
+
+ return $result['aggregate'];
+ }
+ }
+
+ /**
+ * Insert a new record into the database.
+ *
+ * @param array $values
+ * @return bool
+ */
+ public function insert(array $values)
+ {
+ if (empty($values)) {
+ return true;
+ }
+
+ // Since every insert gets treated like a batch insert, we will make sure the
+ // bindings are structured in a way that is convenient for building these
+ // inserts statements by verifying the elements are actually an array.
+ if (! is_array(reset($values))) {
+ $values = [$values];
+ }
+
+ // Since every insert gets treated like a batch insert, we will make sure the
+ // bindings are structured in a way that is convenient for building these
+ // inserts statements by verifying the elements are actually an array.
+ else {
+ foreach ($values as $key => $value) {
+ ksort($value);
+ $values[$key] = $value;
+ }
+ }
+
+ // We'll treat every insert like a batch insert so we can easily insert each
+ // of the records into the database consistently. This will make it much
+ // easier on the grammars to just handle one type of record insertion.
+ $bindings = [];
+
+ foreach ($values as $record) {
+ foreach ($record as $value) {
+ $bindings[] = $value;
+ }
+ }
+
+ $sql = $this->grammar->compileInsert($this, $values);
+
+ // Once we have compiled the insert statement's SQL we can execute it on the
+ // connection and return a result as a boolean success indicator as that
+ // is the same type of result returned by the raw connection instance.
+ $bindings = $this->cleanBindings($bindings);
+
+ return $this->connection->insert($sql, $bindings);
+ }
+
+ /**
+ * Insert a new record and get the value of the primary key.
+ *
+ * @param array $values
+ * @param string $sequence
+ * @return int
+ */
+ public function insertGetId(array $values, $sequence = null)
+ {
+ $sql = $this->grammar->compileInsertGetId($this, $values, $sequence);
+
+ $values = $this->cleanBindings($values);
+
+ return $this->processor->processInsertGetId($this, $sql, $values, $sequence);
+ }
+
+ /**
+ * Update a record in the database.
+ *
+ * @param array $values
+ * @return int
+ */
+ public function update(array $values)
+ {
+ $bindings = array_values(array_merge($values, $this->getBindings()));
+
+ $sql = $this->grammar->compileUpdate($this, $values);
+
+ return $this->connection->update($sql, $this->cleanBindings($bindings));
+ }
+
+ /**
+ * Increment a column's value by a given amount.
+ *
+ * @param string $column
+ * @param int $amount
+ * @param array $extra
+ * @return int
+ */
+ public function increment($column, $amount = 1, array $extra = [])
+ {
+ $wrapped = $this->grammar->wrap($column);
+
+ $columns = array_merge([$column => $this->raw("$wrapped + $amount")], $extra);
+
+ return $this->update($columns);
+ }
+
+ /**
+ * Decrement a column's value by a given amount.
+ *
+ * @param string $column
+ * @param int $amount
+ * @param array $extra
+ * @return int
+ */
+ public function decrement($column, $amount = 1, array $extra = [])
+ {
+ $wrapped = $this->grammar->wrap($column);
+
+ $columns = array_merge([$column => $this->raw("$wrapped - $amount")], $extra);
+
+ return $this->update($columns);
+ }
+
+ /**
+ * Delete a record from the database.
+ *
+ * @param mixed $id
+ * @return int
+ */
+ public function delete($id = null)
+ {
+ // If an ID is passed to the method, we will set the where clause to check
+ // the ID to allow developers to simply and quickly remove a single row
+ // from their database without manually specifying the where clauses.
+ if (! is_null($id)) {
+ $this->where('id', '=', $id);
+ }
+
+ $sql = $this->grammar->compileDelete($this);
+
+ return $this->connection->delete($sql, $this->getBindings());
+ }
+
+ /**
+ * Run a truncate statement on the table.
+ *
+ * @return void
+ */
+ public function truncate()
+ {
+ foreach ($this->grammar->compileTruncate($this) as $sql => $bindings) {
+ $this->connection->statement($sql, $bindings);
+ }
+ }
+
+ /**
+ * Get a new instance of the query builder.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ */
+ public function newQuery()
+ {
+ return new static($this->connection, $this->grammar, $this->processor);
+ }
+
+ /**
+ * Merge an array of where clauses and bindings.
+ *
+ * @param array $wheres
+ * @param array $bindings
+ * @return void
+ */
+ public function mergeWheres($wheres, $bindings)
+ {
+ $this->wheres = array_merge((array) $this->wheres, (array) $wheres);
+
+ $this->bindings['where'] = array_values(array_merge($this->bindings['where'], (array) $bindings));
+ }
+
+ /**
+ * Remove all of the expressions from a list of bindings.
+ *
+ * @param array $bindings
+ * @return array
+ */
+ protected function cleanBindings(array $bindings)
+ {
+ return array_values(array_filter($bindings, function ($binding) {
+ return ! $binding instanceof Expression;
+ }));
+ }
+
+ /**
+ * Create a raw database expression.
+ *
+ * @param mixed $value
+ * @return \Illuminate\Database\Query\Expression
+ */
+ public function raw($value)
+ {
+ return $this->connection->raw($value);
+ }
+
+ /**
+ * Get the current query value bindings in a flattened array.
+ *
+ * @return array
+ */
+ public function getBindings()
+ {
+ return Arr::flatten($this->bindings);
+ }
+
+ /**
+ * Get the raw array of bindings.
+ *
+ * @return array
+ */
+ public function getRawBindings()
+ {
+ return $this->bindings;
+ }
+
+ /**
+ * Set the bindings on the query builder.
+ *
+ * @param array $bindings
+ * @param string $type
+ * @return $this
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setBindings(array $bindings, $type = 'where')
+ {
+ if (! array_key_exists($type, $this->bindings)) {
+ throw new InvalidArgumentException("Invalid binding type: {$type}.");
+ }
+
+ $this->bindings[$type] = $bindings;
+
+ return $this;
+ }
+
+ /**
+ * Add a binding to the query.
+ *
+ * @param mixed $value
+ * @param string $type
+ * @return $this
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function addBinding($value, $type = 'where')
+ {
+ if (! array_key_exists($type, $this->bindings)) {
+ throw new InvalidArgumentException("Invalid binding type: {$type}.");
+ }
+
+ if (is_array($value)) {
+ $this->bindings[$type] = array_values(array_merge($this->bindings[$type], $value));
+ } else {
+ $this->bindings[$type][] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Merge an array of bindings into our bindings.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return $this
+ */
+ public function mergeBindings(Builder $query)
+ {
+ $this->bindings = array_merge_recursive($this->bindings, $query->bindings);
+
+ return $this;
+ }
+
+ /**
+ * Get the database connection instance.
+ *
+ * @return \Illuminate\Database\ConnectionInterface
+ */
+ public function getConnection()
+ {
+ return $this->connection;
+ }
+
+ /**
+ * Get the database query processor instance.
+ *
+ * @return \Illuminate\Database\Query\Processors\Processor
+ */
+ public function getProcessor()
+ {
+ return $this->processor;
+ }
+
+ /**
+ * Get the query grammar instance.
+ *
+ * @return \Illuminate\Database\Query\Grammars\Grammar
+ */
+ public function getGrammar()
+ {
+ return $this->grammar;
+ }
+
+ /**
+ * Use the write pdo for query.
+ *
+ * @return $this
+ */
+ public function useWritePdo()
+ {
+ $this->useWritePdo = true;
+
+ return $this;
+ }
+
+ /**
+ * Handle dynamic method calls into the method.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __call($method, $parameters)
+ {
+ if (static::hasMacro($method)) {
+ return $this->macroCall($method, $parameters);
+ }
+
+ if (Str::startsWith($method, 'where')) {
+ return $this->dynamicWhere($method, $parameters);
+ }
+
+ $className = get_class($this);
+
+ throw new BadMethodCallException("Call to undefined method {$className}::{$method}()");
+ }
+}
diff --git a/vendor/illuminate/database/Query/Expression.php b/vendor/illuminate/database/Query/Expression.php
new file mode 100755
index 00000000..de690299
--- /dev/null
+++ b/vendor/illuminate/database/Query/Expression.php
@@ -0,0 +1,44 @@
+value = $value;
+ }
+
+ /**
+ * Get the value of the expression.
+ *
+ * @return mixed
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Get the value of the expression.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return (string) $this->getValue();
+ }
+}
diff --git a/vendor/illuminate/database/Query/Grammars/Grammar.php b/vendor/illuminate/database/Query/Grammars/Grammar.php
new file mode 100755
index 00000000..d596ad01
--- /dev/null
+++ b/vendor/illuminate/database/Query/Grammars/Grammar.php
@@ -0,0 +1,831 @@
+columns;
+
+ if (is_null($query->columns)) {
+ $query->columns = ['*'];
+ }
+
+ $sql = trim($this->concatenate($this->compileComponents($query)));
+
+ $query->columns = $original;
+
+ return $sql;
+ }
+
+ /**
+ * Compile the components necessary for a select clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return array
+ */
+ protected function compileComponents(Builder $query)
+ {
+ $sql = [];
+
+ foreach ($this->selectComponents as $component) {
+ // To compile the query, we'll spin through each component of the query and
+ // see if that component exists. If it does we'll just call the compiler
+ // function for the component which is responsible for making the SQL.
+ if (! is_null($query->$component)) {
+ $method = 'compile'.ucfirst($component);
+
+ $sql[$component] = $this->$method($query, $query->$component);
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Compile an aggregated select clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $aggregate
+ * @return string
+ */
+ protected function compileAggregate(Builder $query, $aggregate)
+ {
+ $column = $this->columnize($aggregate['columns']);
+
+ // If the query has a "distinct" constraint and we're not asking for all columns
+ // we need to prepend "distinct" onto the column name so that the query takes
+ // it into account when it performs the aggregating operations on the data.
+ if ($query->distinct && $column !== '*') {
+ $column = 'distinct '.$column;
+ }
+
+ return 'select '.$aggregate['function'].'('.$column.') as aggregate';
+ }
+
+ /**
+ * Compile the "select *" portion of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $columns
+ * @return string|null
+ */
+ protected function compileColumns(Builder $query, $columns)
+ {
+ // If the query is actually performing an aggregating select, we will let that
+ // compiler handle the building of the select clauses, as it will need some
+ // more syntax that is best handled by that function to keep things neat.
+ if (! is_null($query->aggregate)) {
+ return;
+ }
+
+ $select = $query->distinct ? 'select distinct ' : 'select ';
+
+ return $select.$this->columnize($columns);
+ }
+
+ /**
+ * Compile the "from" portion of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param string $table
+ * @return string
+ */
+ protected function compileFrom(Builder $query, $table)
+ {
+ return 'from '.$this->wrapTable($table);
+ }
+
+ /**
+ * Compile the "join" portions of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $joins
+ * @return string
+ */
+ protected function compileJoins(Builder $query, $joins)
+ {
+ $sql = [];
+
+ foreach ($joins as $join) {
+ $table = $this->wrapTable($join->table);
+
+ // First we need to build all of the "on" clauses for the join. There may be many
+ // of these clauses so we will need to iterate through each one and build them
+ // separately, then we'll join them up into a single string when we're done.
+ $clauses = [];
+
+ foreach ($join->clauses as $clause) {
+ $clauses[] = $this->compileJoinConstraint($clause);
+ }
+
+ // Once we have constructed the clauses, we'll need to take the boolean connector
+ // off of the first clause as it obviously will not be required on that clause
+ // because it leads the rest of the clauses, thus not requiring any boolean.
+ $clauses[0] = $this->removeLeadingBoolean($clauses[0]);
+
+ $clauses = implode(' ', $clauses);
+
+ $type = $join->type;
+
+ // Once we have everything ready to go, we will just concatenate all the parts to
+ // build the final join statement SQL for the query and we can then return the
+ // final clause back to the callers as a single, stringified join statement.
+ $sql[] = "$type join $table on $clauses";
+ }
+
+ return implode(' ', $sql);
+ }
+
+ /**
+ * Create a join clause constraint segment.
+ *
+ * @param array $clause
+ * @return string
+ */
+ protected function compileJoinConstraint(array $clause)
+ {
+ if ($clause['nested']) {
+ return $this->compileNestedJoinConstraint($clause);
+ }
+
+ $first = $this->wrap($clause['first']);
+
+ if ($clause['where']) {
+ if ($clause['operator'] === 'in' || $clause['operator'] === 'not in') {
+ $second = '('.implode(', ', array_fill(0, $clause['second'], '?')).')';
+ } else {
+ $second = '?';
+ }
+ } else {
+ $second = $this->wrap($clause['second']);
+ }
+
+ return "{$clause['boolean']} $first {$clause['operator']} $second";
+ }
+
+ /**
+ * Create a nested join clause constraint segment.
+ *
+ * @param array $clause
+ * @return string
+ */
+ protected function compileNestedJoinConstraint(array $clause)
+ {
+ $clauses = [];
+
+ foreach ($clause['join']->clauses as $nestedClause) {
+ $clauses[] = $this->compileJoinConstraint($nestedClause);
+ }
+
+ $clauses[0] = $this->removeLeadingBoolean($clauses[0]);
+
+ $clauses = implode(' ', $clauses);
+
+ return "{$clause['boolean']} ({$clauses})";
+ }
+
+ /**
+ * Compile the "where" portions of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string
+ */
+ protected function compileWheres(Builder $query)
+ {
+ $sql = [];
+
+ if (is_null($query->wheres)) {
+ return '';
+ }
+
+ // Each type of where clauses has its own compiler function which is responsible
+ // for actually creating the where clauses SQL. This helps keep the code nice
+ // and maintainable since each clause has a very small method that it uses.
+ foreach ($query->wheres as $where) {
+ $method = "where{$where['type']}";
+
+ $sql[] = $where['boolean'].' '.$this->$method($query, $where);
+ }
+
+ // If we actually have some where clauses, we will strip off the first boolean
+ // operator, which is added by the query builders for convenience so we can
+ // avoid checking for the first clauses in each of the compilers methods.
+ if (count($sql) > 0) {
+ $sql = implode(' ', $sql);
+
+ return 'where '.$this->removeLeadingBoolean($sql);
+ }
+
+ return '';
+ }
+
+ /**
+ * Compile a nested where clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereNested(Builder $query, $where)
+ {
+ $nested = $where['query'];
+
+ return '('.substr($this->compileWheres($nested), 6).')';
+ }
+
+ /**
+ * Compile a where condition with a sub-select.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereSub(Builder $query, $where)
+ {
+ $select = $this->compileSelect($where['query']);
+
+ return $this->wrap($where['column']).' '.$where['operator']." ($select)";
+ }
+
+ /**
+ * Compile a basic where clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereBasic(Builder $query, $where)
+ {
+ $value = $this->parameter($where['value']);
+
+ return $this->wrap($where['column']).' '.$where['operator'].' '.$value;
+ }
+
+ /**
+ * Compile a "between" where clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereBetween(Builder $query, $where)
+ {
+ $between = $where['not'] ? 'not between' : 'between';
+
+ return $this->wrap($where['column']).' '.$between.' ? and ?';
+ }
+
+ /**
+ * Compile a where exists clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereExists(Builder $query, $where)
+ {
+ return 'exists ('.$this->compileSelect($where['query']).')';
+ }
+
+ /**
+ * Compile a where exists clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereNotExists(Builder $query, $where)
+ {
+ return 'not exists ('.$this->compileSelect($where['query']).')';
+ }
+
+ /**
+ * Compile a "where in" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereIn(Builder $query, $where)
+ {
+ if (empty($where['values'])) {
+ return '0 = 1';
+ }
+
+ $values = $this->parameterize($where['values']);
+
+ return $this->wrap($where['column']).' in ('.$values.')';
+ }
+
+ /**
+ * Compile a "where not in" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereNotIn(Builder $query, $where)
+ {
+ if (empty($where['values'])) {
+ return '1 = 1';
+ }
+
+ $values = $this->parameterize($where['values']);
+
+ return $this->wrap($where['column']).' not in ('.$values.')';
+ }
+
+ /**
+ * Compile a where in sub-select clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereInSub(Builder $query, $where)
+ {
+ $select = $this->compileSelect($where['query']);
+
+ return $this->wrap($where['column']).' in ('.$select.')';
+ }
+
+ /**
+ * Compile a where not in sub-select clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereNotInSub(Builder $query, $where)
+ {
+ $select = $this->compileSelect($where['query']);
+
+ return $this->wrap($where['column']).' not in ('.$select.')';
+ }
+
+ /**
+ * Compile a "where null" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereNull(Builder $query, $where)
+ {
+ return $this->wrap($where['column']).' is null';
+ }
+
+ /**
+ * Compile a "where not null" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereNotNull(Builder $query, $where)
+ {
+ return $this->wrap($where['column']).' is not null';
+ }
+
+ /**
+ * Compile a "where date" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereDate(Builder $query, $where)
+ {
+ return $this->dateBasedWhere('date', $query, $where);
+ }
+
+ /**
+ * Compile a "where day" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereDay(Builder $query, $where)
+ {
+ return $this->dateBasedWhere('day', $query, $where);
+ }
+
+ /**
+ * Compile a "where month" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereMonth(Builder $query, $where)
+ {
+ return $this->dateBasedWhere('month', $query, $where);
+ }
+
+ /**
+ * Compile a "where year" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereYear(Builder $query, $where)
+ {
+ return $this->dateBasedWhere('year', $query, $where);
+ }
+
+ /**
+ * Compile a date based where clause.
+ *
+ * @param string $type
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function dateBasedWhere($type, Builder $query, $where)
+ {
+ $value = $this->parameter($where['value']);
+
+ return $type.'('.$this->wrap($where['column']).') '.$where['operator'].' '.$value;
+ }
+
+ /**
+ * Compile a raw where clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereRaw(Builder $query, $where)
+ {
+ return $where['sql'];
+ }
+
+ /**
+ * Compile the "group by" portions of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $groups
+ * @return string
+ */
+ protected function compileGroups(Builder $query, $groups)
+ {
+ return 'group by '.$this->columnize($groups);
+ }
+
+ /**
+ * Compile the "having" portions of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $havings
+ * @return string
+ */
+ protected function compileHavings(Builder $query, $havings)
+ {
+ $sql = implode(' ', array_map([$this, 'compileHaving'], $havings));
+
+ return 'having '.$this->removeLeadingBoolean($sql);
+ }
+
+ /**
+ * Compile a single having clause.
+ *
+ * @param array $having
+ * @return string
+ */
+ protected function compileHaving(array $having)
+ {
+ // If the having clause is "raw", we can just return the clause straight away
+ // without doing any more processing on it. Otherwise, we will compile the
+ // clause into SQL based on the components that make it up from builder.
+ if ($having['type'] === 'raw') {
+ return $having['boolean'].' '.$having['sql'];
+ }
+
+ return $this->compileBasicHaving($having);
+ }
+
+ /**
+ * Compile a basic having clause.
+ *
+ * @param array $having
+ * @return string
+ */
+ protected function compileBasicHaving($having)
+ {
+ $column = $this->wrap($having['column']);
+
+ $parameter = $this->parameter($having['value']);
+
+ return $having['boolean'].' '.$column.' '.$having['operator'].' '.$parameter;
+ }
+
+ /**
+ * Compile the "order by" portions of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $orders
+ * @return string
+ */
+ protected function compileOrders(Builder $query, $orders)
+ {
+ return 'order by '.implode(', ', array_map(function ($order) {
+ if (isset($order['sql'])) {
+ return $order['sql'];
+ }
+
+ return $this->wrap($order['column']).' '.$order['direction'];
+ }, $orders));
+ }
+
+ /**
+ * Compile the "limit" portions of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param int $limit
+ * @return string
+ */
+ protected function compileLimit(Builder $query, $limit)
+ {
+ return 'limit '.(int) $limit;
+ }
+
+ /**
+ * Compile the "offset" portions of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param int $offset
+ * @return string
+ */
+ protected function compileOffset(Builder $query, $offset)
+ {
+ return 'offset '.(int) $offset;
+ }
+
+ /**
+ * Compile the "union" queries attached to the main query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string
+ */
+ protected function compileUnions(Builder $query)
+ {
+ $sql = '';
+
+ foreach ($query->unions as $union) {
+ $sql .= $this->compileUnion($union);
+ }
+
+ if (isset($query->unionOrders)) {
+ $sql .= ' '.$this->compileOrders($query, $query->unionOrders);
+ }
+
+ if (isset($query->unionLimit)) {
+ $sql .= ' '.$this->compileLimit($query, $query->unionLimit);
+ }
+
+ if (isset($query->unionOffset)) {
+ $sql .= ' '.$this->compileOffset($query, $query->unionOffset);
+ }
+
+ return ltrim($sql);
+ }
+
+ /**
+ * Compile a single union statement.
+ *
+ * @param array $union
+ * @return string
+ */
+ protected function compileUnion(array $union)
+ {
+ $joiner = $union['all'] ? ' union all ' : ' union ';
+
+ return $joiner.$union['query']->toSql();
+ }
+
+ /**
+ * Compile an exists statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string
+ */
+ public function compileExists(Builder $query)
+ {
+ $select = $this->compileSelect($query);
+
+ return "select exists($select) as {$this->wrap('exists')}";
+ }
+
+ /**
+ * Compile an insert statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $values
+ * @return string
+ */
+ public function compileInsert(Builder $query, array $values)
+ {
+ // Essentially we will force every insert to be treated as a batch insert which
+ // simply makes creating the SQL easier for us since we can utilize the same
+ // basic routine regardless of an amount of records given to us to insert.
+ $table = $this->wrapTable($query->from);
+
+ if (! is_array(reset($values))) {
+ $values = [$values];
+ }
+
+ $columns = $this->columnize(array_keys(reset($values)));
+
+ // We need to build a list of parameter place-holders of values that are bound
+ // to the query. Each insert should have the exact same amount of parameter
+ // bindings so we will loop through the record and parameterize them all.
+ $parameters = [];
+
+ foreach ($values as $record) {
+ $parameters[] = '('.$this->parameterize($record).')';
+ }
+
+ $parameters = implode(', ', $parameters);
+
+ return "insert into $table ($columns) values $parameters";
+ }
+
+ /**
+ * Compile an insert and get ID statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $values
+ * @param string $sequence
+ * @return string
+ */
+ public function compileInsertGetId(Builder $query, $values, $sequence)
+ {
+ return $this->compileInsert($query, $values);
+ }
+
+ /**
+ * Compile an update statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $values
+ * @return string
+ */
+ public function compileUpdate(Builder $query, $values)
+ {
+ $table = $this->wrapTable($query->from);
+
+ // Each one of the columns in the update statements needs to be wrapped in the
+ // keyword identifiers, also a place-holder needs to be created for each of
+ // the values in the list of bindings so we can make the sets statements.
+ $columns = [];
+
+ foreach ($values as $key => $value) {
+ $columns[] = $this->wrap($key).' = '.$this->parameter($value);
+ }
+
+ $columns = implode(', ', $columns);
+
+ // If the query has any "join" clauses, we will setup the joins on the builder
+ // and compile them so we can attach them to this update, as update queries
+ // can get join statements to attach to other tables when they're needed.
+ if (isset($query->joins)) {
+ $joins = ' '.$this->compileJoins($query, $query->joins);
+ } else {
+ $joins = '';
+ }
+
+ // Of course, update queries may also be constrained by where clauses so we'll
+ // need to compile the where clauses and attach it to the query so only the
+ // intended records are updated by the SQL statements we generate to run.
+ $where = $this->compileWheres($query);
+
+ return trim("update {$table}{$joins} set $columns $where");
+ }
+
+ /**
+ * Compile a delete statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string
+ */
+ public function compileDelete(Builder $query)
+ {
+ $table = $this->wrapTable($query->from);
+
+ $where = is_array($query->wheres) ? $this->compileWheres($query) : '';
+
+ return trim("delete from $table ".$where);
+ }
+
+ /**
+ * Compile a truncate table statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return array
+ */
+ public function compileTruncate(Builder $query)
+ {
+ return ['truncate '.$this->wrapTable($query->from) => []];
+ }
+
+ /**
+ * Compile the lock into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param bool|string $value
+ * @return string
+ */
+ protected function compileLock(Builder $query, $value)
+ {
+ return is_string($value) ? $value : '';
+ }
+
+ /**
+ * Determine if the grammar supports savepoints.
+ *
+ * @return bool
+ */
+ public function supportsSavepoints()
+ {
+ return true;
+ }
+
+ /**
+ * Compile the SQL statement to define a savepoint.
+ *
+ * @param string $name
+ * @return string
+ */
+ public function compileSavepoint($name)
+ {
+ return 'SAVEPOINT '.$name;
+ }
+
+ /**
+ * Compile the SQL statement to execute a savepoint rollback.
+ *
+ * @param string $name
+ * @return string
+ */
+ public function compileSavepointRollBack($name)
+ {
+ return 'ROLLBACK TO SAVEPOINT '.$name;
+ }
+
+ /**
+ * Concatenate an array of segments, removing empties.
+ *
+ * @param array $segments
+ * @return string
+ */
+ protected function concatenate($segments)
+ {
+ return implode(' ', array_filter($segments, function ($value) {
+ return (string) $value !== '';
+ }));
+ }
+
+ /**
+ * Remove the leading boolean from a statement.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function removeLeadingBoolean($value)
+ {
+ return preg_replace('/and |or /i', '', $value, 1);
+ }
+}
diff --git a/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php b/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php
new file mode 100755
index 00000000..41f5c85a
--- /dev/null
+++ b/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php
@@ -0,0 +1,141 @@
+unions) {
+ $sql = '('.$sql.') '.$this->compileUnions($query);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Compile a single union statement.
+ *
+ * @param array $union
+ * @return string
+ */
+ protected function compileUnion(array $union)
+ {
+ $joiner = $union['all'] ? ' union all ' : ' union ';
+
+ return $joiner.'('.$union['query']->toSql().')';
+ }
+
+ /**
+ * Compile the lock into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param bool|string $value
+ * @return string
+ */
+ protected function compileLock(Builder $query, $value)
+ {
+ if (is_string($value)) {
+ return $value;
+ }
+
+ return $value ? 'for update' : 'lock in share mode';
+ }
+
+ /**
+ * Compile an update statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $values
+ * @return string
+ */
+ public function compileUpdate(Builder $query, $values)
+ {
+ $sql = parent::compileUpdate($query, $values);
+
+ if (isset($query->orders)) {
+ $sql .= ' '.$this->compileOrders($query, $query->orders);
+ }
+
+ if (isset($query->limit)) {
+ $sql .= ' '.$this->compileLimit($query, $query->limit);
+ }
+
+ return rtrim($sql);
+ }
+
+ /**
+ * Compile a delete statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string
+ */
+ public function compileDelete(Builder $query)
+ {
+ $table = $this->wrapTable($query->from);
+
+ $where = is_array($query->wheres) ? $this->compileWheres($query) : '';
+
+ if (isset($query->joins)) {
+ $joins = ' '.$this->compileJoins($query, $query->joins);
+
+ $sql = trim("delete $table from {$table}{$joins} $where");
+ } else {
+ $sql = trim("delete from $table $where");
+ }
+
+ if (isset($query->orders)) {
+ $sql .= ' '.$this->compileOrders($query, $query->orders);
+ }
+
+ if (isset($query->limit)) {
+ $sql .= ' '.$this->compileLimit($query, $query->limit);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Wrap a single string in keyword identifiers.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function wrapValue($value)
+ {
+ if ($value === '*') {
+ return $value;
+ }
+
+ return '`'.str_replace('`', '``', $value).'`';
+ }
+}
diff --git a/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php b/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php
new file mode 100755
index 00000000..2c8f5534
--- /dev/null
+++ b/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php
@@ -0,0 +1,180 @@
+', '<=', '>=', '<>', '!=',
+ 'like', 'not like', 'between', 'ilike',
+ '&', '|', '#', '<<', '>>',
+ ];
+
+ /**
+ * Compile the lock into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param bool|string $value
+ * @return string
+ */
+ protected function compileLock(Builder $query, $value)
+ {
+ if (is_string($value)) {
+ return $value;
+ }
+
+ return $value ? 'for update' : 'for share';
+ }
+
+ /**
+ * Compile an update statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $values
+ * @return string
+ */
+ public function compileUpdate(Builder $query, $values)
+ {
+ $table = $this->wrapTable($query->from);
+
+ // Each one of the columns in the update statements needs to be wrapped in the
+ // keyword identifiers, also a place-holder needs to be created for each of
+ // the values in the list of bindings so we can make the sets statements.
+ $columns = $this->compileUpdateColumns($values);
+
+ $from = $this->compileUpdateFrom($query);
+
+ $where = $this->compileUpdateWheres($query);
+
+ return trim("update {$table} set {$columns}{$from} $where");
+ }
+
+ /**
+ * Compile the columns for the update statement.
+ *
+ * @param array $values
+ * @return string
+ */
+ protected function compileUpdateColumns($values)
+ {
+ $columns = [];
+
+ // When gathering the columns for an update statement, we'll wrap each of the
+ // columns and convert it to a parameter value. Then we will concatenate a
+ // list of the columns that can be added into this update query clauses.
+ foreach ($values as $key => $value) {
+ $columns[] = $this->wrap($key).' = '.$this->parameter($value);
+ }
+
+ return implode(', ', $columns);
+ }
+
+ /**
+ * Compile the "from" clause for an update with a join.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string|null
+ */
+ protected function compileUpdateFrom(Builder $query)
+ {
+ if (! isset($query->joins)) {
+ return '';
+ }
+
+ $froms = [];
+
+ // When using Postgres, updates with joins list the joined tables in the from
+ // clause, which is different than other systems like MySQL. Here, we will
+ // compile out the tables that are joined and add them to a from clause.
+ foreach ($query->joins as $join) {
+ $froms[] = $this->wrapTable($join->table);
+ }
+
+ if (count($froms) > 0) {
+ return ' from '.implode(', ', $froms);
+ }
+ }
+
+ /**
+ * Compile the additional where clauses for updates with joins.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string
+ */
+ protected function compileUpdateWheres(Builder $query)
+ {
+ $baseWhere = $this->compileWheres($query);
+
+ if (! isset($query->joins)) {
+ return $baseWhere;
+ }
+
+ // Once we compile the join constraints, we will either use them as the where
+ // clause or append them to the existing base where clauses. If we need to
+ // strip the leading boolean we will do so when using as the only where.
+ $joinWhere = $this->compileUpdateJoinWheres($query);
+
+ if (trim($baseWhere) == '') {
+ return 'where '.$this->removeLeadingBoolean($joinWhere);
+ }
+
+ return $baseWhere.' '.$joinWhere;
+ }
+
+ /**
+ * Compile the "join" clauses for an update.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string
+ */
+ protected function compileUpdateJoinWheres(Builder $query)
+ {
+ $joinWheres = [];
+
+ // Here we will just loop through all of the join constraints and compile them
+ // all out then implode them. This should give us "where" like syntax after
+ // everything has been built and then we will join it to the real wheres.
+ foreach ($query->joins as $join) {
+ foreach ($join->clauses as $clause) {
+ $joinWheres[] = $this->compileJoinConstraint($clause);
+ }
+ }
+
+ return implode(' ', $joinWheres);
+ }
+
+ /**
+ * Compile an insert and get ID statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $values
+ * @param string $sequence
+ * @return string
+ */
+ public function compileInsertGetId(Builder $query, $values, $sequence)
+ {
+ if (is_null($sequence)) {
+ $sequence = 'id';
+ }
+
+ return $this->compileInsert($query, $values).' returning '.$this->wrap($sequence);
+ }
+
+ /**
+ * Compile a truncate table statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return array
+ */
+ public function compileTruncate(Builder $query)
+ {
+ return ['truncate '.$this->wrapTable($query->from).' restart identity' => []];
+ }
+}
diff --git a/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php b/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php
new file mode 100755
index 00000000..dd1f9c00
--- /dev/null
+++ b/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php
@@ -0,0 +1,140 @@
+', '<=', '>=', '<>', '!=',
+ 'like', 'not like', 'between', 'ilike',
+ '&', '|', '<<', '>>',
+ ];
+
+ /**
+ * Compile an insert statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $values
+ * @return string
+ */
+ public function compileInsert(Builder $query, array $values)
+ {
+ // Essentially we will force every insert to be treated as a batch insert which
+ // simply makes creating the SQL easier for us since we can utilize the same
+ // basic routine regardless of an amount of records given to us to insert.
+ $table = $this->wrapTable($query->from);
+
+ if (! is_array(reset($values))) {
+ $values = [$values];
+ }
+
+ // If there is only one record being inserted, we will just use the usual query
+ // grammar insert builder because no special syntax is needed for the single
+ // row inserts in SQLite. However, if there are multiples, we'll continue.
+ if (count($values) == 1) {
+ return parent::compileInsert($query, reset($values));
+ }
+
+ $names = $this->columnize(array_keys(reset($values)));
+
+ $columns = [];
+
+ // SQLite requires us to build the multi-row insert as a listing of select with
+ // unions joining them together. So we'll build out this list of columns and
+ // then join them all together with select unions to complete the queries.
+ foreach (array_keys(reset($values)) as $column) {
+ $columns[] = '? as '.$this->wrap($column);
+ }
+
+ $columns = array_fill(0, count($values), implode(', ', $columns));
+
+ return "insert into $table ($names) select ".implode(' union all select ', $columns);
+ }
+
+ /**
+ * Compile a truncate table statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return array
+ */
+ public function compileTruncate(Builder $query)
+ {
+ $sql = ['delete from sqlite_sequence where name = ?' => [$query->from]];
+
+ $sql['delete from '.$this->wrapTable($query->from)] = [];
+
+ return $sql;
+ }
+
+ /**
+ * Compile a "where date" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereDate(Builder $query, $where)
+ {
+ return $this->dateBasedWhere('%Y-%m-%d', $query, $where);
+ }
+
+ /**
+ * Compile a "where day" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereDay(Builder $query, $where)
+ {
+ return $this->dateBasedWhere('%d', $query, $where);
+ }
+
+ /**
+ * Compile a "where month" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereMonth(Builder $query, $where)
+ {
+ return $this->dateBasedWhere('%m', $query, $where);
+ }
+
+ /**
+ * Compile a "where year" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereYear(Builder $query, $where)
+ {
+ return $this->dateBasedWhere('%Y', $query, $where);
+ }
+
+ /**
+ * Compile a date based where clause.
+ *
+ * @param string $type
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function dateBasedWhere($type, Builder $query, $where)
+ {
+ $value = str_pad($where['value'], 2, '0', STR_PAD_LEFT);
+
+ $value = $this->parameter($value);
+
+ return 'strftime(\''.$type.'\', '.$this->wrap($where['column']).') '.$where['operator'].' '.$value;
+ }
+}
diff --git a/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php b/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php
new file mode 100755
index 00000000..6b54d1f7
--- /dev/null
+++ b/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php
@@ -0,0 +1,324 @@
+', '<=', '>=', '!<', '!>', '<>', '!=',
+ 'like', 'not like', 'between', 'ilike',
+ '&', '&=', '|', '|=', '^', '^=',
+ ];
+
+ /**
+ * Compile a select query into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string
+ */
+ public function compileSelect(Builder $query)
+ {
+ $original = $query->columns;
+
+ if (is_null($query->columns)) {
+ $query->columns = ['*'];
+ }
+
+ $components = $this->compileComponents($query);
+
+ // If an offset is present on the query, we will need to wrap the query in
+ // a big "ANSI" offset syntax block. This is very nasty compared to the
+ // other database systems but is necessary for implementing features.
+ if ($query->offset > 0) {
+ return $this->compileAnsiOffset($query, $components);
+ }
+
+ $sql = $this->concatenate($components);
+
+ $query->columns = $original;
+
+ return $sql;
+ }
+
+ /**
+ * Compile the "select *" portion of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $columns
+ * @return string|null
+ */
+ protected function compileColumns(Builder $query, $columns)
+ {
+ if (! is_null($query->aggregate)) {
+ return;
+ }
+
+ $select = $query->distinct ? 'select distinct ' : 'select ';
+
+ // If there is a limit on the query, but not an offset, we will add the top
+ // clause to the query, which serves as a "limit" type clause within the
+ // SQL Server system similar to the limit keywords available in MySQL.
+ if ($query->limit > 0 && $query->offset <= 0) {
+ $select .= 'top '.$query->limit.' ';
+ }
+
+ return $select.$this->columnize($columns);
+ }
+
+ /**
+ * Compile the "from" portion of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param string $table
+ * @return string
+ */
+ protected function compileFrom(Builder $query, $table)
+ {
+ $from = parent::compileFrom($query, $table);
+
+ if (is_string($query->lock)) {
+ return $from.' '.$query->lock;
+ }
+
+ if (! is_null($query->lock)) {
+ return $from.' with(rowlock,'.($query->lock ? 'updlock,' : '').'holdlock)';
+ }
+
+ return $from;
+ }
+
+ /**
+ * Create a full ANSI offset clause for the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $components
+ * @return string
+ */
+ protected function compileAnsiOffset(Builder $query, $components)
+ {
+ // An ORDER BY clause is required to make this offset query work, so if one does
+ // not exist we'll just create a dummy clause to trick the database and so it
+ // does not complain about the queries for not having an "order by" clause.
+ if (! isset($components['orders'])) {
+ $components['orders'] = 'order by (select 0)';
+ }
+
+ // We need to add the row number to the query so we can compare it to the offset
+ // and limit values given for the statements. So we will add an expression to
+ // the "select" that will give back the row numbers on each of the records.
+ $orderings = $components['orders'];
+
+ $components['columns'] .= $this->compileOver($orderings);
+
+ unset($components['orders']);
+
+ // Next we need to calculate the constraints that should be placed on the query
+ // to get the right offset and limit from our query but if there is no limit
+ // set we will just handle the offset only since that is all that matters.
+ $constraint = $this->compileRowConstraint($query);
+
+ $sql = $this->concatenate($components);
+
+ // We are now ready to build the final SQL query so we'll create a common table
+ // expression from the query and get the records with row numbers within our
+ // given limit and offset value that we just put on as a query constraint.
+ return $this->compileTableExpression($sql, $constraint);
+ }
+
+ /**
+ * Compile the over statement for a table expression.
+ *
+ * @param string $orderings
+ * @return string
+ */
+ protected function compileOver($orderings)
+ {
+ return ", row_number() over ({$orderings}) as row_num";
+ }
+
+ /**
+ * Compile the limit / offset row constraint for a query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string
+ */
+ protected function compileRowConstraint($query)
+ {
+ $start = $query->offset + 1;
+
+ if ($query->limit > 0) {
+ $finish = $query->offset + $query->limit;
+
+ return "between {$start} and {$finish}";
+ }
+
+ return ">= {$start}";
+ }
+
+ /**
+ * Compile a common table expression for a query.
+ *
+ * @param string $sql
+ * @param string $constraint
+ * @return string
+ */
+ protected function compileTableExpression($sql, $constraint)
+ {
+ return "select * from ({$sql}) as temp_table where row_num {$constraint}";
+ }
+
+ /**
+ * Compile the "limit" portions of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param int $limit
+ * @return string
+ */
+ protected function compileLimit(Builder $query, $limit)
+ {
+ return '';
+ }
+
+ /**
+ * Compile the "offset" portions of the query.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param int $offset
+ * @return string
+ */
+ protected function compileOffset(Builder $query, $offset)
+ {
+ return '';
+ }
+
+ /**
+ * Compile a truncate table statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return array
+ */
+ public function compileTruncate(Builder $query)
+ {
+ return ['truncate table '.$this->wrapTable($query->from) => []];
+ }
+
+ /**
+ * Compile an exists statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return string
+ */
+ public function compileExists(Builder $query)
+ {
+ $existsQuery = clone $query;
+
+ $existsQuery->columns = [];
+
+ return $this->compileSelect($existsQuery->selectRaw('1 [exists]')->limit(1));
+ }
+
+ /**
+ * Compile a "where date" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereDate(Builder $query, $where)
+ {
+ $value = $this->parameter($where['value']);
+
+ return 'cast('.$this->wrap($where['column']).' as date) '.$where['operator'].' '.$value;
+ }
+
+ /**
+ * Determine if the grammar supports savepoints.
+ *
+ * @return bool
+ */
+ public function supportsSavepoints()
+ {
+ return false;
+ }
+
+ /**
+ * Get the format for database stored dates.
+ *
+ * @return string
+ */
+ public function getDateFormat()
+ {
+ return 'Y-m-d H:i:s.000';
+ }
+
+ /**
+ * Wrap a single string in keyword identifiers.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function wrapValue($value)
+ {
+ if ($value === '*') {
+ return $value;
+ }
+
+ return '['.str_replace(']', ']]', $value).']';
+ }
+
+ /**
+ * Compile an update statement into SQL.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $values
+ * @return string
+ */
+ public function compileUpdate(Builder $query, $values)
+ {
+ $table = $alias = $this->wrapTable($query->from);
+
+ if (strpos(strtolower($table), '] as [') !== false) {
+ $segments = explode('] as [', $table);
+
+ $alias = '['.$segments[1];
+ }
+
+ // Each one of the columns in the update statements needs to be wrapped in the
+ // keyword identifiers, also a place-holder needs to be created for each of
+ // the values in the list of bindings so we can make the sets statements.
+ $columns = [];
+
+ foreach ($values as $key => $value) {
+ $columns[] = $this->wrap($key).' = '.$this->parameter($value);
+ }
+
+ $columns = implode(', ', $columns);
+
+ // If the query has any "join" clauses, we will setup the joins on the builder
+ // and compile them so we can attach them to this update, as update queries
+ // can get join statements to attach to other tables when they're needed.
+ if (isset($query->joins)) {
+ $joins = ' '.$this->compileJoins($query, $query->joins);
+ } else {
+ $joins = '';
+ }
+
+ // Of course, update queries may also be constrained by where clauses so we'll
+ // need to compile the where clauses and attach it to the query so only the
+ // intended records are updated by the SQL statements we generate to run.
+ $where = $this->compileWheres($query);
+
+ if (! empty($joins)) {
+ return trim("update {$alias} set {$columns} from {$table}{$joins} {$where}");
+ }
+
+ return trim("update {$table}{$joins} set $columns $where");
+ }
+}
diff --git a/vendor/illuminate/database/Query/JoinClause.php b/vendor/illuminate/database/Query/JoinClause.php
new file mode 100755
index 00000000..6f81043a
--- /dev/null
+++ b/vendor/illuminate/database/Query/JoinClause.php
@@ -0,0 +1,253 @@
+type = $type;
+ $this->table = $table;
+ }
+
+ /**
+ * Add an "on" clause to the join.
+ *
+ * On clauses can be chained, e.g.
+ *
+ * $join->on('contacts.user_id', '=', 'users.id')
+ * ->on('contacts.info_id', '=', 'info.id')
+ *
+ * will produce the following SQL:
+ *
+ * on `contacts`.`user_id` = `users`.`id` and `contacts`.`info_id` = `info`.`id`
+ *
+ * @param string|\Closure $first
+ * @param string|null $operator
+ * @param string|null $second
+ * @param string $boolean
+ * @param bool $where
+ * @return $this
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function on($first, $operator = null, $second = null, $boolean = 'and', $where = false)
+ {
+ if ($first instanceof Closure) {
+ return $this->nest($first, $boolean);
+ }
+
+ if (func_num_args() < 3) {
+ throw new InvalidArgumentException('Not enough arguments for the on clause.');
+ }
+
+ if ($where) {
+ $this->bindings[] = $second;
+ }
+
+ if ($where && ($operator === 'in' || $operator === 'not in') && is_array($second)) {
+ $second = count($second);
+ }
+
+ $nested = false;
+
+ $this->clauses[] = compact('first', 'operator', 'second', 'boolean', 'where', 'nested');
+
+ return $this;
+ }
+
+ /**
+ * Add an "or on" clause to the join.
+ *
+ * @param string|\Closure $first
+ * @param string|null $operator
+ * @param string|null $second
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function orOn($first, $operator = null, $second = null)
+ {
+ return $this->on($first, $operator, $second, 'or');
+ }
+
+ /**
+ * Add an "on where" clause to the join.
+ *
+ * @param string|\Closure $first
+ * @param string|null $operator
+ * @param string|null $second
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function where($first, $operator = null, $second = null, $boolean = 'and')
+ {
+ return $this->on($first, $operator, $second, $boolean, true);
+ }
+
+ /**
+ * Add an "or on where" clause to the join.
+ *
+ * @param string|\Closure $first
+ * @param string|null $operator
+ * @param string|null $second
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function orWhere($first, $operator = null, $second = null)
+ {
+ return $this->on($first, $operator, $second, 'or', true);
+ }
+
+ /**
+ * Add an "on where is null" clause to the join.
+ *
+ * @param string $column
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function whereNull($column, $boolean = 'and')
+ {
+ return $this->on($column, 'is', new Expression('null'), $boolean, false);
+ }
+
+ /**
+ * Add an "or on where is null" clause to the join.
+ *
+ * @param string $column
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function orWhereNull($column)
+ {
+ return $this->whereNull($column, 'or');
+ }
+
+ /**
+ * Add an "on where is not null" clause to the join.
+ *
+ * @param string $column
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function whereNotNull($column, $boolean = 'and')
+ {
+ return $this->on($column, 'is', new Expression('not null'), $boolean, false);
+ }
+
+ /**
+ * Add an "or on where is not null" clause to the join.
+ *
+ * @param string $column
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function orWhereNotNull($column)
+ {
+ return $this->whereNotNull($column, 'or');
+ }
+
+ /**
+ * Add an "on where in (...)" clause to the join.
+ *
+ * @param string $column
+ * @param array $values
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function whereIn($column, array $values)
+ {
+ return $this->on($column, 'in', $values, 'and', true);
+ }
+
+ /**
+ * Add an "on where not in (...)" clause to the join.
+ *
+ * @param string $column
+ * @param array $values
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function whereNotIn($column, array $values)
+ {
+ return $this->on($column, 'not in', $values, 'and', true);
+ }
+
+ /**
+ * Add an "or on where in (...)" clause to the join.
+ *
+ * @param string $column
+ * @param array $values
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function orWhereIn($column, array $values)
+ {
+ return $this->on($column, 'in', $values, 'or', true);
+ }
+
+ /**
+ * Add an "or on where not in (...)" clause to the join.
+ *
+ * @param string $column
+ * @param array $values
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function orWhereNotIn($column, array $values)
+ {
+ return $this->on($column, 'not in', $values, 'or', true);
+ }
+
+ /**
+ * Add a nested where statement to the query.
+ *
+ * @param \Closure $callback
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\JoinClause
+ */
+ public function nest(Closure $callback, $boolean = 'and')
+ {
+ $join = new static($this->type, $this->table);
+
+ $callback($join);
+
+ if (count($join->clauses)) {
+ $nested = true;
+
+ $this->clauses[] = compact('nested', 'join', 'boolean');
+ $this->bindings = array_merge($this->bindings, $join->bindings);
+ }
+
+ return $this;
+ }
+}
diff --git a/vendor/illuminate/database/Query/Processors/MySqlProcessor.php b/vendor/illuminate/database/Query/Processors/MySqlProcessor.php
new file mode 100644
index 00000000..a8a9a6ce
--- /dev/null
+++ b/vendor/illuminate/database/Query/Processors/MySqlProcessor.php
@@ -0,0 +1,23 @@
+column_name;
+ };
+
+ return array_map($mapping, $results);
+ }
+}
diff --git a/vendor/illuminate/database/Query/Processors/PostgresProcessor.php b/vendor/illuminate/database/Query/Processors/PostgresProcessor.php
new file mode 100755
index 00000000..ab350cb0
--- /dev/null
+++ b/vendor/illuminate/database/Query/Processors/PostgresProcessor.php
@@ -0,0 +1,47 @@
+getConnection()->selectFromWriteConnection($sql, $values);
+
+ $sequence = $sequence ?: 'id';
+
+ $result = (array) $results[0];
+
+ $id = $result[$sequence];
+
+ return is_numeric($id) ? (int) $id : $id;
+ }
+
+ /**
+ * Process the results of a column listing query.
+ *
+ * @param array $results
+ * @return array
+ */
+ public function processColumnListing($results)
+ {
+ $mapping = function ($r) {
+ $r = (object) $r;
+
+ return $r->column_name;
+ };
+
+ return array_map($mapping, $results);
+ }
+}
diff --git a/vendor/illuminate/database/Query/Processors/Processor.php b/vendor/illuminate/database/Query/Processors/Processor.php
new file mode 100755
index 00000000..f78429fb
--- /dev/null
+++ b/vendor/illuminate/database/Query/Processors/Processor.php
@@ -0,0 +1,49 @@
+getConnection()->insert($sql, $values);
+
+ $id = $query->getConnection()->getPdo()->lastInsertId($sequence);
+
+ return is_numeric($id) ? (int) $id : $id;
+ }
+
+ /**
+ * Process the results of a column listing query.
+ *
+ * @param array $results
+ * @return array
+ */
+ public function processColumnListing($results)
+ {
+ return $results;
+ }
+}
diff --git a/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php b/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php
new file mode 100644
index 00000000..e4a89504
--- /dev/null
+++ b/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php
@@ -0,0 +1,23 @@
+name;
+ };
+
+ return array_map($mapping, $results);
+ }
+}
diff --git a/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php b/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php
new file mode 100755
index 00000000..447a9c6f
--- /dev/null
+++ b/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php
@@ -0,0 +1,43 @@
+getConnection()->insert($sql, $values);
+
+ $id = $query->getConnection()->getPdo()->lastInsertId();
+
+ return is_numeric($id) ? (int) $id : $id;
+ }
+
+ /**
+ * Process the results of a column listing query.
+ *
+ * @param array $results
+ * @return array
+ */
+ public function processColumnListing($results)
+ {
+ $mapping = function ($r) {
+ $r = (object) $r;
+
+ return $r->name;
+ };
+
+ return array_map($mapping, $results);
+ }
+}
diff --git a/vendor/illuminate/database/QueryException.php b/vendor/illuminate/database/QueryException.php
new file mode 100644
index 00000000..922570b4
--- /dev/null
+++ b/vendor/illuminate/database/QueryException.php
@@ -0,0 +1,78 @@
+sql = $sql;
+ $this->bindings = $bindings;
+ $this->previous = $previous;
+ $this->code = $previous->getCode();
+ $this->message = $this->formatMessage($sql, $bindings, $previous);
+
+ if ($previous instanceof PDOException) {
+ $this->errorInfo = $previous->errorInfo;
+ }
+ }
+
+ /**
+ * Format the SQL error message.
+ *
+ * @param string $sql
+ * @param array $bindings
+ * @param \Exception $previous
+ * @return string
+ */
+ protected function formatMessage($sql, $bindings, $previous)
+ {
+ return $previous->getMessage().' (SQL: '.str_replace_array('\?', $bindings, $sql).')';
+ }
+
+ /**
+ * Get the SQL for the query.
+ *
+ * @return string
+ */
+ public function getSql()
+ {
+ return $this->sql;
+ }
+
+ /**
+ * Get the bindings for the query.
+ *
+ * @return array
+ */
+ public function getBindings()
+ {
+ return $this->bindings;
+ }
+}
diff --git a/vendor/illuminate/database/README.md b/vendor/illuminate/database/README.md
new file mode 100755
index 00000000..1675a932
--- /dev/null
+++ b/vendor/illuminate/database/README.md
@@ -0,0 +1,70 @@
+## Illuminate Database
+
+The Illuminate Database component is a full database toolkit for PHP, providing an expressive query builder, ActiveRecord style ORM, and schema builder. It currently supports MySQL, Postgres, SQL Server, and SQLite. It also serves as the database layer of the Laravel PHP framework.
+
+### Usage Instructions
+
+First, create a new "Capsule" manager instance. Capsule aims to make configuring the library for usage outside of the Laravel framework as easy as possible.
+
+```PHP
+use Illuminate\Database\Capsule\Manager as Capsule;
+
+$capsule = new Capsule;
+
+$capsule->addConnection([
+ 'driver' => 'mysql',
+ 'host' => 'localhost',
+ 'database' => 'database',
+ 'username' => 'root',
+ 'password' => 'password',
+ 'charset' => 'utf8',
+ 'collation' => 'utf8_unicode_ci',
+ 'prefix' => '',
+]);
+
+// Set the event dispatcher used by Eloquent models... (optional)
+use Illuminate\Events\Dispatcher;
+use Illuminate\Container\Container;
+$capsule->setEventDispatcher(new Dispatcher(new Container));
+
+// Make this Capsule instance available globally via static methods... (optional)
+$capsule->setAsGlobal();
+
+// Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())
+$capsule->bootEloquent();
+```
+
+> `composer require "illuminate/events"` required when you need to use observers with Eloquent.
+
+Once the Capsule instance has been registered. You may use it like so:
+
+**Using The Query Builder**
+
+```PHP
+$users = Capsule::table('users')->where('votes', '>', 100)->get();
+```
+Other core methods may be accessed directly from the Capsule in the same manner as from the DB facade:
+```PHP
+$results = Capsule::select('select * from users where id = ?', array(1));
+```
+
+**Using The Schema Builder**
+
+```PHP
+Capsule::schema()->create('users', function($table)
+{
+ $table->increments('id');
+ $table->string('email')->unique();
+ $table->timestamps();
+});
+```
+
+**Using The Eloquent ORM**
+
+```PHP
+class User extends Illuminate\Database\Eloquent\Model {}
+
+$users = User::where('votes', '>', 1)->get();
+```
+
+For further documentation on using the various database facilities this library provides, consult the [Laravel framework documentation](http://laravel.com/docs).
diff --git a/vendor/illuminate/database/SQLiteConnection.php b/vendor/illuminate/database/SQLiteConnection.php
new file mode 100755
index 00000000..b32786c1
--- /dev/null
+++ b/vendor/illuminate/database/SQLiteConnection.php
@@ -0,0 +1,51 @@
+withTablePrefix(new QueryGrammar);
+ }
+
+ /**
+ * Get the default schema grammar instance.
+ *
+ * @return \Illuminate\Database\Schema\Grammars\SQLiteGrammar
+ */
+ protected function getDefaultSchemaGrammar()
+ {
+ return $this->withTablePrefix(new SchemaGrammar);
+ }
+
+ /**
+ * Get the default post processor instance.
+ *
+ * @return \Illuminate\Database\Query\Processors\SQLiteProcessor
+ */
+ protected function getDefaultPostProcessor()
+ {
+ return new SQLiteProcessor;
+ }
+
+ /**
+ * Get the Doctrine DBAL driver.
+ *
+ * @return \Doctrine\DBAL\Driver\PDOSqlite\Driver
+ */
+ protected function getDoctrineDriver()
+ {
+ return new DoctrineDriver;
+ }
+}
diff --git a/vendor/illuminate/database/Schema/Blueprint.php b/vendor/illuminate/database/Schema/Blueprint.php
new file mode 100755
index 00000000..fca8e896
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Blueprint.php
@@ -0,0 +1,1040 @@
+table = $table;
+
+ if (! is_null($callback)) {
+ $callback($this);
+ }
+ }
+
+ /**
+ * Execute the blueprint against the database.
+ *
+ * @param \Illuminate\Database\Connection $connection
+ * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
+ * @return void
+ */
+ public function build(Connection $connection, Grammar $grammar)
+ {
+ foreach ($this->toSql($connection, $grammar) as $statement) {
+ $connection->statement($statement);
+ }
+ }
+
+ /**
+ * Get the raw SQL statements for the blueprint.
+ *
+ * @param \Illuminate\Database\Connection $connection
+ * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
+ * @return array
+ */
+ public function toSql(Connection $connection, Grammar $grammar)
+ {
+ $this->addImpliedCommands();
+
+ $statements = [];
+
+ // Each type of command has a corresponding compiler function on the schema
+ // grammar which is used to build the necessary SQL statements to build
+ // the blueprint element, so we'll just call that compilers function.
+ foreach ($this->commands as $command) {
+ $method = 'compile'.ucfirst($command->name);
+
+ if (method_exists($grammar, $method)) {
+ if (! is_null($sql = $grammar->$method($this, $command, $connection))) {
+ $statements = array_merge($statements, (array) $sql);
+ }
+ }
+ }
+
+ return $statements;
+ }
+
+ /**
+ * Add the commands that are implied by the blueprint.
+ *
+ * @return void
+ */
+ protected function addImpliedCommands()
+ {
+ if (count($this->getAddedColumns()) > 0 && ! $this->creating()) {
+ array_unshift($this->commands, $this->createCommand('add'));
+ }
+
+ if (count($this->getChangedColumns()) > 0 && ! $this->creating()) {
+ array_unshift($this->commands, $this->createCommand('change'));
+ }
+
+ $this->addFluentIndexes();
+ }
+
+ /**
+ * Add the index commands fluently specified on columns.
+ *
+ * @return void
+ */
+ protected function addFluentIndexes()
+ {
+ foreach ($this->columns as $column) {
+ foreach (['primary', 'unique', 'index'] as $index) {
+ // If the index has been specified on the given column, but is simply
+ // equal to "true" (boolean), no name has been specified for this
+ // index, so we will simply call the index methods without one.
+ if ($column->$index === true) {
+ $this->$index($column->name);
+
+ continue 2;
+ }
+
+ // If the index has been specified on the column and it is something
+ // other than boolean true, we will assume a name was provided on
+ // the index specification, and pass in the name to the method.
+ elseif (isset($column->$index)) {
+ $this->$index($column->name, $column->$index);
+
+ continue 2;
+ }
+ }
+ }
+ }
+
+ /**
+ * Determine if the blueprint has a create command.
+ *
+ * @return bool
+ */
+ protected function creating()
+ {
+ foreach ($this->commands as $command) {
+ if ($command->name == 'create') {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Indicate that the table needs to be created.
+ *
+ * @return \Illuminate\Support\Fluent
+ */
+ public function create()
+ {
+ return $this->addCommand('create');
+ }
+
+ /**
+ * Indicate that the table needs to be temporary.
+ *
+ * @return void
+ */
+ public function temporary()
+ {
+ $this->temporary = true;
+ }
+
+ /**
+ * Indicate that the table should be dropped.
+ *
+ * @return \Illuminate\Support\Fluent
+ */
+ public function drop()
+ {
+ return $this->addCommand('drop');
+ }
+
+ /**
+ * Indicate that the table should be dropped if it exists.
+ *
+ * @return \Illuminate\Support\Fluent
+ */
+ public function dropIfExists()
+ {
+ return $this->addCommand('dropIfExists');
+ }
+
+ /**
+ * Indicate that the given columns should be dropped.
+ *
+ * @param array|mixed $columns
+ * @return \Illuminate\Support\Fluent
+ */
+ public function dropColumn($columns)
+ {
+ $columns = is_array($columns) ? $columns : (array) func_get_args();
+
+ return $this->addCommand('dropColumn', compact('columns'));
+ }
+
+ /**
+ * Indicate that the given columns should be renamed.
+ *
+ * @param string $from
+ * @param string $to
+ * @return \Illuminate\Support\Fluent
+ */
+ public function renameColumn($from, $to)
+ {
+ return $this->addCommand('renameColumn', compact('from', 'to'));
+ }
+
+ /**
+ * Indicate that the given primary key should be dropped.
+ *
+ * @param string|array $index
+ * @return \Illuminate\Support\Fluent
+ */
+ public function dropPrimary($index = null)
+ {
+ return $this->dropIndexCommand('dropPrimary', 'primary', $index);
+ }
+
+ /**
+ * Indicate that the given unique key should be dropped.
+ *
+ * @param string|array $index
+ * @return \Illuminate\Support\Fluent
+ */
+ public function dropUnique($index)
+ {
+ return $this->dropIndexCommand('dropUnique', 'unique', $index);
+ }
+
+ /**
+ * Indicate that the given index should be dropped.
+ *
+ * @param string|array $index
+ * @return \Illuminate\Support\Fluent
+ */
+ public function dropIndex($index)
+ {
+ return $this->dropIndexCommand('dropIndex', 'index', $index);
+ }
+
+ /**
+ * Indicate that the given foreign key should be dropped.
+ *
+ * @param string $index
+ * @return \Illuminate\Support\Fluent
+ */
+ public function dropForeign($index)
+ {
+ return $this->dropIndexCommand('dropForeign', 'foreign', $index);
+ }
+
+ /**
+ * Indicate that the timestamp columns should be dropped.
+ *
+ * @return void
+ */
+ public function dropTimestamps()
+ {
+ $this->dropColumn('created_at', 'updated_at');
+ }
+
+ /**
+ * Indicate that the timestamp columns should be dropped.
+ *
+ * @return void
+ */
+ public function dropTimestampsTz()
+ {
+ $this->dropTimestamps();
+ }
+
+ /**
+ * Indicate that the soft delete column should be dropped.
+ *
+ * @return void
+ */
+ public function dropSoftDeletes()
+ {
+ $this->dropColumn('deleted_at');
+ }
+
+ /**
+ * Indicate that the remember token column should be dropped.
+ *
+ * @return void
+ */
+ public function dropRememberToken()
+ {
+ $this->dropColumn('remember_token');
+ }
+
+ /**
+ * Rename the table to a given name.
+ *
+ * @param string $to
+ * @return \Illuminate\Support\Fluent
+ */
+ public function rename($to)
+ {
+ return $this->addCommand('rename', compact('to'));
+ }
+
+ /**
+ * Specify the primary key(s) for the table.
+ *
+ * @param string|array $columns
+ * @param string $name
+ * @return \Illuminate\Support\Fluent
+ */
+ public function primary($columns, $name = null)
+ {
+ return $this->indexCommand('primary', $columns, $name);
+ }
+
+ /**
+ * Specify a unique index for the table.
+ *
+ * @param string|array $columns
+ * @param string $name
+ * @return \Illuminate\Support\Fluent
+ */
+ public function unique($columns, $name = null)
+ {
+ return $this->indexCommand('unique', $columns, $name);
+ }
+
+ /**
+ * Specify an index for the table.
+ *
+ * @param string|array $columns
+ * @param string $name
+ * @return \Illuminate\Support\Fluent
+ */
+ public function index($columns, $name = null)
+ {
+ return $this->indexCommand('index', $columns, $name);
+ }
+
+ /**
+ * Specify a foreign key for the table.
+ *
+ * @param string|array $columns
+ * @param string $name
+ * @return \Illuminate\Support\Fluent
+ */
+ public function foreign($columns, $name = null)
+ {
+ return $this->indexCommand('foreign', $columns, $name);
+ }
+
+ /**
+ * Create a new auto-incrementing integer (4-byte) column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function increments($column)
+ {
+ return $this->unsignedInteger($column, true);
+ }
+
+ /**
+ * Create a new auto-incrementing small integer (2-byte) column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function smallIncrements($column)
+ {
+ return $this->unsignedSmallInteger($column, true);
+ }
+
+ /**
+ * Create a new auto-incrementing medium integer (3-byte) column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function mediumIncrements($column)
+ {
+ return $this->unsignedMediumInteger($column, true);
+ }
+
+ /**
+ * Create a new auto-incrementing big integer (8-byte) column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function bigIncrements($column)
+ {
+ return $this->unsignedBigInteger($column, true);
+ }
+
+ /**
+ * Create a new char column on the table.
+ *
+ * @param string $column
+ * @param int $length
+ * @return \Illuminate\Support\Fluent
+ */
+ public function char($column, $length = 255)
+ {
+ return $this->addColumn('char', $column, compact('length'));
+ }
+
+ /**
+ * Create a new string column on the table.
+ *
+ * @param string $column
+ * @param int $length
+ * @return \Illuminate\Support\Fluent
+ */
+ public function string($column, $length = 255)
+ {
+ return $this->addColumn('string', $column, compact('length'));
+ }
+
+ /**
+ * Create a new text column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function text($column)
+ {
+ return $this->addColumn('text', $column);
+ }
+
+ /**
+ * Create a new medium text column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function mediumText($column)
+ {
+ return $this->addColumn('mediumText', $column);
+ }
+
+ /**
+ * Create a new long text column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function longText($column)
+ {
+ return $this->addColumn('longText', $column);
+ }
+
+ /**
+ * Create a new integer (4-byte) column on the table.
+ *
+ * @param string $column
+ * @param bool $autoIncrement
+ * @param bool $unsigned
+ * @return \Illuminate\Support\Fluent
+ */
+ public function integer($column, $autoIncrement = false, $unsigned = false)
+ {
+ return $this->addColumn('integer', $column, compact('autoIncrement', 'unsigned'));
+ }
+
+ /**
+ * Create a new tiny integer (1-byte) column on the table.
+ *
+ * @param string $column
+ * @param bool $autoIncrement
+ * @param bool $unsigned
+ * @return \Illuminate\Support\Fluent
+ */
+ public function tinyInteger($column, $autoIncrement = false, $unsigned = false)
+ {
+ return $this->addColumn('tinyInteger', $column, compact('autoIncrement', 'unsigned'));
+ }
+
+ /**
+ * Create a new small integer (2-byte) column on the table.
+ *
+ * @param string $column
+ * @param bool $autoIncrement
+ * @param bool $unsigned
+ * @return \Illuminate\Support\Fluent
+ */
+ public function smallInteger($column, $autoIncrement = false, $unsigned = false)
+ {
+ return $this->addColumn('smallInteger', $column, compact('autoIncrement', 'unsigned'));
+ }
+
+ /**
+ * Create a new medium integer (3-byte) column on the table.
+ *
+ * @param string $column
+ * @param bool $autoIncrement
+ * @param bool $unsigned
+ * @return \Illuminate\Support\Fluent
+ */
+ public function mediumInteger($column, $autoIncrement = false, $unsigned = false)
+ {
+ return $this->addColumn('mediumInteger', $column, compact('autoIncrement', 'unsigned'));
+ }
+
+ /**
+ * Create a new big integer (8-byte) column on the table.
+ *
+ * @param string $column
+ * @param bool $autoIncrement
+ * @param bool $unsigned
+ * @return \Illuminate\Support\Fluent
+ */
+ public function bigInteger($column, $autoIncrement = false, $unsigned = false)
+ {
+ return $this->addColumn('bigInteger', $column, compact('autoIncrement', 'unsigned'));
+ }
+
+ /**
+ * Create a new unsigned tiny integer (1-byte) column on the table.
+ *
+ * @param string $column
+ * @param bool $autoIncrement
+ * @return \Illuminate\Support\Fluent
+ */
+ public function unsignedTinyInteger($column, $autoIncrement = false)
+ {
+ return $this->tinyInteger($column, $autoIncrement, true);
+ }
+
+ /**
+ * Create a new unsigned small integer (2-byte) column on the table.
+ *
+ * @param string $column
+ * @param bool $autoIncrement
+ * @return \Illuminate\Support\Fluent
+ */
+ public function unsignedSmallInteger($column, $autoIncrement = false)
+ {
+ return $this->smallInteger($column, $autoIncrement, true);
+ }
+
+ /**
+ * Create a new unsigned medium integer (3-byte) column on the table.
+ *
+ * @param string $column
+ * @param bool $autoIncrement
+ * @return \Illuminate\Support\Fluent
+ */
+ public function unsignedMediumInteger($column, $autoIncrement = false)
+ {
+ return $this->mediumInteger($column, $autoIncrement, true);
+ }
+
+ /**
+ * Create a new unsigned integer (4-byte) column on the table.
+ *
+ * @param string $column
+ * @param bool $autoIncrement
+ * @return \Illuminate\Support\Fluent
+ */
+ public function unsignedInteger($column, $autoIncrement = false)
+ {
+ return $this->integer($column, $autoIncrement, true);
+ }
+
+ /**
+ * Create a new unsigned big integer (8-byte) column on the table.
+ *
+ * @param string $column
+ * @param bool $autoIncrement
+ * @return \Illuminate\Support\Fluent
+ */
+ public function unsignedBigInteger($column, $autoIncrement = false)
+ {
+ return $this->bigInteger($column, $autoIncrement, true);
+ }
+
+ /**
+ * Create a new float column on the table.
+ *
+ * @param string $column
+ * @param int $total
+ * @param int $places
+ * @return \Illuminate\Support\Fluent
+ */
+ public function float($column, $total = 8, $places = 2)
+ {
+ return $this->addColumn('float', $column, compact('total', 'places'));
+ }
+
+ /**
+ * Create a new double column on the table.
+ *
+ * @param string $column
+ * @param int|null $total
+ * @param int|null $places
+ * @return \Illuminate\Support\Fluent
+ */
+ public function double($column, $total = null, $places = null)
+ {
+ return $this->addColumn('double', $column, compact('total', 'places'));
+ }
+
+ /**
+ * Create a new decimal column on the table.
+ *
+ * @param string $column
+ * @param int $total
+ * @param int $places
+ * @return \Illuminate\Support\Fluent
+ */
+ public function decimal($column, $total = 8, $places = 2)
+ {
+ return $this->addColumn('decimal', $column, compact('total', 'places'));
+ }
+
+ /**
+ * Create a new boolean column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function boolean($column)
+ {
+ return $this->addColumn('boolean', $column);
+ }
+
+ /**
+ * Create a new enum column on the table.
+ *
+ * @param string $column
+ * @param array $allowed
+ * @return \Illuminate\Support\Fluent
+ */
+ public function enum($column, array $allowed)
+ {
+ return $this->addColumn('enum', $column, compact('allowed'));
+ }
+
+ /**
+ * Create a new json column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function json($column)
+ {
+ return $this->addColumn('json', $column);
+ }
+
+ /**
+ * Create a new jsonb column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function jsonb($column)
+ {
+ return $this->addColumn('jsonb', $column);
+ }
+
+ /**
+ * Create a new date column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function date($column)
+ {
+ return $this->addColumn('date', $column);
+ }
+
+ /**
+ * Create a new date-time column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function dateTime($column)
+ {
+ return $this->addColumn('dateTime', $column);
+ }
+
+ /**
+ * Create a new date-time column (with time zone) on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function dateTimeTz($column)
+ {
+ return $this->addColumn('dateTimeTz', $column);
+ }
+
+ /**
+ * Create a new time column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function time($column)
+ {
+ return $this->addColumn('time', $column);
+ }
+
+ /**
+ * Create a new time column (with time zone) on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function timeTz($column)
+ {
+ return $this->addColumn('timeTz', $column);
+ }
+
+ /**
+ * Create a new timestamp column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function timestamp($column)
+ {
+ return $this->addColumn('timestamp', $column);
+ }
+
+ /**
+ * Create a new timestamp (with time zone) column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function timestampTz($column)
+ {
+ return $this->addColumn('timestampTz', $column);
+ }
+
+ /**
+ * Add nullable creation and update timestamps to the table.
+ *
+ * @return void
+ */
+ public function nullableTimestamps()
+ {
+ $this->timestamp('created_at')->nullable();
+
+ $this->timestamp('updated_at')->nullable();
+ }
+
+ /**
+ * Add creation and update timestamps to the table.
+ *
+ * @return void
+ */
+ public function timestamps()
+ {
+ $this->timestamp('created_at');
+
+ $this->timestamp('updated_at');
+ }
+
+ /**
+ * Add creation and update timestampTz columns to the table.
+ *
+ * @return void
+ */
+ public function timestampsTz()
+ {
+ $this->timestampTz('created_at');
+
+ $this->timestampTz('updated_at');
+ }
+
+ /**
+ * Add a "deleted at" timestamp for the table.
+ *
+ * @return \Illuminate\Support\Fluent
+ */
+ public function softDeletes()
+ {
+ return $this->timestamp('deleted_at')->nullable();
+ }
+
+ /**
+ * Create a new binary column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function binary($column)
+ {
+ return $this->addColumn('binary', $column);
+ }
+
+ /**
+ * Create a new uuid column on the table.
+ *
+ * @param string $column
+ * @return \Illuminate\Support\Fluent
+ */
+ public function uuid($column)
+ {
+ return $this->addColumn('uuid', $column);
+ }
+
+ /**
+ * Add the proper columns for a polymorphic table.
+ *
+ * @param string $name
+ * @param string|null $indexName
+ * @return void
+ */
+ public function morphs($name, $indexName = null)
+ {
+ $this->unsignedInteger("{$name}_id");
+
+ $this->string("{$name}_type");
+
+ $this->index(["{$name}_id", "{$name}_type"], $indexName);
+ }
+
+ /**
+ * Adds the `remember_token` column to the table.
+ *
+ * @return \Illuminate\Support\Fluent
+ */
+ public function rememberToken()
+ {
+ return $this->string('remember_token', 100)->nullable();
+ }
+
+ /**
+ * Create a new drop index command on the blueprint.
+ *
+ * @param string $command
+ * @param string $type
+ * @param string|array $index
+ * @return \Illuminate\Support\Fluent
+ */
+ protected function dropIndexCommand($command, $type, $index)
+ {
+ $columns = [];
+
+ // If the given "index" is actually an array of columns, the developer means
+ // to drop an index merely by specifying the columns involved without the
+ // conventional name, so we will build the index name from the columns.
+ if (is_array($index)) {
+ $columns = $index;
+
+ $index = $this->createIndexName($type, $columns);
+ }
+
+ return $this->indexCommand($command, $columns, $index);
+ }
+
+ /**
+ * Add a new index command to the blueprint.
+ *
+ * @param string $type
+ * @param string|array $columns
+ * @param string $index
+ * @return \Illuminate\Support\Fluent
+ */
+ protected function indexCommand($type, $columns, $index)
+ {
+ $columns = (array) $columns;
+
+ // If no name was specified for this index, we will create one using a basic
+ // convention of the table name, followed by the columns, followed by an
+ // index type, such as primary or index, which makes the index unique.
+ if (is_null($index)) {
+ $index = $this->createIndexName($type, $columns);
+ }
+
+ return $this->addCommand($type, compact('index', 'columns'));
+ }
+
+ /**
+ * Create a default index name for the table.
+ *
+ * @param string $type
+ * @param array $columns
+ * @return string
+ */
+ protected function createIndexName($type, array $columns)
+ {
+ $index = strtolower($this->table.'_'.implode('_', $columns).'_'.$type);
+
+ return str_replace(['-', '.'], '_', $index);
+ }
+
+ /**
+ * Add a new column to the blueprint.
+ *
+ * @param string $type
+ * @param string $name
+ * @param array $parameters
+ * @return \Illuminate\Support\Fluent
+ */
+ protected function addColumn($type, $name, array $parameters = [])
+ {
+ $attributes = array_merge(compact('type', 'name'), $parameters);
+
+ $this->columns[] = $column = new Fluent($attributes);
+
+ return $column;
+ }
+
+ /**
+ * Remove a column from the schema blueprint.
+ *
+ * @param string $name
+ * @return $this
+ */
+ public function removeColumn($name)
+ {
+ $this->columns = array_values(array_filter($this->columns, function ($c) use ($name) {
+ return $c['attributes']['name'] != $name;
+ }));
+
+ return $this;
+ }
+
+ /**
+ * Add a new command to the blueprint.
+ *
+ * @param string $name
+ * @param array $parameters
+ * @return \Illuminate\Support\Fluent
+ */
+ protected function addCommand($name, array $parameters = [])
+ {
+ $this->commands[] = $command = $this->createCommand($name, $parameters);
+
+ return $command;
+ }
+
+ /**
+ * Create a new Fluent command.
+ *
+ * @param string $name
+ * @param array $parameters
+ * @return \Illuminate\Support\Fluent
+ */
+ protected function createCommand($name, array $parameters = [])
+ {
+ return new Fluent(array_merge(compact('name'), $parameters));
+ }
+
+ /**
+ * Get the table the blueprint describes.
+ *
+ * @return string
+ */
+ public function getTable()
+ {
+ return $this->table;
+ }
+
+ /**
+ * Get the columns on the blueprint.
+ *
+ * @return array
+ */
+ public function getColumns()
+ {
+ return $this->columns;
+ }
+
+ /**
+ * Get the commands on the blueprint.
+ *
+ * @return array
+ */
+ public function getCommands()
+ {
+ return $this->commands;
+ }
+
+ /**
+ * Get the columns on the blueprint that should be added.
+ *
+ * @return array
+ */
+ public function getAddedColumns()
+ {
+ return array_filter($this->columns, function ($column) {
+ return ! $column->change;
+ });
+ }
+
+ /**
+ * Get the columns on the blueprint that should be changed.
+ *
+ * @return array
+ */
+ public function getChangedColumns()
+ {
+ return array_filter($this->columns, function ($column) {
+ return (bool) $column->change;
+ });
+ }
+}
diff --git a/vendor/illuminate/database/Schema/Builder.php b/vendor/illuminate/database/Schema/Builder.php
new file mode 100755
index 00000000..5e10b424
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Builder.php
@@ -0,0 +1,243 @@
+connection = $connection;
+ $this->grammar = $connection->getSchemaGrammar();
+ }
+
+ /**
+ * Determine if the given table exists.
+ *
+ * @param string $table
+ * @return bool
+ */
+ public function hasTable($table)
+ {
+ $sql = $this->grammar->compileTableExists();
+
+ $table = $this->connection->getTablePrefix().$table;
+
+ return count($this->connection->select($sql, [$table])) > 0;
+ }
+
+ /**
+ * Determine if the given table has a given column.
+ *
+ * @param string $table
+ * @param string $column
+ * @return bool
+ */
+ public function hasColumn($table, $column)
+ {
+ $column = strtolower($column);
+
+ return in_array($column, array_map('strtolower', $this->getColumnListing($table)));
+ }
+
+ /**
+ * Determine if the given table has given columns.
+ *
+ * @param string $table
+ * @param array $columns
+ * @return bool
+ */
+ public function hasColumns($table, array $columns)
+ {
+ $tableColumns = array_map('strtolower', $this->getColumnListing($table));
+
+ foreach ($columns as $column) {
+ if (! in_array(strtolower($column), $tableColumns)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the column listing for a given table.
+ *
+ * @param string $table
+ * @return array
+ */
+ public function getColumnListing($table)
+ {
+ $table = $this->connection->getTablePrefix().$table;
+
+ $results = $this->connection->select($this->grammar->compileColumnExists($table));
+
+ return $this->connection->getPostProcessor()->processColumnListing($results);
+ }
+
+ /**
+ * Modify a table on the schema.
+ *
+ * @param string $table
+ * @param \Closure $callback
+ * @return \Illuminate\Database\Schema\Blueprint
+ */
+ public function table($table, Closure $callback)
+ {
+ $this->build($this->createBlueprint($table, $callback));
+ }
+
+ /**
+ * Create a new table on the schema.
+ *
+ * @param string $table
+ * @param \Closure $callback
+ * @return \Illuminate\Database\Schema\Blueprint
+ */
+ public function create($table, Closure $callback)
+ {
+ $blueprint = $this->createBlueprint($table);
+
+ $blueprint->create();
+
+ $callback($blueprint);
+
+ $this->build($blueprint);
+ }
+
+ /**
+ * Drop a table from the schema.
+ *
+ * @param string $table
+ * @return \Illuminate\Database\Schema\Blueprint
+ */
+ public function drop($table)
+ {
+ $blueprint = $this->createBlueprint($table);
+
+ $blueprint->drop();
+
+ $this->build($blueprint);
+ }
+
+ /**
+ * Drop a table from the schema if it exists.
+ *
+ * @param string $table
+ * @return \Illuminate\Database\Schema\Blueprint
+ */
+ public function dropIfExists($table)
+ {
+ $blueprint = $this->createBlueprint($table);
+
+ $blueprint->dropIfExists();
+
+ $this->build($blueprint);
+ }
+
+ /**
+ * Rename a table on the schema.
+ *
+ * @param string $from
+ * @param string $to
+ * @return \Illuminate\Database\Schema\Blueprint
+ */
+ public function rename($from, $to)
+ {
+ $blueprint = $this->createBlueprint($from);
+
+ $blueprint->rename($to);
+
+ $this->build($blueprint);
+ }
+
+ /**
+ * Execute the blueprint to build / modify the table.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @return void
+ */
+ protected function build(Blueprint $blueprint)
+ {
+ $blueprint->build($this->connection, $this->grammar);
+ }
+
+ /**
+ * Create a new command set with a Closure.
+ *
+ * @param string $table
+ * @param \Closure|null $callback
+ * @return \Illuminate\Database\Schema\Blueprint
+ */
+ protected function createBlueprint($table, Closure $callback = null)
+ {
+ if (isset($this->resolver)) {
+ return call_user_func($this->resolver, $table, $callback);
+ }
+
+ return new Blueprint($table, $callback);
+ }
+
+ /**
+ * Get the database connection instance.
+ *
+ * @return \Illuminate\Database\Connection
+ */
+ public function getConnection()
+ {
+ return $this->connection;
+ }
+
+ /**
+ * Set the database connection instance.
+ *
+ * @param \Illuminate\Database\Connection $connection
+ * @return $this
+ */
+ public function setConnection(Connection $connection)
+ {
+ $this->connection = $connection;
+
+ return $this;
+ }
+
+ /**
+ * Set the Schema Blueprint resolver callback.
+ *
+ * @param \Closure $resolver
+ * @return void
+ */
+ public function blueprintResolver(Closure $resolver)
+ {
+ $this->resolver = $resolver;
+ }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/Grammar.php b/vendor/illuminate/database/Schema/Grammars/Grammar.php
new file mode 100755
index 00000000..6eeff753
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/Grammar.php
@@ -0,0 +1,459 @@
+getDoctrineSchemaManager();
+
+ $table = $this->getTablePrefix().$blueprint->getTable();
+
+ $column = $connection->getDoctrineColumn($table, $command->from);
+
+ $tableDiff = $this->getRenamedDiff($blueprint, $command, $column, $schema);
+
+ return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff);
+ }
+
+ /**
+ * Get a new column instance with the new column name.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @param \Doctrine\DBAL\Schema\Column $column
+ * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema
+ * @return \Doctrine\DBAL\Schema\TableDiff
+ */
+ protected function getRenamedDiff(Blueprint $blueprint, Fluent $command, Column $column, SchemaManager $schema)
+ {
+ $tableDiff = $this->getDoctrineTableDiff($blueprint, $schema);
+
+ return $this->setRenamedColumns($tableDiff, $command, $column);
+ }
+
+ /**
+ * Set the renamed columns on the table diff.
+ *
+ * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff
+ * @param \Illuminate\Support\Fluent $command
+ * @param \Doctrine\DBAL\Schema\Column $column
+ * @return \Doctrine\DBAL\Schema\TableDiff
+ */
+ protected function setRenamedColumns(TableDiff $tableDiff, Fluent $command, Column $column)
+ {
+ $newColumn = new Column($command->to, $column->getType(), $column->toArray());
+
+ $tableDiff->renamedColumns = [$command->from => $newColumn];
+
+ return $tableDiff;
+ }
+
+ /**
+ * Compile a foreign key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileForeign(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ $on = $this->wrapTable($command->on);
+
+ // We need to prepare several of the elements of the foreign key definition
+ // before we can create the SQL, such as wrapping the tables and convert
+ // an array of columns to comma-delimited strings for the SQL queries.
+ $columns = $this->columnize($command->columns);
+
+ $onColumns = $this->columnize((array) $command->references);
+
+ $sql = "alter table {$table} add constraint {$command->index} ";
+
+ $sql .= "foreign key ({$columns}) references {$on} ({$onColumns})";
+
+ // Once we have the basic foreign key creation statement constructed we can
+ // build out the syntax for what should happen on an update or delete of
+ // the affected columns, which will get something like "cascade", etc.
+ if (! is_null($command->onDelete)) {
+ $sql .= " on delete {$command->onDelete}";
+ }
+
+ if (! is_null($command->onUpdate)) {
+ $sql .= " on update {$command->onUpdate}";
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Compile the blueprint's column definitions.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @return array
+ */
+ protected function getColumns(Blueprint $blueprint)
+ {
+ $columns = [];
+
+ foreach ($blueprint->getAddedColumns() as $column) {
+ // Each of the column types have their own compiler functions which are tasked
+ // with turning the column definition into its SQL format for this platform
+ // used by the connection. The column's modifiers are compiled and added.
+ $sql = $this->wrap($column).' '.$this->getType($column);
+
+ $columns[] = $this->addModifiers($sql, $blueprint, $column);
+ }
+
+ return $columns;
+ }
+
+ /**
+ * Add the column modifiers to the definition.
+ *
+ * @param string $sql
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function addModifiers($sql, Blueprint $blueprint, Fluent $column)
+ {
+ foreach ($this->modifiers as $modifier) {
+ if (method_exists($this, $method = "modify{$modifier}")) {
+ $sql .= $this->{$method}($blueprint, $column);
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Get the primary key command if it exists on the blueprint.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param string $name
+ * @return \Illuminate\Support\Fluent|null
+ */
+ protected function getCommandByName(Blueprint $blueprint, $name)
+ {
+ $commands = $this->getCommandsByName($blueprint, $name);
+
+ if (count($commands) > 0) {
+ return reset($commands);
+ }
+ }
+
+ /**
+ * Get all of the commands with a given name.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param string $name
+ * @return array
+ */
+ protected function getCommandsByName(Blueprint $blueprint, $name)
+ {
+ return array_filter($blueprint->getCommands(), function ($value) use ($name) {
+ return $value->name == $name;
+ });
+ }
+
+ /**
+ * Get the SQL for the column data type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function getType(Fluent $column)
+ {
+ return $this->{'type'.ucfirst($column->type)}($column);
+ }
+
+ /**
+ * Add a prefix to an array of values.
+ *
+ * @param string $prefix
+ * @param array $values
+ * @return array
+ */
+ public function prefixArray($prefix, array $values)
+ {
+ return array_map(function ($value) use ($prefix) {
+ return $prefix.' '.$value;
+
+ }, $values);
+ }
+
+ /**
+ * Wrap a table in keyword identifiers.
+ *
+ * @param mixed $table
+ * @return string
+ */
+ public function wrapTable($table)
+ {
+ if ($table instanceof Blueprint) {
+ $table = $table->getTable();
+ }
+
+ return parent::wrapTable($table);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function wrap($value, $prefixAlias = false)
+ {
+ if ($value instanceof Fluent) {
+ $value = $value->name;
+ }
+
+ return parent::wrap($value, $prefixAlias);
+ }
+
+ /**
+ * Format a value so that it can be used in "default" clauses.
+ *
+ * @param mixed $value
+ * @return string
+ */
+ protected function getDefaultValue($value)
+ {
+ if ($value instanceof Expression) {
+ return $value;
+ }
+
+ if (is_bool($value)) {
+ return "'".(int) $value."'";
+ }
+
+ return "'".strval($value)."'";
+ }
+
+ /**
+ * Create an empty Doctrine DBAL TableDiff from the Blueprint.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema
+ * @return \Doctrine\DBAL\Schema\TableDiff
+ */
+ protected function getDoctrineTableDiff(Blueprint $blueprint, SchemaManager $schema)
+ {
+ $table = $this->getTablePrefix().$blueprint->getTable();
+
+ $tableDiff = new TableDiff($table);
+
+ $tableDiff->fromTable = $schema->listTableDetails($table);
+
+ return $tableDiff;
+ }
+
+ /**
+ * Compile a change column command into a series of SQL statements.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @param \Illuminate\Database\Connection $connection
+ * @return array
+ */
+ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $connection)
+ {
+ if (! $connection->isDoctrineAvailable()) {
+ throw new RuntimeException(sprintf(
+ 'Changing columns for table "%s" requires Doctrine DBAL; install "doctrine/dbal".',
+ $blueprint->getTable()
+ ));
+ }
+
+ $schema = $connection->getDoctrineSchemaManager();
+
+ $tableDiff = $this->getChangedDiff($blueprint, $schema);
+
+ if ($tableDiff !== false) {
+ return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff);
+ }
+
+ return [];
+ }
+
+ /**
+ * Get the Doctrine table difference for the given changes.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema
+ * @return \Doctrine\DBAL\Schema\TableDiff|bool
+ */
+ protected function getChangedDiff(Blueprint $blueprint, SchemaManager $schema)
+ {
+ $table = $schema->listTableDetails($this->getTablePrefix().$blueprint->getTable());
+
+ return (new Comparator)->diffTable($table, $this->getTableWithColumnChanges($blueprint, $table));
+ }
+
+ /**
+ * Get a copy of the given Doctrine table after making the column changes.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Doctrine\DBAL\Schema\Table $table
+ * @return \Doctrine\DBAL\Schema\TableDiff
+ */
+ protected function getTableWithColumnChanges(Blueprint $blueprint, Table $table)
+ {
+ $table = clone $table;
+
+ foreach ($blueprint->getChangedColumns() as $fluent) {
+ $column = $this->getDoctrineColumnForChange($table, $fluent);
+
+ // Here we will spin through each fluent column definition and map it to the proper
+ // Doctrine column definitions - which is necessary because Laravel and Doctrine
+ // use some different terminology for various column attributes on the tables.
+ foreach ($fluent->getAttributes() as $key => $value) {
+ if (! is_null($option = $this->mapFluentOptionToDoctrine($key))) {
+ if (method_exists($column, $method = 'set'.ucfirst($option))) {
+ $column->{$method}($this->mapFluentValueToDoctrine($option, $value));
+ }
+ }
+ }
+ }
+
+ return $table;
+ }
+
+ /**
+ * Get the Doctrine column instance for a column change.
+ *
+ * @param \Doctrine\DBAL\Schema\Table $table
+ * @param \Illuminate\Support\Fluent $fluent
+ * @return \Doctrine\DBAL\Schema\Column
+ */
+ protected function getDoctrineColumnForChange(Table $table, Fluent $fluent)
+ {
+ return $table->changeColumn(
+ $fluent['name'], $this->getDoctrineColumnChangeOptions($fluent)
+ )->getColumn($fluent['name']);
+ }
+
+ /**
+ * Get the Doctrine column change options.
+ *
+ * @param \Illuminate\Support\Fluent $fluent
+ * @return array
+ */
+ protected function getDoctrineColumnChangeOptions(Fluent $fluent)
+ {
+ $options = ['type' => $this->getDoctrineColumnType($fluent['type'])];
+
+ if (in_array($fluent['type'], ['text', 'mediumText', 'longText'])) {
+ $options['length'] = $this->calculateDoctrineTextLength($fluent['type']);
+ }
+
+ return $options;
+ }
+
+ /**
+ * Get the doctrine column type.
+ *
+ * @param string $type
+ * @return \Doctrine\DBAL\Types\Type
+ */
+ protected function getDoctrineColumnType($type)
+ {
+ $type = strtolower($type);
+
+ switch ($type) {
+ case 'biginteger':
+ $type = 'bigint';
+ break;
+ case 'smallinteger':
+ $type = 'smallint';
+ break;
+ case 'mediumtext':
+ case 'longtext':
+ $type = 'text';
+ break;
+ }
+
+ return Type::getType($type);
+ }
+
+ /**
+ * Calculate the proper column length to force the Doctrine text type.
+ *
+ * @param string $type
+ * @return int
+ */
+ protected function calculateDoctrineTextLength($type)
+ {
+ switch ($type) {
+ case 'mediumText':
+ return 65535 + 1;
+
+ case 'longText':
+ return 16777215 + 1;
+
+ default:
+ return 255 + 1;
+ }
+ }
+
+ /**
+ * Get the matching Doctrine option for a given Fluent attribute name.
+ *
+ * @param string $attribute
+ * @return string|null
+ */
+ protected function mapFluentOptionToDoctrine($attribute)
+ {
+ switch ($attribute) {
+ case 'type':
+ case 'name':
+ return;
+
+ case 'nullable':
+ return 'notnull';
+
+ case 'total':
+ return 'precision';
+
+ case 'places':
+ return 'scale';
+
+ default:
+ return $attribute;
+ }
+ }
+
+ /**
+ * Get the matching Doctrine value for a given Fluent attribute.
+ *
+ * @param string $option
+ * @param mixed $value
+ * @return mixed
+ */
+ protected function mapFluentValueToDoctrine($option, $value)
+ {
+ return $option == 'notnull' ? ! $value : $value;
+ }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php b/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php
new file mode 100755
index 00000000..1601fba3
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php
@@ -0,0 +1,713 @@
+getColumns($blueprint));
+
+ $sql = $blueprint->temporary ? 'create temporary' : 'create';
+
+ $sql .= ' table '.$this->wrapTable($blueprint)." ($columns)";
+
+ // Once we have the primary SQL, we can add the encoding option to the SQL for
+ // the table. Then, we can check if a storage engine has been supplied for
+ // the table. If so, we will add the engine declaration to the SQL query.
+ $sql = $this->compileCreateEncoding($sql, $connection, $blueprint);
+
+ if (isset($blueprint->engine)) {
+ $sql .= ' engine = '.$blueprint->engine;
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Append the character set specifications to a command.
+ *
+ * @param string $sql
+ * @param \Illuminate\Database\Connection $connection
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @return string
+ */
+ protected function compileCreateEncoding($sql, Connection $connection, Blueprint $blueprint)
+ {
+ if (isset($blueprint->charset)) {
+ $sql .= ' default character set '.$blueprint->charset;
+ } elseif (! is_null($charset = $connection->getConfig('charset'))) {
+ $sql .= ' default character set '.$charset;
+ }
+
+ if (isset($blueprint->collation)) {
+ $sql .= ' collate '.$blueprint->collation;
+ } elseif (! is_null($collation = $connection->getConfig('collation'))) {
+ $sql .= ' collate '.$collation;
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Compile an add column command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileAdd(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ $columns = $this->prefixArray('add', $this->getColumns($blueprint));
+
+ return 'alter table '.$table.' '.implode(', ', $columns);
+ }
+
+ /**
+ * Compile a primary key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compilePrimary(Blueprint $blueprint, Fluent $command)
+ {
+ $command->name(null);
+
+ return $this->compileKey($blueprint, $command, 'primary key');
+ }
+
+ /**
+ * Compile a unique key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileUnique(Blueprint $blueprint, Fluent $command)
+ {
+ return $this->compileKey($blueprint, $command, 'unique');
+ }
+
+ /**
+ * Compile a plain index key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileIndex(Blueprint $blueprint, Fluent $command)
+ {
+ return $this->compileKey($blueprint, $command, 'index');
+ }
+
+ /**
+ * Compile an index creation command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @param string $type
+ * @return string
+ */
+ protected function compileKey(Blueprint $blueprint, Fluent $command, $type)
+ {
+ $columns = $this->columnize($command->columns);
+
+ $table = $this->wrapTable($blueprint);
+
+ return "alter table {$table} add {$type} `{$command->index}`($columns)";
+ }
+
+ /**
+ * Compile a drop table command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDrop(Blueprint $blueprint, Fluent $command)
+ {
+ return 'drop table '.$this->wrapTable($blueprint);
+ }
+
+ /**
+ * Compile a drop table (if exists) command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
+ {
+ return 'drop table if exists '.$this->wrapTable($blueprint);
+ }
+
+ /**
+ * Compile a drop column command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropColumn(Blueprint $blueprint, Fluent $command)
+ {
+ $columns = $this->prefixArray('drop', $this->wrapArray($command->columns));
+
+ $table = $this->wrapTable($blueprint);
+
+ return 'alter table '.$table.' '.implode(', ', $columns);
+ }
+
+ /**
+ * Compile a drop primary key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
+ {
+ return 'alter table '.$this->wrapTable($blueprint).' drop primary key';
+ }
+
+ /**
+ * Compile a drop unique key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropUnique(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ return "alter table {$table} drop index `{$command->index}`";
+ }
+
+ /**
+ * Compile a drop index command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropIndex(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ return "alter table {$table} drop index `{$command->index}`";
+ }
+
+ /**
+ * Compile a drop foreign key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropForeign(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ return "alter table {$table} drop foreign key `{$command->index}`";
+ }
+
+ /**
+ * Compile a rename table command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileRename(Blueprint $blueprint, Fluent $command)
+ {
+ $from = $this->wrapTable($blueprint);
+
+ return "rename table {$from} to ".$this->wrapTable($command->to);
+ }
+
+ /**
+ * Create the column definition for a char type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeChar(Fluent $column)
+ {
+ return "char({$column->length})";
+ }
+
+ /**
+ * Create the column definition for a string type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeString(Fluent $column)
+ {
+ return "varchar({$column->length})";
+ }
+
+ /**
+ * Create the column definition for a text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeText(Fluent $column)
+ {
+ return 'text';
+ }
+
+ /**
+ * Create the column definition for a medium text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeMediumText(Fluent $column)
+ {
+ return 'mediumtext';
+ }
+
+ /**
+ * Create the column definition for a long text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeLongText(Fluent $column)
+ {
+ return 'longtext';
+ }
+
+ /**
+ * Create the column definition for a big integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBigInteger(Fluent $column)
+ {
+ return 'bigint';
+ }
+
+ /**
+ * Create the column definition for a integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeInteger(Fluent $column)
+ {
+ return 'int';
+ }
+
+ /**
+ * Create the column definition for a medium integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeMediumInteger(Fluent $column)
+ {
+ return 'mediumint';
+ }
+
+ /**
+ * Create the column definition for a tiny integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTinyInteger(Fluent $column)
+ {
+ return 'tinyint';
+ }
+
+ /**
+ * Create the column definition for a small integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeSmallInteger(Fluent $column)
+ {
+ return 'smallint';
+ }
+
+ /**
+ * Create the column definition for a float type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeFloat(Fluent $column)
+ {
+ return $this->typeDouble($column);
+ }
+
+ /**
+ * Create the column definition for a double type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDouble(Fluent $column)
+ {
+ if ($column->total && $column->places) {
+ return "double({$column->total}, {$column->places})";
+ }
+
+ return 'double';
+ }
+
+ /**
+ * Create the column definition for a decimal type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDecimal(Fluent $column)
+ {
+ return "decimal({$column->total}, {$column->places})";
+ }
+
+ /**
+ * Create the column definition for a boolean type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBoolean(Fluent $column)
+ {
+ return 'tinyint(1)';
+ }
+
+ /**
+ * Create the column definition for an enum type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeEnum(Fluent $column)
+ {
+ return "enum('".implode("', '", $column->allowed)."')";
+ }
+
+ /**
+ * Create the column definition for a json type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeJson(Fluent $column)
+ {
+ return 'json';
+ }
+
+ /**
+ * Create the column definition for a jsonb type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeJsonb(Fluent $column)
+ {
+ return 'json';
+ }
+
+ /**
+ * Create the column definition for a date type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDate(Fluent $column)
+ {
+ return 'date';
+ }
+
+ /**
+ * Create the column definition for a date-time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDateTime(Fluent $column)
+ {
+ return 'datetime';
+ }
+
+ /**
+ * Create the column definition for a date-time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDateTimeTz(Fluent $column)
+ {
+ return 'datetime';
+ }
+
+ /**
+ * Create the column definition for a time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTime(Fluent $column)
+ {
+ return 'time';
+ }
+
+ /**
+ * Create the column definition for a time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimeTz(Fluent $column)
+ {
+ return 'time';
+ }
+
+ /**
+ * Create the column definition for a timestamp type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimestamp(Fluent $column)
+ {
+ if ($column->useCurrent) {
+ return 'timestamp default CURRENT_TIMESTAMP';
+ }
+
+ return 'timestamp';
+ }
+
+ /**
+ * Create the column definition for a timestamp type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimestampTz(Fluent $column)
+ {
+ if ($column->useCurrent) {
+ return 'timestamp default CURRENT_TIMESTAMP';
+ }
+
+ return 'timestamp';
+ }
+
+ /**
+ * Create the column definition for a binary type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBinary(Fluent $column)
+ {
+ return 'blob';
+ }
+
+ /**
+ * Create the column definition for a uuid type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeUuid(Fluent $column)
+ {
+ return 'char(36)';
+ }
+
+ /**
+ * Get the SQL for an unsigned column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyUnsigned(Blueprint $blueprint, Fluent $column)
+ {
+ if ($column->unsigned) {
+ return ' unsigned';
+ }
+ }
+
+ /**
+ * Get the SQL for a character set column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyCharset(Blueprint $blueprint, Fluent $column)
+ {
+ if (! is_null($column->charset)) {
+ return ' character set '.$column->charset;
+ }
+ }
+
+ /**
+ * Get the SQL for a collation column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyCollate(Blueprint $blueprint, Fluent $column)
+ {
+ if (! is_null($column->collation)) {
+ return ' collate '.$column->collation;
+ }
+ }
+
+ /**
+ * Get the SQL for a nullable column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyNullable(Blueprint $blueprint, Fluent $column)
+ {
+ return $column->nullable ? ' null' : ' not null';
+ }
+
+ /**
+ * Get the SQL for a default column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyDefault(Blueprint $blueprint, Fluent $column)
+ {
+ if (! is_null($column->default)) {
+ return ' default '.$this->getDefaultValue($column->default);
+ }
+ }
+
+ /**
+ * Get the SQL for an auto-increment column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
+ {
+ if (in_array($column->type, $this->serials) && $column->autoIncrement) {
+ return ' auto_increment primary key';
+ }
+ }
+
+ /**
+ * Get the SQL for a "first" column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyFirst(Blueprint $blueprint, Fluent $column)
+ {
+ if (! is_null($column->first)) {
+ return ' first';
+ }
+ }
+
+ /**
+ * Get the SQL for an "after" column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyAfter(Blueprint $blueprint, Fluent $column)
+ {
+ if (! is_null($column->after)) {
+ return ' after '.$this->wrap($column->after);
+ }
+ }
+
+ /**
+ * Get the SQL for a "comment" column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyComment(Blueprint $blueprint, Fluent $column)
+ {
+ if (! is_null($column->comment)) {
+ return ' comment "'.$column->comment.'"';
+ }
+ }
+
+ /**
+ * Wrap a single string in keyword identifiers.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function wrapValue($value)
+ {
+ if ($value === '*') {
+ return $value;
+ }
+
+ return '`'.str_replace('`', '``', $value).'`';
+ }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php b/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php
new file mode 100755
index 00000000..129292b3
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php
@@ -0,0 +1,568 @@
+getColumns($blueprint));
+
+ $sql = $blueprint->temporary ? 'create temporary' : 'create';
+
+ $sql .= ' table '.$this->wrapTable($blueprint)." ($columns)";
+
+ return $sql;
+ }
+
+ /**
+ * Compile a create table command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileAdd(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ $columns = $this->prefixArray('add column', $this->getColumns($blueprint));
+
+ return 'alter table '.$table.' '.implode(', ', $columns);
+ }
+
+ /**
+ * Compile a primary key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compilePrimary(Blueprint $blueprint, Fluent $command)
+ {
+ $columns = $this->columnize($command->columns);
+
+ return 'alter table '.$this->wrapTable($blueprint)." add primary key ({$columns})";
+ }
+
+ /**
+ * Compile a unique key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileUnique(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ $columns = $this->columnize($command->columns);
+
+ return "alter table $table add constraint {$command->index} unique ($columns)";
+ }
+
+ /**
+ * Compile a plain index key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileIndex(Blueprint $blueprint, Fluent $command)
+ {
+ $columns = $this->columnize($command->columns);
+
+ return "create index {$command->index} on ".$this->wrapTable($blueprint)." ({$columns})";
+ }
+
+ /**
+ * Compile a drop table command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDrop(Blueprint $blueprint, Fluent $command)
+ {
+ return 'drop table '.$this->wrapTable($blueprint);
+ }
+
+ /**
+ * Compile a drop table (if exists) command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
+ {
+ return 'drop table if exists '.$this->wrapTable($blueprint);
+ }
+
+ /**
+ * Compile a drop column command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropColumn(Blueprint $blueprint, Fluent $command)
+ {
+ $columns = $this->prefixArray('drop column', $this->wrapArray($command->columns));
+
+ $table = $this->wrapTable($blueprint);
+
+ return 'alter table '.$table.' '.implode(', ', $columns);
+ }
+
+ /**
+ * Compile a drop primary key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $blueprint->getTable();
+
+ return 'alter table '.$this->wrapTable($blueprint)." drop constraint {$table}_pkey";
+ }
+
+ /**
+ * Compile a drop unique key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropUnique(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ return "alter table {$table} drop constraint {$command->index}";
+ }
+
+ /**
+ * Compile a drop index command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropIndex(Blueprint $blueprint, Fluent $command)
+ {
+ return "drop index {$command->index}";
+ }
+
+ /**
+ * Compile a drop foreign key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropForeign(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ return "alter table {$table} drop constraint {$command->index}";
+ }
+
+ /**
+ * Compile a rename table command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileRename(Blueprint $blueprint, Fluent $command)
+ {
+ $from = $this->wrapTable($blueprint);
+
+ return "alter table {$from} rename to ".$this->wrapTable($command->to);
+ }
+
+ /**
+ * Create the column definition for a char type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeChar(Fluent $column)
+ {
+ return "char({$column->length})";
+ }
+
+ /**
+ * Create the column definition for a string type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeString(Fluent $column)
+ {
+ return "varchar({$column->length})";
+ }
+
+ /**
+ * Create the column definition for a text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeText(Fluent $column)
+ {
+ return 'text';
+ }
+
+ /**
+ * Create the column definition for a medium text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeMediumText(Fluent $column)
+ {
+ return 'text';
+ }
+
+ /**
+ * Create the column definition for a long text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeLongText(Fluent $column)
+ {
+ return 'text';
+ }
+
+ /**
+ * Create the column definition for a integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeInteger(Fluent $column)
+ {
+ return $column->autoIncrement ? 'serial' : 'integer';
+ }
+
+ /**
+ * Create the column definition for a big integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBigInteger(Fluent $column)
+ {
+ return $column->autoIncrement ? 'bigserial' : 'bigint';
+ }
+
+ /**
+ * Create the column definition for a medium integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeMediumInteger(Fluent $column)
+ {
+ return $column->autoIncrement ? 'serial' : 'integer';
+ }
+
+ /**
+ * Create the column definition for a tiny integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTinyInteger(Fluent $column)
+ {
+ return $column->autoIncrement ? 'smallserial' : 'smallint';
+ }
+
+ /**
+ * Create the column definition for a small integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeSmallInteger(Fluent $column)
+ {
+ return $column->autoIncrement ? 'smallserial' : 'smallint';
+ }
+
+ /**
+ * Create the column definition for a float type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeFloat(Fluent $column)
+ {
+ return $this->typeDouble($column);
+ }
+
+ /**
+ * Create the column definition for a double type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDouble(Fluent $column)
+ {
+ return 'double precision';
+ }
+
+ /**
+ * Create the column definition for a decimal type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDecimal(Fluent $column)
+ {
+ return "decimal({$column->total}, {$column->places})";
+ }
+
+ /**
+ * Create the column definition for a boolean type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBoolean(Fluent $column)
+ {
+ return 'boolean';
+ }
+
+ /**
+ * Create the column definition for an enum type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeEnum(Fluent $column)
+ {
+ $allowed = array_map(function ($a) {
+ return "'".$a."'";
+ }, $column->allowed);
+
+ return "varchar(255) check (\"{$column->name}\" in (".implode(', ', $allowed).'))';
+ }
+
+ /**
+ * Create the column definition for a json type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeJson(Fluent $column)
+ {
+ return 'json';
+ }
+
+ /**
+ * Create the column definition for a jsonb type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeJsonb(Fluent $column)
+ {
+ return 'jsonb';
+ }
+
+ /**
+ * Create the column definition for a date type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDate(Fluent $column)
+ {
+ return 'date';
+ }
+
+ /**
+ * Create the column definition for a date-time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDateTime(Fluent $column)
+ {
+ return 'timestamp(0) without time zone';
+ }
+
+ /**
+ * Create the column definition for a date-time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDateTimeTz(Fluent $column)
+ {
+ return 'timestamp(0) with time zone';
+ }
+
+ /**
+ * Create the column definition for a time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTime(Fluent $column)
+ {
+ return 'time(0) without time zone';
+ }
+
+ /**
+ * Create the column definition for a time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimeTz(Fluent $column)
+ {
+ return 'time(0) with time zone';
+ }
+
+ /**
+ * Create the column definition for a timestamp type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimestamp(Fluent $column)
+ {
+ if ($column->useCurrent) {
+ return 'timestamp(0) without time zone default CURRENT_TIMESTAMP(0)';
+ }
+
+ return 'timestamp(0) without time zone';
+ }
+
+ /**
+ * Create the column definition for a timestamp type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimestampTz(Fluent $column)
+ {
+ if ($column->useCurrent) {
+ return 'timestamp(0) with time zone default CURRENT_TIMESTAMP(0)';
+ }
+
+ return 'timestamp(0) with time zone';
+ }
+
+ /**
+ * Create the column definition for a binary type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBinary(Fluent $column)
+ {
+ return 'bytea';
+ }
+
+ /**
+ * Create the column definition for a uuid type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeUuid(Fluent $column)
+ {
+ return 'uuid';
+ }
+
+ /**
+ * Get the SQL for a nullable column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyNullable(Blueprint $blueprint, Fluent $column)
+ {
+ return $column->nullable ? ' null' : ' not null';
+ }
+
+ /**
+ * Get the SQL for a default column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyDefault(Blueprint $blueprint, Fluent $column)
+ {
+ if (! is_null($column->default)) {
+ return ' default '.$this->getDefaultValue($column->default);
+ }
+ }
+
+ /**
+ * Get the SQL for an auto-increment column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
+ {
+ if (in_array($column->type, $this->serials) && $column->autoIncrement) {
+ return ' primary key';
+ }
+ }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php b/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php
new file mode 100755
index 00000000..a257de7d
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php
@@ -0,0 +1,625 @@
+getColumns($blueprint));
+
+ $sql = $blueprint->temporary ? 'create temporary' : 'create';
+
+ $sql .= ' table '.$this->wrapTable($blueprint)." ($columns";
+
+ // SQLite forces primary keys to be added when the table is initially created
+ // so we will need to check for a primary key commands and add the columns
+ // to the table's declaration here so they can be created on the tables.
+ $sql .= (string) $this->addForeignKeys($blueprint);
+
+ $sql .= (string) $this->addPrimaryKeys($blueprint);
+
+ return $sql.')';
+ }
+
+ /**
+ * Get the foreign key syntax for a table creation statement.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @return string|null
+ */
+ protected function addForeignKeys(Blueprint $blueprint)
+ {
+ $sql = '';
+
+ $foreigns = $this->getCommandsByName($blueprint, 'foreign');
+
+ // Once we have all the foreign key commands for the table creation statement
+ // we'll loop through each of them and add them to the create table SQL we
+ // are building, since SQLite needs foreign keys on the tables creation.
+ foreach ($foreigns as $foreign) {
+ $sql .= $this->getForeignKey($foreign);
+
+ if (! is_null($foreign->onDelete)) {
+ $sql .= " on delete {$foreign->onDelete}";
+ }
+
+ if (! is_null($foreign->onUpdate)) {
+ $sql .= " on update {$foreign->onUpdate}";
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Get the SQL for the foreign key.
+ *
+ * @param \Illuminate\Support\Fluent $foreign
+ * @return string
+ */
+ protected function getForeignKey($foreign)
+ {
+ $on = $this->wrapTable($foreign->on);
+
+ // We need to columnize the columns that the foreign key is being defined for
+ // so that it is a properly formatted list. Once we have done this, we can
+ // return the foreign key SQL declaration to the calling method for use.
+ $columns = $this->columnize($foreign->columns);
+
+ $onColumns = $this->columnize((array) $foreign->references);
+
+ return ", foreign key($columns) references $on($onColumns)";
+ }
+
+ /**
+ * Get the primary key syntax for a table creation statement.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @return string|null
+ */
+ protected function addPrimaryKeys(Blueprint $blueprint)
+ {
+ $primary = $this->getCommandByName($blueprint, 'primary');
+
+ if (! is_null($primary)) {
+ $columns = $this->columnize($primary->columns);
+
+ return ", primary key ({$columns})";
+ }
+ }
+
+ /**
+ * Compile alter table commands for adding columns.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return array
+ */
+ public function compileAdd(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ $columns = $this->prefixArray('add column', $this->getColumns($blueprint));
+
+ $statements = [];
+
+ foreach ($columns as $column) {
+ $statements[] = 'alter table '.$table.' '.$column;
+ }
+
+ return $statements;
+ }
+
+ /**
+ * Compile a unique key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileUnique(Blueprint $blueprint, Fluent $command)
+ {
+ $columns = $this->columnize($command->columns);
+
+ $table = $this->wrapTable($blueprint);
+
+ return "create unique index {$command->index} on {$table} ({$columns})";
+ }
+
+ /**
+ * Compile a plain index key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileIndex(Blueprint $blueprint, Fluent $command)
+ {
+ $columns = $this->columnize($command->columns);
+
+ $table = $this->wrapTable($blueprint);
+
+ return "create index {$command->index} on {$table} ({$columns})";
+ }
+
+ /**
+ * Compile a foreign key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileForeign(Blueprint $blueprint, Fluent $command)
+ {
+ // Handled on table creation...
+ }
+
+ /**
+ * Compile a drop table command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDrop(Blueprint $blueprint, Fluent $command)
+ {
+ return 'drop table '.$this->wrapTable($blueprint);
+ }
+
+ /**
+ * Compile a drop table (if exists) command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
+ {
+ return 'drop table if exists '.$this->wrapTable($blueprint);
+ }
+
+ /**
+ * Compile a drop column command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @param \Illuminate\Database\Connection $connection
+ * @return array
+ */
+ public function compileDropColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
+ {
+ $schema = $connection->getDoctrineSchemaManager();
+
+ $tableDiff = $this->getDoctrineTableDiff($blueprint, $schema);
+
+ foreach ($command->columns as $name) {
+ $column = $connection->getDoctrineColumn($blueprint->getTable(), $name);
+
+ $tableDiff->removedColumns[$name] = $column;
+ }
+
+ return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff);
+ }
+
+ /**
+ * Compile a drop unique key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropUnique(Blueprint $blueprint, Fluent $command)
+ {
+ return "drop index {$command->index}";
+ }
+
+ /**
+ * Compile a drop index command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropIndex(Blueprint $blueprint, Fluent $command)
+ {
+ return "drop index {$command->index}";
+ }
+
+ /**
+ * Compile a rename table command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileRename(Blueprint $blueprint, Fluent $command)
+ {
+ $from = $this->wrapTable($blueprint);
+
+ return "alter table {$from} rename to ".$this->wrapTable($command->to);
+ }
+
+ /**
+ * Create the column definition for a char type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeChar(Fluent $column)
+ {
+ return 'varchar';
+ }
+
+ /**
+ * Create the column definition for a string type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeString(Fluent $column)
+ {
+ return 'varchar';
+ }
+
+ /**
+ * Create the column definition for a text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeText(Fluent $column)
+ {
+ return 'text';
+ }
+
+ /**
+ * Create the column definition for a medium text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeMediumText(Fluent $column)
+ {
+ return 'text';
+ }
+
+ /**
+ * Create the column definition for a long text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeLongText(Fluent $column)
+ {
+ return 'text';
+ }
+
+ /**
+ * Create the column definition for a integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeInteger(Fluent $column)
+ {
+ return 'integer';
+ }
+
+ /**
+ * Create the column definition for a big integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBigInteger(Fluent $column)
+ {
+ return 'integer';
+ }
+
+ /**
+ * Create the column definition for a medium integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeMediumInteger(Fluent $column)
+ {
+ return 'integer';
+ }
+
+ /**
+ * Create the column definition for a tiny integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTinyInteger(Fluent $column)
+ {
+ return 'integer';
+ }
+
+ /**
+ * Create the column definition for a small integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeSmallInteger(Fluent $column)
+ {
+ return 'integer';
+ }
+
+ /**
+ * Create the column definition for a float type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeFloat(Fluent $column)
+ {
+ return 'float';
+ }
+
+ /**
+ * Create the column definition for a double type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDouble(Fluent $column)
+ {
+ return 'float';
+ }
+
+ /**
+ * Create the column definition for a decimal type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDecimal(Fluent $column)
+ {
+ return 'numeric';
+ }
+
+ /**
+ * Create the column definition for a boolean type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBoolean(Fluent $column)
+ {
+ return 'tinyint(1)';
+ }
+
+ /**
+ * Create the column definition for an enum type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeEnum(Fluent $column)
+ {
+ return 'varchar';
+ }
+
+ /**
+ * Create the column definition for a json type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeJson(Fluent $column)
+ {
+ return 'text';
+ }
+
+ /**
+ * Create the column definition for a jsonb type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeJsonb(Fluent $column)
+ {
+ return 'text';
+ }
+
+ /**
+ * Create the column definition for a date type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDate(Fluent $column)
+ {
+ return 'date';
+ }
+
+ /**
+ * Create the column definition for a date-time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDateTime(Fluent $column)
+ {
+ return 'datetime';
+ }
+
+ /**
+ * Create the column definition for a date-time type.
+ *
+ * Note: "SQLite does not have a storage class set aside for storing dates and/or times."
+ * @link https://www.sqlite.org/datatype3.html
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDateTimeTz(Fluent $column)
+ {
+ return 'datetime';
+ }
+
+ /**
+ * Create the column definition for a time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTime(Fluent $column)
+ {
+ return 'time';
+ }
+
+ /**
+ * Create the column definition for a time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimeTz(Fluent $column)
+ {
+ return 'time';
+ }
+
+ /**
+ * Create the column definition for a timestamp type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimestamp(Fluent $column)
+ {
+ if ($column->useCurrent) {
+ return 'datetime default CURRENT_TIMESTAMP';
+ }
+
+ return 'datetime';
+ }
+
+ /**
+ * Create the column definition for a timestamp type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimestampTz(Fluent $column)
+ {
+ if ($column->useCurrent) {
+ return 'datetime default CURRENT_TIMESTAMP';
+ }
+
+ return 'datetime';
+ }
+
+ /**
+ * Create the column definition for a binary type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBinary(Fluent $column)
+ {
+ return 'blob';
+ }
+
+ /**
+ * Create the column definition for a uuid type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeUuid(Fluent $column)
+ {
+ return 'varchar';
+ }
+
+ /**
+ * Get the SQL for a nullable column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyNullable(Blueprint $blueprint, Fluent $column)
+ {
+ return $column->nullable ? ' null' : ' not null';
+ }
+
+ /**
+ * Get the SQL for a default column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyDefault(Blueprint $blueprint, Fluent $column)
+ {
+ if (! is_null($column->default)) {
+ return ' default '.$this->getDefaultValue($column->default);
+ }
+ }
+
+ /**
+ * Get the SQL for an auto-increment column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
+ {
+ if (in_array($column->type, $this->serials) && $column->autoIncrement) {
+ return ' primary key autoincrement';
+ }
+ }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php b/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php
new file mode 100755
index 00000000..ba5d245a
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php
@@ -0,0 +1,570 @@
+getColumns($blueprint));
+
+ return 'create table '.$this->wrapTable($blueprint)." ($columns)";
+ }
+
+ /**
+ * Compile a create table command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileAdd(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ $columns = $this->getColumns($blueprint);
+
+ return 'alter table '.$table.' add '.implode(', ', $columns);
+ }
+
+ /**
+ * Compile a primary key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compilePrimary(Blueprint $blueprint, Fluent $command)
+ {
+ $columns = $this->columnize($command->columns);
+
+ $table = $this->wrapTable($blueprint);
+
+ return "alter table {$table} add constraint {$command->index} primary key ({$columns})";
+ }
+
+ /**
+ * Compile a unique key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileUnique(Blueprint $blueprint, Fluent $command)
+ {
+ $columns = $this->columnize($command->columns);
+
+ $table = $this->wrapTable($blueprint);
+
+ return "create unique index {$command->index} on {$table} ({$columns})";
+ }
+
+ /**
+ * Compile a plain index key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileIndex(Blueprint $blueprint, Fluent $command)
+ {
+ $columns = $this->columnize($command->columns);
+
+ $table = $this->wrapTable($blueprint);
+
+ return "create index {$command->index} on {$table} ({$columns})";
+ }
+
+ /**
+ * Compile a drop table command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDrop(Blueprint $blueprint, Fluent $command)
+ {
+ return 'drop table '.$this->wrapTable($blueprint);
+ }
+
+ /**
+ * Compile a drop table (if exists) command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
+ {
+ return 'if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = \''.$blueprint->getTable().'\') drop table '.$blueprint->getTable();
+ }
+
+ /**
+ * Compile a drop column command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropColumn(Blueprint $blueprint, Fluent $command)
+ {
+ $columns = $this->wrapArray($command->columns);
+
+ $table = $this->wrapTable($blueprint);
+
+ return 'alter table '.$table.' drop column '.implode(', ', $columns);
+ }
+
+ /**
+ * Compile a drop primary key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ return "alter table {$table} drop constraint {$command->index}";
+ }
+
+ /**
+ * Compile a drop unique key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropUnique(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ return "drop index {$command->index} on {$table}";
+ }
+
+ /**
+ * Compile a drop index command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropIndex(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ return "drop index {$command->index} on {$table}";
+ }
+
+ /**
+ * Compile a drop foreign key command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileDropForeign(Blueprint $blueprint, Fluent $command)
+ {
+ $table = $this->wrapTable($blueprint);
+
+ return "alter table {$table} drop constraint {$command->index}";
+ }
+
+ /**
+ * Compile a rename table command.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $command
+ * @return string
+ */
+ public function compileRename(Blueprint $blueprint, Fluent $command)
+ {
+ $from = $this->wrapTable($blueprint);
+
+ return "sp_rename {$from}, ".$this->wrapTable($command->to);
+ }
+
+ /**
+ * Create the column definition for a char type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeChar(Fluent $column)
+ {
+ return "nchar({$column->length})";
+ }
+
+ /**
+ * Create the column definition for a string type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeString(Fluent $column)
+ {
+ return "nvarchar({$column->length})";
+ }
+
+ /**
+ * Create the column definition for a text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeText(Fluent $column)
+ {
+ return 'nvarchar(max)';
+ }
+
+ /**
+ * Create the column definition for a medium text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeMediumText(Fluent $column)
+ {
+ return 'nvarchar(max)';
+ }
+
+ /**
+ * Create the column definition for a long text type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeLongText(Fluent $column)
+ {
+ return 'nvarchar(max)';
+ }
+
+ /**
+ * Create the column definition for a integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeInteger(Fluent $column)
+ {
+ return 'int';
+ }
+
+ /**
+ * Create the column definition for a big integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBigInteger(Fluent $column)
+ {
+ return 'bigint';
+ }
+
+ /**
+ * Create the column definition for a medium integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeMediumInteger(Fluent $column)
+ {
+ return 'int';
+ }
+
+ /**
+ * Create the column definition for a tiny integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTinyInteger(Fluent $column)
+ {
+ return 'tinyint';
+ }
+
+ /**
+ * Create the column definition for a small integer type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeSmallInteger(Fluent $column)
+ {
+ return 'smallint';
+ }
+
+ /**
+ * Create the column definition for a float type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeFloat(Fluent $column)
+ {
+ return 'float';
+ }
+
+ /**
+ * Create the column definition for a double type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDouble(Fluent $column)
+ {
+ return 'float';
+ }
+
+ /**
+ * Create the column definition for a decimal type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDecimal(Fluent $column)
+ {
+ return "decimal({$column->total}, {$column->places})";
+ }
+
+ /**
+ * Create the column definition for a boolean type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBoolean(Fluent $column)
+ {
+ return 'bit';
+ }
+
+ /**
+ * Create the column definition for an enum type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeEnum(Fluent $column)
+ {
+ return 'nvarchar(255)';
+ }
+
+ /**
+ * Create the column definition for a json type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeJson(Fluent $column)
+ {
+ return 'nvarchar(max)';
+ }
+
+ /**
+ * Create the column definition for a jsonb type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeJsonb(Fluent $column)
+ {
+ return 'nvarchar(max)';
+ }
+
+ /**
+ * Create the column definition for a date type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDate(Fluent $column)
+ {
+ return 'date';
+ }
+
+ /**
+ * Create the column definition for a date-time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDateTime(Fluent $column)
+ {
+ return 'datetime';
+ }
+
+ /**
+ * Create the column definition for a date-time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeDateTimeTz(Fluent $column)
+ {
+ return 'datetimeoffset(0)';
+ }
+
+ /**
+ * Create the column definition for a time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTime(Fluent $column)
+ {
+ return 'time';
+ }
+
+ /**
+ * Create the column definition for a time type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimeTz(Fluent $column)
+ {
+ return 'time';
+ }
+
+ /**
+ * Create the column definition for a timestamp type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimestamp(Fluent $column)
+ {
+ if ($column->useCurrent) {
+ return 'datetime default CURRENT_TIMESTAMP';
+ }
+
+ return 'datetime';
+ }
+
+ /**
+ * Create the column definition for a timestamp type.
+ *
+ * @link https://msdn.microsoft.com/en-us/library/bb630289(v=sql.120).aspx
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeTimestampTz(Fluent $column)
+ {
+ if ($column->useCurrent) {
+ return 'datetimeoffset(0) default CURRENT_TIMESTAMP';
+ }
+
+ return 'datetimeoffset(0)';
+ }
+
+ /**
+ * Create the column definition for a binary type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeBinary(Fluent $column)
+ {
+ return 'varbinary(max)';
+ }
+
+ /**
+ * Create the column definition for a uuid type.
+ *
+ * @param \Illuminate\Support\Fluent $column
+ * @return string
+ */
+ protected function typeUuid(Fluent $column)
+ {
+ return 'uniqueidentifier';
+ }
+
+ /**
+ * Get the SQL for a nullable column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyNullable(Blueprint $blueprint, Fluent $column)
+ {
+ return $column->nullable ? ' null' : ' not null';
+ }
+
+ /**
+ * Get the SQL for a default column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyDefault(Blueprint $blueprint, Fluent $column)
+ {
+ if (! is_null($column->default)) {
+ return ' default '.$this->getDefaultValue($column->default);
+ }
+ }
+
+ /**
+ * Get the SQL for an auto-increment column modifier.
+ *
+ * @param \Illuminate\Database\Schema\Blueprint $blueprint
+ * @param \Illuminate\Support\Fluent $column
+ * @return string|null
+ */
+ protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
+ {
+ if (in_array($column->type, $this->serials) && $column->autoIncrement) {
+ return ' identity primary key';
+ }
+ }
+}
diff --git a/vendor/illuminate/database/Schema/MySqlBuilder.php b/vendor/illuminate/database/Schema/MySqlBuilder.php
new file mode 100755
index 00000000..e0b0ade9
--- /dev/null
+++ b/vendor/illuminate/database/Schema/MySqlBuilder.php
@@ -0,0 +1,42 @@
+grammar->compileTableExists();
+
+ $database = $this->connection->getDatabaseName();
+
+ $table = $this->connection->getTablePrefix().$table;
+
+ return count($this->connection->select($sql, [$database, $table])) > 0;
+ }
+
+ /**
+ * Get the column listing for a given table.
+ *
+ * @param string $table
+ * @return array
+ */
+ public function getColumnListing($table)
+ {
+ $sql = $this->grammar->compileColumnExists();
+
+ $database = $this->connection->getDatabaseName();
+
+ $table = $this->connection->getTablePrefix().$table;
+
+ $results = $this->connection->select($sql, [$database, $table]);
+
+ return $this->connection->getPostProcessor()->processColumnListing($results);
+ }
+}
diff --git a/vendor/illuminate/database/SeedServiceProvider.php b/vendor/illuminate/database/SeedServiceProvider.php
new file mode 100755
index 00000000..417e86ad
--- /dev/null
+++ b/vendor/illuminate/database/SeedServiceProvider.php
@@ -0,0 +1,54 @@
+app->singleton('seeder', function () {
+ return new Seeder;
+ });
+
+ $this->registerSeedCommand();
+
+ $this->commands('command.seed');
+ }
+
+ /**
+ * Register the seed console command.
+ *
+ * @return void
+ */
+ protected function registerSeedCommand()
+ {
+ $this->app->singleton('command.seed', function ($app) {
+ return new SeedCommand($app['db']);
+ });
+ }
+
+ /**
+ * Get the services provided by the provider.
+ *
+ * @return array
+ */
+ public function provides()
+ {
+ return ['seeder', 'command.seed'];
+ }
+}
diff --git a/vendor/illuminate/database/Seeder.php b/vendor/illuminate/database/Seeder.php
new file mode 100755
index 00000000..a9d9ef69
--- /dev/null
+++ b/vendor/illuminate/database/Seeder.php
@@ -0,0 +1,94 @@
+resolve($class)->run();
+
+ if (isset($this->command)) {
+ $this->command->getOutput()->writeln("Seeded: $class");
+ }
+ }
+
+ /**
+ * Resolve an instance of the given seeder class.
+ *
+ * @param string $class
+ * @return \Illuminate\Database\Seeder
+ */
+ protected function resolve($class)
+ {
+ if (isset($this->container)) {
+ $instance = $this->container->make($class);
+
+ $instance->setContainer($this->container);
+ } else {
+ $instance = new $class;
+ }
+
+ if (isset($this->command)) {
+ $instance->setCommand($this->command);
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Set the IoC container instance.
+ *
+ * @param \Illuminate\Container\Container $container
+ * @return $this
+ */
+ public function setContainer(Container $container)
+ {
+ $this->container = $container;
+
+ return $this;
+ }
+
+ /**
+ * Set the console command instance.
+ *
+ * @param \Illuminate\Console\Command $command
+ * @return $this
+ */
+ public function setCommand(Command $command)
+ {
+ $this->command = $command;
+
+ return $this;
+ }
+}
diff --git a/vendor/illuminate/database/SqlServerConnection.php b/vendor/illuminate/database/SqlServerConnection.php
new file mode 100755
index 00000000..fa097e2d
--- /dev/null
+++ b/vendor/illuminate/database/SqlServerConnection.php
@@ -0,0 +1,95 @@
+getDriverName() == 'sqlsrv') {
+ return parent::transaction($callback);
+ }
+
+ $this->pdo->exec('BEGIN TRAN');
+
+ // We'll simply execute the given callback within a try / catch block
+ // and if we catch any exception we can rollback the transaction
+ // so that none of the changes are persisted to the database.
+ try {
+ $result = $callback($this);
+
+ $this->pdo->exec('COMMIT TRAN');
+ }
+
+ // If we catch an exception, we will roll back so nothing gets messed
+ // up in the database. Then we'll re-throw the exception so it can
+ // be handled how the developer sees fit for their applications.
+ catch (Exception $e) {
+ $this->pdo->exec('ROLLBACK TRAN');
+
+ throw $e;
+ } catch (Throwable $e) {
+ $this->pdo->exec('ROLLBACK TRAN');
+
+ throw $e;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get the default query grammar instance.
+ *
+ * @return \Illuminate\Database\Query\Grammars\SqlServerGrammar
+ */
+ protected function getDefaultQueryGrammar()
+ {
+ return $this->withTablePrefix(new QueryGrammar);
+ }
+
+ /**
+ * Get the default schema grammar instance.
+ *
+ * @return \Illuminate\Database\Schema\Grammars\SqlServerGrammar
+ */
+ protected function getDefaultSchemaGrammar()
+ {
+ return $this->withTablePrefix(new SchemaGrammar);
+ }
+
+ /**
+ * Get the default post processor instance.
+ *
+ * @return \Illuminate\Database\Query\Processors\SqlServerProcessor
+ */
+ protected function getDefaultPostProcessor()
+ {
+ return new SqlServerProcessor;
+ }
+
+ /**
+ * Get the Doctrine DBAL driver.
+ *
+ * @return \Doctrine\DBAL\Driver\PDOSqlsrv\Driver
+ */
+ protected function getDoctrineDriver()
+ {
+ return new DoctrineDriver;
+ }
+}
diff --git a/vendor/illuminate/database/composer.json b/vendor/illuminate/database/composer.json
new file mode 100644
index 00000000..55a341f7
--- /dev/null
+++ b/vendor/illuminate/database/composer.json
@@ -0,0 +1,43 @@
+{
+ "name": "illuminate/database",
+ "description": "The Illuminate Database package.",
+ "license": "MIT",
+ "homepage": "http://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "keywords": ["laravel", "database", "sql", "orm"],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylorotwell@gmail.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.5.9",
+ "illuminate/container": "5.2.*",
+ "illuminate/contracts": "5.2.*",
+ "illuminate/support": "5.2.*",
+ "nesbot/carbon": "~1.20"
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Database\\": ""
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "suggest": {
+ "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).",
+ "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).",
+ "illuminate/console": "Required to use the database commands (5.2.*).",
+ "illuminate/events": "Required to use the observers with Eloquent (5.2.*).",
+ "illuminate/filesystem": "Required to use the migrations (5.2.*).",
+ "illuminate/pagination": "Required to paginate the result set (5.2.*)."
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/support/AggregateServiceProvider.php b/vendor/illuminate/support/AggregateServiceProvider.php
new file mode 100644
index 00000000..ca5f9a86
--- /dev/null
+++ b/vendor/illuminate/support/AggregateServiceProvider.php
@@ -0,0 +1,52 @@
+instances = [];
+
+ foreach ($this->providers as $provider) {
+ $this->instances[] = $this->app->register($provider);
+ }
+ }
+
+ /**
+ * Get the services provided by the provider.
+ *
+ * @return array
+ */
+ public function provides()
+ {
+ $provides = [];
+
+ foreach ($this->providers as $provider) {
+ $instance = $this->app->resolveProviderClass($provider);
+
+ $provides = array_merge($provides, $instance->provides());
+ }
+
+ return $provides;
+ }
+}
diff --git a/vendor/illuminate/support/Arr.php b/vendor/illuminate/support/Arr.php
new file mode 100755
index 00000000..13aa8918
--- /dev/null
+++ b/vendor/illuminate/support/Arr.php
@@ -0,0 +1,528 @@
+ $value) {
+ list($innerKey, $innerValue) = call_user_func($callback, $key, $value);
+
+ $results[$innerKey] = $innerValue;
+ }
+
+ return $results;
+ }
+
+ /**
+ * Collapse an array of arrays into a single array.
+ *
+ * @param array $array
+ * @return array
+ */
+ public static function collapse($array)
+ {
+ $results = [];
+
+ foreach ($array as $values) {
+ if ($values instanceof Collection) {
+ $values = $values->all();
+ } elseif (! is_array($values)) {
+ continue;
+ }
+
+ $results = array_merge($results, $values);
+ }
+
+ return $results;
+ }
+
+ /**
+ * Divide an array into two arrays. One with keys and the other with values.
+ *
+ * @param array $array
+ * @return array
+ */
+ public static function divide($array)
+ {
+ return [array_keys($array), array_values($array)];
+ }
+
+ /**
+ * Flatten a multi-dimensional associative array with dots.
+ *
+ * @param array $array
+ * @param string $prepend
+ * @return array
+ */
+ public static function dot($array, $prepend = '')
+ {
+ $results = [];
+
+ foreach ($array as $key => $value) {
+ if (is_array($value) && ! empty($value)) {
+ $results = array_merge($results, static::dot($value, $prepend.$key.'.'));
+ } else {
+ $results[$prepend.$key] = $value;
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Get all of the given array except for a specified array of items.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return array
+ */
+ public static function except($array, $keys)
+ {
+ static::forget($array, $keys);
+
+ return $array;
+ }
+
+ /**
+ * Determine if the given key exists in the provided array.
+ *
+ * @param \ArrayAccess|array $array
+ * @param string|int $key
+ * @return bool
+ */
+ public static function exists($array, $key)
+ {
+ if ($array instanceof ArrayAccess) {
+ return $array->offsetExists($key);
+ }
+
+ return array_key_exists($key, $array);
+ }
+
+ /**
+ * Return the first element in an array passing a given truth test.
+ *
+ * @param array $array
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ public static function first($array, callable $callback = null, $default = null)
+ {
+ if (is_null($callback)) {
+ return empty($array) ? value($default) : reset($array);
+ }
+
+ foreach ($array as $key => $value) {
+ if (call_user_func($callback, $key, $value)) {
+ return $value;
+ }
+ }
+
+ return value($default);
+ }
+
+ /**
+ * Return the last element in an array passing a given truth test.
+ *
+ * @param array $array
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ public static function last($array, callable $callback = null, $default = null)
+ {
+ if (is_null($callback)) {
+ return empty($array) ? value($default) : end($array);
+ }
+
+ return static::first(array_reverse($array), $callback, $default);
+ }
+
+ /**
+ * Flatten a multi-dimensional array into a single level.
+ *
+ * @param array $array
+ * @param int $depth
+ * @return array
+ */
+ public static function flatten($array, $depth = INF)
+ {
+ $result = [];
+
+ foreach ($array as $item) {
+ $item = $item instanceof Collection ? $item->all() : $item;
+
+ if (is_array($item)) {
+ if ($depth === 1) {
+ $result = array_merge($result, $item);
+ continue;
+ }
+
+ $result = array_merge($result, static::flatten($item, $depth - 1));
+ continue;
+ }
+
+ $result[] = $item;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Remove one or many array items from a given array using "dot" notation.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return void
+ */
+ public static function forget(&$array, $keys)
+ {
+ $original = &$array;
+
+ $keys = (array) $keys;
+
+ if (count($keys) === 0) {
+ return;
+ }
+
+ foreach ($keys as $key) {
+ // if the exact key exists in the top-level, remove it
+ if (static::exists($array, $key)) {
+ unset($array[$key]);
+
+ continue;
+ }
+
+ $parts = explode('.', $key);
+
+ // clean up before each pass
+ $array = &$original;
+
+ while (count($parts) > 1) {
+ $part = array_shift($parts);
+
+ if (isset($array[$part]) && is_array($array[$part])) {
+ $array = &$array[$part];
+ } else {
+ continue 2;
+ }
+ }
+
+ unset($array[array_shift($parts)]);
+ }
+ }
+
+ /**
+ * Get an item from an array using "dot" notation.
+ *
+ * @param \ArrayAccess|array $array
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public static function get($array, $key, $default = null)
+ {
+ if (! static::accessible($array)) {
+ return value($default);
+ }
+
+ if (is_null($key)) {
+ return $array;
+ }
+
+ if (static::exists($array, $key)) {
+ return $array[$key];
+ }
+
+ foreach (explode('.', $key) as $segment) {
+ if (static::accessible($array) && static::exists($array, $segment)) {
+ $array = $array[$segment];
+ } else {
+ return value($default);
+ }
+ }
+
+ return $array;
+ }
+
+ /**
+ * Check if an item exists in an array using "dot" notation.
+ *
+ * @param \ArrayAccess|array $array
+ * @param string $key
+ * @return bool
+ */
+ public static function has($array, $key)
+ {
+ if (! $array) {
+ return false;
+ }
+
+ if (is_null($key)) {
+ return false;
+ }
+
+ if (static::exists($array, $key)) {
+ return true;
+ }
+
+ foreach (explode('.', $key) as $segment) {
+ if (static::accessible($array) && static::exists($array, $segment)) {
+ $array = $array[$segment];
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Determines if an array is associative.
+ *
+ * An array is "associative" if it doesn't have sequential numerical keys beginning with zero.
+ *
+ * @param array $array
+ * @return bool
+ */
+ public static function isAssoc(array $array)
+ {
+ $keys = array_keys($array);
+
+ return array_keys($keys) !== $keys;
+ }
+
+ /**
+ * Get a subset of the items from the given array.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return array
+ */
+ public static function only($array, $keys)
+ {
+ return array_intersect_key($array, array_flip((array) $keys));
+ }
+
+ /**
+ * Pluck an array of values from an array.
+ *
+ * @param array $array
+ * @param string|array $value
+ * @param string|array|null $key
+ * @return array
+ */
+ public static function pluck($array, $value, $key = null)
+ {
+ $results = [];
+
+ list($value, $key) = static::explodePluckParameters($value, $key);
+
+ foreach ($array as $item) {
+ $itemValue = data_get($item, $value);
+
+ // If the key is "null", we will just append the value to the array and keep
+ // looping. Otherwise we will key the array using the value of the key we
+ // received from the developer. Then we'll return the final array form.
+ if (is_null($key)) {
+ $results[] = $itemValue;
+ } else {
+ $itemKey = data_get($item, $key);
+
+ $results[$itemKey] = $itemValue;
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Explode the "value" and "key" arguments passed to "pluck".
+ *
+ * @param string|array $value
+ * @param string|array|null $key
+ * @return array
+ */
+ protected static function explodePluckParameters($value, $key)
+ {
+ $value = is_string($value) ? explode('.', $value) : $value;
+
+ $key = is_null($key) || is_array($key) ? $key : explode('.', $key);
+
+ return [$value, $key];
+ }
+
+ /**
+ * Push an item onto the beginning of an array.
+ *
+ * @param array $array
+ * @param mixed $value
+ * @param mixed $key
+ * @return array
+ */
+ public static function prepend($array, $value, $key = null)
+ {
+ if (is_null($key)) {
+ array_unshift($array, $value);
+ } else {
+ $array = [$key => $value] + $array;
+ }
+
+ return $array;
+ }
+
+ /**
+ * Get a value from the array, and remove it.
+ *
+ * @param array $array
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public static function pull(&$array, $key, $default = null)
+ {
+ $value = static::get($array, $key, $default);
+
+ static::forget($array, $key);
+
+ return $value;
+ }
+
+ /**
+ * Set an array item to a given value using "dot" notation.
+ *
+ * If no key is given to the method, the entire array will be replaced.
+ *
+ * @param array $array
+ * @param string $key
+ * @param mixed $value
+ * @return array
+ */
+ public static function set(&$array, $key, $value)
+ {
+ if (is_null($key)) {
+ return $array = $value;
+ }
+
+ $keys = explode('.', $key);
+
+ while (count($keys) > 1) {
+ $key = array_shift($keys);
+
+ // If the key doesn't exist at this depth, we will just create an empty array
+ // to hold the next value, allowing us to create the arrays to hold final
+ // values at the correct depth. Then we'll keep digging into the array.
+ if (! isset($array[$key]) || ! is_array($array[$key])) {
+ $array[$key] = [];
+ }
+
+ $array = &$array[$key];
+ }
+
+ $array[array_shift($keys)] = $value;
+
+ return $array;
+ }
+
+ /**
+ * Sort the array using the given callback.
+ *
+ * @param array $array
+ * @param callable $callback
+ * @return array
+ */
+ public static function sort($array, callable $callback)
+ {
+ return Collection::make($array)->sortBy($callback)->all();
+ }
+
+ /**
+ * Recursively sort an array by keys and values.
+ *
+ * @param array $array
+ * @return array
+ */
+ public static function sortRecursive($array)
+ {
+ foreach ($array as &$value) {
+ if (is_array($value)) {
+ $value = static::sortRecursive($value);
+ }
+ }
+
+ if (static::isAssoc($array)) {
+ ksort($array);
+ } else {
+ sort($array);
+ }
+
+ return $array;
+ }
+
+ /**
+ * Filter the array using the given callback.
+ *
+ * @param array $array
+ * @param callable $callback
+ * @return array
+ */
+ public static function where($array, callable $callback)
+ {
+ $filtered = [];
+
+ foreach ($array as $key => $value) {
+ if (call_user_func($callback, $key, $value)) {
+ $filtered[$key] = $value;
+ }
+ }
+
+ return $filtered;
+ }
+}
diff --git a/vendor/illuminate/support/ClassLoader.php b/vendor/illuminate/support/ClassLoader.php
new file mode 100644
index 00000000..6a8d2358
--- /dev/null
+++ b/vendor/illuminate/support/ClassLoader.php
@@ -0,0 +1,104 @@
+items = $this->getArrayableItems($items);
+ }
+
+ /**
+ * Create a new collection instance if the value isn't one already.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public static function make($items = [])
+ {
+ return new static($items);
+ }
+
+ /**
+ * Get all of the items in the collection.
+ *
+ * @return array
+ */
+ public function all()
+ {
+ return $this->items;
+ }
+
+ /**
+ * Get the average value of a given key.
+ *
+ * @param string|null $key
+ * @return mixed
+ */
+ public function avg($key = null)
+ {
+ if ($count = $this->count()) {
+ return $this->sum($key) / $count;
+ }
+ }
+
+ /**
+ * Alias for the "avg" method.
+ *
+ * @param string|null $key
+ * @return mixed
+ */
+ public function average($key = null)
+ {
+ return $this->avg($key);
+ }
+
+ /**
+ * Get the median of a given key.
+ *
+ * @param null $key
+ * @return mixed|null
+ */
+ public function median($key = null)
+ {
+ $count = $this->count();
+
+ if ($count == 0) {
+ return;
+ }
+
+ $values = with(isset($key) ? $this->pluck($key) : $this)
+ ->sort()->values();
+
+ $middle = (int) floor($count / 2);
+
+ if ($count % 2) {
+ return $values->get($middle);
+ }
+
+ return (new static([
+ $values->get($middle - 1), $values->get($middle),
+ ]))->average();
+ }
+
+ /**
+ * Get the mode of a given key.
+ *
+ * @param null $key
+ * @return array
+ */
+ public function mode($key = null)
+ {
+ $count = $this->count();
+
+ if ($count == 0) {
+ return;
+ }
+
+ $collection = isset($key) ? $this->pluck($key) : $this;
+
+ $counts = new self;
+
+ $collection->each(function ($value) use ($counts) {
+ $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1;
+ });
+
+ $sorted = $counts->sort();
+
+ $highestValue = $sorted->last();
+
+ return $sorted->filter(function ($value) use ($highestValue) {
+ return $value == $highestValue;
+ })->sort()->keys()->all();
+ }
+
+ /**
+ * Collapse the collection of items into a single array.
+ *
+ * @return static
+ */
+ public function collapse()
+ {
+ return new static(Arr::collapse($this->items));
+ }
+
+ /**
+ * Determine if an item exists in the collection.
+ *
+ * @param mixed $key
+ * @param mixed $value
+ * @return bool
+ */
+ public function contains($key, $value = null)
+ {
+ if (func_num_args() == 2) {
+ return $this->contains(function ($k, $item) use ($key, $value) {
+ return data_get($item, $key) == $value;
+ });
+ }
+
+ if ($this->useAsCallable($key)) {
+ return ! is_null($this->first($key));
+ }
+
+ return in_array($key, $this->items);
+ }
+
+ /**
+ * Get the items in the collection that are not present in the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function diff($items)
+ {
+ return new static(array_diff($this->items, $this->getArrayableItems($items)));
+ }
+
+ /**
+ * Get the items in the collection whose keys are not present in the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function diffKeys($items)
+ {
+ return new static(array_diff_key($this->items, $this->getArrayableItems($items)));
+ }
+
+ /**
+ * Execute a callback over each item.
+ *
+ * @param callable $callback
+ * @return $this
+ */
+ public function each(callable $callback)
+ {
+ foreach ($this->items as $key => $item) {
+ if ($callback($item, $key) === false) {
+ break;
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Create a new collection consisting of every n-th element.
+ *
+ * @param int $step
+ * @param int $offset
+ * @return static
+ */
+ public function every($step, $offset = 0)
+ {
+ $new = [];
+
+ $position = 0;
+
+ foreach ($this->items as $item) {
+ if ($position % $step === $offset) {
+ $new[] = $item;
+ }
+
+ $position++;
+ }
+
+ return new static($new);
+ }
+
+ /**
+ * Get all items except for those with the specified keys.
+ *
+ * @param mixed $keys
+ * @return static
+ */
+ public function except($keys)
+ {
+ $keys = is_array($keys) ? $keys : func_get_args();
+
+ return new static(Arr::except($this->items, $keys));
+ }
+
+ /**
+ * Run a filter over each of the items.
+ *
+ * @param callable|null $callback
+ * @return static
+ */
+ public function filter(callable $callback = null)
+ {
+ if ($callback) {
+ $return = [];
+
+ foreach ($this->items as $key => $value) {
+ if ($callback($value, $key)) {
+ $return[$key] = $value;
+ }
+ }
+
+ return new static($return);
+ }
+
+ return new static(array_filter($this->items));
+ }
+
+ /**
+ * Filter items by the given key value pair.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @param bool $strict
+ * @return static
+ */
+ public function where($key, $value, $strict = true)
+ {
+ return $this->filter(function ($item) use ($key, $value, $strict) {
+ return $strict ? data_get($item, $key) === $value
+ : data_get($item, $key) == $value;
+ });
+ }
+
+ /**
+ * Filter items by the given key value pair using loose comparison.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return static
+ */
+ public function whereLoose($key, $value)
+ {
+ return $this->where($key, $value, false);
+ }
+
+ /**
+ * Filter items by the given key value pair.
+ *
+ * @param string $key
+ * @param array $values
+ * @param bool $strict
+ * @return static
+ */
+ public function whereIn($key, array $values, $strict = true)
+ {
+ return $this->filter(function ($item) use ($key, $values, $strict) {
+ return in_array(data_get($item, $key), $values, $strict);
+ });
+ }
+
+ /**
+ * Filter items by the given key value pair using loose comparison.
+ *
+ * @param string $key
+ * @param array $values
+ * @return static
+ */
+ public function whereInLoose($key, array $values)
+ {
+ return $this->whereIn($key, $values, false);
+ }
+
+ /**
+ * Get the first item from the collection.
+ *
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ public function first(callable $callback = null, $default = null)
+ {
+ return Arr::first($this->items, $callback, $default);
+ }
+
+ /**
+ * Get a flattened array of the items in the collection.
+ *
+ * @param int $depth
+ * @return static
+ */
+ public function flatten($depth = INF)
+ {
+ return new static(Arr::flatten($this->items, $depth));
+ }
+
+ /**
+ * Flip the items in the collection.
+ *
+ * @return static
+ */
+ public function flip()
+ {
+ return new static(array_flip($this->items));
+ }
+
+ /**
+ * Remove an item from the collection by key.
+ *
+ * @param string|array $keys
+ * @return $this
+ */
+ public function forget($keys)
+ {
+ foreach ((array) $keys as $key) {
+ $this->offsetUnset($key);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get an item from the collection by key.
+ *
+ * @param mixed $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function get($key, $default = null)
+ {
+ if ($this->offsetExists($key)) {
+ return $this->items[$key];
+ }
+
+ return value($default);
+ }
+
+ /**
+ * Group an associative array by a field or using a callback.
+ *
+ * @param callable|string $groupBy
+ * @param bool $preserveKeys
+ * @return static
+ */
+ public function groupBy($groupBy, $preserveKeys = false)
+ {
+ $groupBy = $this->valueRetriever($groupBy);
+
+ $results = [];
+
+ foreach ($this->items as $key => $value) {
+ $groupKeys = $groupBy($value, $key);
+
+ if (! is_array($groupKeys)) {
+ $groupKeys = [$groupKeys];
+ }
+
+ foreach ($groupKeys as $groupKey) {
+ if (! array_key_exists($groupKey, $results)) {
+ $results[$groupKey] = new static;
+ }
+
+ $results[$groupKey]->offsetSet($preserveKeys ? $key : null, $value);
+ }
+ }
+
+ return new static($results);
+ }
+
+ /**
+ * Key an associative array by a field or using a callback.
+ *
+ * @param callable|string $keyBy
+ * @return static
+ */
+ public function keyBy($keyBy)
+ {
+ $keyBy = $this->valueRetriever($keyBy);
+
+ $results = [];
+
+ foreach ($this->items as $key => $item) {
+ $results[$keyBy($item, $key)] = $item;
+ }
+
+ return new static($results);
+ }
+
+ /**
+ * Determine if an item exists in the collection by key.
+ *
+ * @param mixed $key
+ * @return bool
+ */
+ public function has($key)
+ {
+ return $this->offsetExists($key);
+ }
+
+ /**
+ * Concatenate values of a given key as a string.
+ *
+ * @param string $value
+ * @param string $glue
+ * @return string
+ */
+ public function implode($value, $glue = null)
+ {
+ $first = $this->first();
+
+ if (is_array($first) || is_object($first)) {
+ return implode($glue, $this->pluck($value)->all());
+ }
+
+ return implode($value, $this->items);
+ }
+
+ /**
+ * Intersect the collection with the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function intersect($items)
+ {
+ return new static(array_intersect($this->items, $this->getArrayableItems($items)));
+ }
+
+ /**
+ * Determine if the collection is empty or not.
+ *
+ * @return bool
+ */
+ public function isEmpty()
+ {
+ return empty($this->items);
+ }
+
+ /**
+ * Determine if the given value is callable, but not a string.
+ *
+ * @param mixed $value
+ * @return bool
+ */
+ protected function useAsCallable($value)
+ {
+ return ! is_string($value) && is_callable($value);
+ }
+
+ /**
+ * Get the keys of the collection items.
+ *
+ * @return static
+ */
+ public function keys()
+ {
+ return new static(array_keys($this->items));
+ }
+
+ /**
+ * Get the last item from the collection.
+ *
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ public function last(callable $callback = null, $default = null)
+ {
+ return Arr::last($this->items, $callback, $default);
+ }
+
+ /**
+ * Get the values of a given key.
+ *
+ * @param string $value
+ * @param string|null $key
+ * @return static
+ */
+ public function pluck($value, $key = null)
+ {
+ return new static(Arr::pluck($this->items, $value, $key));
+ }
+
+ /**
+ * Alias for the "pluck" method.
+ *
+ * @param string $value
+ * @param string|null $key
+ * @return static
+ *
+ * @deprecated since version 5.2. Use the "pluck" method directly.
+ */
+ public function lists($value, $key = null)
+ {
+ return $this->pluck($value, $key);
+ }
+
+ /**
+ * Run a map over each of the items.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function map(callable $callback)
+ {
+ $keys = array_keys($this->items);
+
+ $items = array_map($callback, $this->items, $keys);
+
+ return new static(array_combine($keys, $items));
+ }
+
+ /**
+ * Map a collection and flatten the result by a single level.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function flatMap(callable $callback)
+ {
+ return $this->map($callback)->collapse();
+ }
+
+ /**
+ * Get the max value of a given key.
+ *
+ * @param string|null $key
+ * @return mixed
+ */
+ public function max($key = null)
+ {
+ return $this->reduce(function ($result, $item) use ($key) {
+ $value = data_get($item, $key);
+
+ return is_null($result) || $value > $result ? $value : $result;
+ });
+ }
+
+ /**
+ * Merge the collection with the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function merge($items)
+ {
+ return new static(array_merge($this->items, $this->getArrayableItems($items)));
+ }
+
+ /**
+ * Create a collection by using this collection for keys and another for its values.
+ *
+ * @param mixed $values
+ * @return static
+ */
+ public function combine($values)
+ {
+ return new static(array_combine($this->all(), $this->getArrayableItems($values)));
+ }
+
+ /**
+ * Union the collection with the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function union($items)
+ {
+ return new static($this->items + $this->getArrayableItems($items));
+ }
+
+ /**
+ * Get the min value of a given key.
+ *
+ * @param string|null $key
+ * @return mixed
+ */
+ public function min($key = null)
+ {
+ return $this->reduce(function ($result, $item) use ($key) {
+ $value = data_get($item, $key);
+
+ return is_null($result) || $value < $result ? $value : $result;
+ });
+ }
+
+ /**
+ * Get the items with the specified keys.
+ *
+ * @param mixed $keys
+ * @return static
+ */
+ public function only($keys)
+ {
+ $keys = is_array($keys) ? $keys : func_get_args();
+
+ return new static(Arr::only($this->items, $keys));
+ }
+
+ /**
+ * "Paginate" the collection by slicing it into a smaller collection.
+ *
+ * @param int $page
+ * @param int $perPage
+ * @return static
+ */
+ public function forPage($page, $perPage)
+ {
+ return $this->slice(($page - 1) * $perPage, $perPage);
+ }
+
+ /**
+ * Pass the collection to the given callback and return the result.
+ *
+ * @param callable $callback
+ * @return mixed
+ */
+ public function pipe(callable $callback)
+ {
+ return $callback($this);
+ }
+
+ /**
+ * Get and remove the last item from the collection.
+ *
+ * @return mixed
+ */
+ public function pop()
+ {
+ return array_pop($this->items);
+ }
+
+ /**
+ * Push an item onto the beginning of the collection.
+ *
+ * @param mixed $value
+ * @param mixed $key
+ * @return $this
+ */
+ public function prepend($value, $key = null)
+ {
+ $this->items = Arr::prepend($this->items, $value, $key);
+
+ return $this;
+ }
+
+ /**
+ * Push an item onto the end of the collection.
+ *
+ * @param mixed $value
+ * @return $this
+ */
+ public function push($value)
+ {
+ $this->offsetSet(null, $value);
+
+ return $this;
+ }
+
+ /**
+ * Get and remove an item from the collection.
+ *
+ * @param mixed $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function pull($key, $default = null)
+ {
+ return Arr::pull($this->items, $key, $default);
+ }
+
+ /**
+ * Put an item in the collection by key.
+ *
+ * @param mixed $key
+ * @param mixed $value
+ * @return $this
+ */
+ public function put($key, $value)
+ {
+ $this->offsetSet($key, $value);
+
+ return $this;
+ }
+
+ /**
+ * Get one or more items randomly from the collection.
+ *
+ * @param int $amount
+ * @return mixed
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function random($amount = 1)
+ {
+ if ($amount > ($count = $this->count())) {
+ throw new InvalidArgumentException("You requested {$amount} items, but there are only {$count} items in the collection");
+ }
+
+ $keys = array_rand($this->items, $amount);
+
+ if ($amount == 1) {
+ return $this->items[$keys];
+ }
+
+ return new static(array_intersect_key($this->items, array_flip($keys)));
+ }
+
+ /**
+ * Reduce the collection to a single value.
+ *
+ * @param callable $callback
+ * @param mixed $initial
+ * @return mixed
+ */
+ public function reduce(callable $callback, $initial = null)
+ {
+ return array_reduce($this->items, $callback, $initial);
+ }
+
+ /**
+ * Create a collection of all elements that do not pass a given truth test.
+ *
+ * @param callable|mixed $callback
+ * @return static
+ */
+ public function reject($callback)
+ {
+ if ($this->useAsCallable($callback)) {
+ return $this->filter(function ($value, $key) use ($callback) {
+ return ! $callback($value, $key);
+ });
+ }
+
+ return $this->filter(function ($item) use ($callback) {
+ return $item != $callback;
+ });
+ }
+
+ /**
+ * Reverse items order.
+ *
+ * @return static
+ */
+ public function reverse()
+ {
+ return new static(array_reverse($this->items, true));
+ }
+
+ /**
+ * Search the collection for a given value and return the corresponding key if successful.
+ *
+ * @param mixed $value
+ * @param bool $strict
+ * @return mixed
+ */
+ public function search($value, $strict = false)
+ {
+ if (! $this->useAsCallable($value)) {
+ return array_search($value, $this->items, $strict);
+ }
+
+ foreach ($this->items as $key => $item) {
+ if (call_user_func($value, $item, $key)) {
+ return $key;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get and remove the first item from the collection.
+ *
+ * @return mixed
+ */
+ public function shift()
+ {
+ return array_shift($this->items);
+ }
+
+ /**
+ * Shuffle the items in the collection.
+ *
+ * @param int $seed
+ * @return static
+ */
+ public function shuffle($seed = null)
+ {
+ $items = $this->items;
+
+ if (is_null($seed)) {
+ shuffle($items);
+ } else {
+ srand($seed);
+
+ usort($items, function () {
+ return rand(-1, 1);
+ });
+ }
+
+ return new static($items);
+ }
+
+ /**
+ * Slice the underlying collection array.
+ *
+ * @param int $offset
+ * @param int $length
+ * @return static
+ */
+ public function slice($offset, $length = null)
+ {
+ return new static(array_slice($this->items, $offset, $length, true));
+ }
+
+ /**
+ * Chunk the underlying collection array.
+ *
+ * @param int $size
+ * @return static
+ */
+ public function chunk($size)
+ {
+ $chunks = [];
+
+ foreach (array_chunk($this->items, $size, true) as $chunk) {
+ $chunks[] = new static($chunk);
+ }
+
+ return new static($chunks);
+ }
+
+ /**
+ * Sort through each item with a callback.
+ *
+ * @param callable|null $callback
+ * @return static
+ */
+ public function sort(callable $callback = null)
+ {
+ $items = $this->items;
+
+ $callback ? uasort($items, $callback) : uasort($items, function ($a, $b) {
+ if ($a == $b) {
+ return 0;
+ }
+
+ return ($a < $b) ? -1 : 1;
+ });
+
+ return new static($items);
+ }
+
+ /**
+ * Sort the collection using the given callback.
+ *
+ * @param callable|string $callback
+ * @param int $options
+ * @param bool $descending
+ * @return static
+ */
+ public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
+ {
+ $results = [];
+
+ $callback = $this->valueRetriever($callback);
+
+ // First we will loop through the items and get the comparator from a callback
+ // function which we were given. Then, we will sort the returned values and
+ // and grab the corresponding values for the sorted keys from this array.
+ foreach ($this->items as $key => $value) {
+ $results[$key] = $callback($value, $key);
+ }
+
+ $descending ? arsort($results, $options)
+ : asort($results, $options);
+
+ // Once we have sorted all of the keys in the array, we will loop through them
+ // and grab the corresponding model so we can set the underlying items list
+ // to the sorted version. Then we'll just return the collection instance.
+ foreach (array_keys($results) as $key) {
+ $results[$key] = $this->items[$key];
+ }
+
+ return new static($results);
+ }
+
+ /**
+ * Sort the collection in descending order using the given callback.
+ *
+ * @param callable|string $callback
+ * @param int $options
+ * @return static
+ */
+ public function sortByDesc($callback, $options = SORT_REGULAR)
+ {
+ return $this->sortBy($callback, $options, true);
+ }
+
+ /**
+ * Splice a portion of the underlying collection array.
+ *
+ * @param int $offset
+ * @param int|null $length
+ * @param mixed $replacement
+ * @return static
+ */
+ public function splice($offset, $length = null, $replacement = [])
+ {
+ if (func_num_args() == 1) {
+ return new static(array_splice($this->items, $offset));
+ }
+
+ return new static(array_splice($this->items, $offset, $length, $replacement));
+ }
+
+ /**
+ * Get the sum of the given values.
+ *
+ * @param callable|string|null $callback
+ * @return mixed
+ */
+ public function sum($callback = null)
+ {
+ if (is_null($callback)) {
+ return array_sum($this->items);
+ }
+
+ $callback = $this->valueRetriever($callback);
+
+ return $this->reduce(function ($result, $item) use ($callback) {
+ return $result += $callback($item);
+ }, 0);
+ }
+
+ /**
+ * Take the first or last {$limit} items.
+ *
+ * @param int $limit
+ * @return static
+ */
+ public function take($limit)
+ {
+ if ($limit < 0) {
+ return $this->slice($limit, abs($limit));
+ }
+
+ return $this->slice(0, $limit);
+ }
+
+ /**
+ * Transform each item in the collection using a callback.
+ *
+ * @param callable $callback
+ * @return $this
+ */
+ public function transform(callable $callback)
+ {
+ $this->items = $this->map($callback)->all();
+
+ return $this;
+ }
+
+ /**
+ * Return only unique items from the collection array.
+ *
+ * @param string|callable|null $key
+ * @return static
+ */
+ public function unique($key = null)
+ {
+ if (is_null($key)) {
+ return new static(array_unique($this->items, SORT_REGULAR));
+ }
+
+ $key = $this->valueRetriever($key);
+
+ $exists = [];
+
+ return $this->reject(function ($item) use ($key, &$exists) {
+ if (in_array($id = $key($item), $exists)) {
+ return true;
+ }
+
+ $exists[] = $id;
+ });
+ }
+
+ /**
+ * Reset the keys on the underlying array.
+ *
+ * @return static
+ */
+ public function values()
+ {
+ return new static(array_values($this->items));
+ }
+
+ /**
+ * Get a value retrieving callback.
+ *
+ * @param string $value
+ * @return callable
+ */
+ protected function valueRetriever($value)
+ {
+ if ($this->useAsCallable($value)) {
+ return $value;
+ }
+
+ return function ($item) use ($value) {
+ return data_get($item, $value);
+ };
+ }
+
+ /**
+ * Zip the collection together with one or more arrays.
+ *
+ * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]);
+ * => [[1, 4], [2, 5], [3, 6]]
+ *
+ * @param mixed ...$items
+ * @return static
+ */
+ public function zip($items)
+ {
+ $arrayableItems = array_map(function ($items) {
+ return $this->getArrayableItems($items);
+ }, func_get_args());
+
+ $params = array_merge([function () {
+ return new static(func_get_args());
+ }, $this->items], $arrayableItems);
+
+ return new static(call_user_func_array('array_map', $params));
+ }
+
+ /**
+ * Get the collection of items as a plain array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return array_map(function ($value) {
+ return $value instanceof Arrayable ? $value->toArray() : $value;
+ }, $this->items);
+ }
+
+ /**
+ * Convert the object into something JSON serializable.
+ *
+ * @return array
+ */
+ public function jsonSerialize()
+ {
+ return array_map(function ($value) {
+ if ($value instanceof JsonSerializable) {
+ return $value->jsonSerialize();
+ } elseif ($value instanceof Jsonable) {
+ return json_decode($value->toJson(), true);
+ } elseif ($value instanceof Arrayable) {
+ return $value->toArray();
+ } else {
+ return $value;
+ }
+ }, $this->items);
+ }
+
+ /**
+ * Get the collection of items as JSON.
+ *
+ * @param int $options
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ return json_encode($this->jsonSerialize(), $options);
+ }
+
+ /**
+ * Get an iterator for the items.
+ *
+ * @return \ArrayIterator
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->items);
+ }
+
+ /**
+ * Get a CachingIterator instance.
+ *
+ * @param int $flags
+ * @return \CachingIterator
+ */
+ public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING)
+ {
+ return new CachingIterator($this->getIterator(), $flags);
+ }
+
+ /**
+ * Count the number of items in the collection.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->items);
+ }
+
+ /**
+ * Determine if an item exists at an offset.
+ *
+ * @param mixed $key
+ * @return bool
+ */
+ public function offsetExists($key)
+ {
+ return array_key_exists($key, $this->items);
+ }
+
+ /**
+ * Get an item at a given offset.
+ *
+ * @param mixed $key
+ * @return mixed
+ */
+ public function offsetGet($key)
+ {
+ return $this->items[$key];
+ }
+
+ /**
+ * Set the item at a given offset.
+ *
+ * @param mixed $key
+ * @param mixed $value
+ * @return void
+ */
+ public function offsetSet($key, $value)
+ {
+ if (is_null($key)) {
+ $this->items[] = $value;
+ } else {
+ $this->items[$key] = $value;
+ }
+ }
+
+ /**
+ * Unset the item at a given offset.
+ *
+ * @param string $key
+ * @return void
+ */
+ public function offsetUnset($key)
+ {
+ unset($this->items[$key]);
+ }
+
+ /**
+ * Convert the collection to its string representation.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->toJson();
+ }
+
+ /**
+ * Results array of items from Collection or Arrayable.
+ *
+ * @param mixed $items
+ * @return array
+ */
+ protected function getArrayableItems($items)
+ {
+ if (is_array($items)) {
+ return $items;
+ } elseif ($items instanceof self) {
+ return $items->all();
+ } elseif ($items instanceof Arrayable) {
+ return $items->toArray();
+ } elseif ($items instanceof Jsonable) {
+ return json_decode($items->toJson(), true);
+ } elseif ($items instanceof JsonSerializable) {
+ return $items->jsonSerialize();
+ } elseif ($items instanceof Traversable) {
+ return iterator_to_array($items);
+ }
+
+ return (array) $items;
+ }
+}
diff --git a/vendor/illuminate/support/Composer.php b/vendor/illuminate/support/Composer.php
new file mode 100644
index 00000000..50bed398
--- /dev/null
+++ b/vendor/illuminate/support/Composer.php
@@ -0,0 +1,106 @@
+files = $files;
+ $this->workingPath = $workingPath;
+ }
+
+ /**
+ * Regenerate the Composer autoloader files.
+ *
+ * @param string $extra
+ * @return void
+ */
+ public function dumpAutoloads($extra = '')
+ {
+ $process = $this->getProcess();
+
+ $process->setCommandLine(trim($this->findComposer().' dump-autoload '.$extra));
+
+ $process->run();
+ }
+
+ /**
+ * Regenerate the optimized Composer autoloader files.
+ *
+ * @return void
+ */
+ public function dumpOptimized()
+ {
+ $this->dumpAutoloads('--optimize');
+ }
+
+ /**
+ * Get the composer command for the environment.
+ *
+ * @return string
+ */
+ protected function findComposer()
+ {
+ if (! $this->files->exists($this->workingPath.'/composer.phar')) {
+ return 'composer';
+ }
+
+ $binary = ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false));
+
+ if (defined('HHVM_VERSION')) {
+ $binary .= ' --php';
+ }
+
+ return "{$binary} composer.phar";
+ }
+
+ /**
+ * Get a new Symfony process instance.
+ *
+ * @return \Symfony\Component\Process\Process
+ */
+ protected function getProcess()
+ {
+ return (new Process('', $this->workingPath))->setTimeout(null);
+ }
+
+ /**
+ * Set the working path used by the class.
+ *
+ * @param string $path
+ * @return $this
+ */
+ public function setWorkingPath($path)
+ {
+ $this->workingPath = realpath($path);
+
+ return $this;
+ }
+}
diff --git a/vendor/illuminate/support/Debug/Dumper.php b/vendor/illuminate/support/Debug/Dumper.php
new file mode 100644
index 00000000..99a045da
--- /dev/null
+++ b/vendor/illuminate/support/Debug/Dumper.php
@@ -0,0 +1,26 @@
+dump((new VarCloner)->cloneVar($value));
+ } else {
+ var_dump($value);
+ }
+ }
+}
diff --git a/vendor/illuminate/support/Debug/HtmlDumper.php b/vendor/illuminate/support/Debug/HtmlDumper.php
new file mode 100644
index 00000000..5825ac8d
--- /dev/null
+++ b/vendor/illuminate/support/Debug/HtmlDumper.php
@@ -0,0 +1,29 @@
+ 'background-color:#fff; color:#222; line-height:1.2em; font-weight:normal; font:12px Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:100000',
+ 'num' => 'color:#a71d5d',
+ 'const' => 'color:#795da3',
+ 'str' => 'color:#df5000',
+ 'cchr' => 'color:#222',
+ 'note' => 'color:#a71d5d',
+ 'ref' => 'color:#a0a0a0',
+ 'public' => 'color:#795da3',
+ 'protected' => 'color:#795da3',
+ 'private' => 'color:#795da3',
+ 'meta' => 'color:#b729d9',
+ 'key' => 'color:#df5000',
+ 'index' => 'color:#a71d5d',
+ ];
+}
diff --git a/vendor/illuminate/support/Facades/App.php b/vendor/illuminate/support/Facades/App.php
new file mode 100755
index 00000000..2675d56a
--- /dev/null
+++ b/vendor/illuminate/support/Facades/App.php
@@ -0,0 +1,19 @@
+getEngineResolver()->resolve('blade')->getCompiler();
+ }
+}
diff --git a/vendor/illuminate/support/Facades/Bus.php b/vendor/illuminate/support/Facades/Bus.php
new file mode 100644
index 00000000..7c42e9ed
--- /dev/null
+++ b/vendor/illuminate/support/Facades/Bus.php
@@ -0,0 +1,19 @@
+cookie($key, null));
+ }
+
+ /**
+ * Retrieve a cookie from the request.
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return string
+ */
+ public static function get($key = null, $default = null)
+ {
+ return static::$app['request']->cookie($key, $default);
+ }
+
+ /**
+ * Get the registered name of the component.
+ *
+ * @return string
+ */
+ protected static function getFacadeAccessor()
+ {
+ return 'cookie';
+ }
+}
diff --git a/vendor/illuminate/support/Facades/Crypt.php b/vendor/illuminate/support/Facades/Crypt.php
new file mode 100755
index 00000000..0eef08d1
--- /dev/null
+++ b/vendor/illuminate/support/Facades/Crypt.php
@@ -0,0 +1,19 @@
+instance(static::getFacadeAccessor(), $instance);
+ }
+
+ /**
+ * Initiate a mock expectation on the facade.
+ *
+ * @param mixed
+ * @return \Mockery\Expectation
+ */
+ public static function shouldReceive()
+ {
+ $name = static::getFacadeAccessor();
+
+ if (static::isMock()) {
+ $mock = static::$resolvedInstance[$name];
+ } else {
+ $mock = static::createFreshMockInstance($name);
+ }
+
+ return call_user_func_array([$mock, 'shouldReceive'], func_get_args());
+ }
+
+ /**
+ * Create a fresh mock instance for the given class.
+ *
+ * @param string $name
+ * @return \Mockery\Expectation
+ */
+ protected static function createFreshMockInstance($name)
+ {
+ static::$resolvedInstance[$name] = $mock = static::createMockByName($name);
+
+ $mock->shouldAllowMockingProtectedMethods();
+
+ if (isset(static::$app)) {
+ static::$app->instance($name, $mock);
+ }
+
+ return $mock;
+ }
+
+ /**
+ * Create a fresh mock instance for the given class.
+ *
+ * @param string $name
+ * @return \Mockery\Expectation
+ */
+ protected static function createMockByName($name)
+ {
+ $class = static::getMockableClass($name);
+
+ return $class ? Mockery::mock($class) : Mockery::mock();
+ }
+
+ /**
+ * Determines whether a mock is set as the instance of the facade.
+ *
+ * @return bool
+ */
+ protected static function isMock()
+ {
+ $name = static::getFacadeAccessor();
+
+ return isset(static::$resolvedInstance[$name]) && static::$resolvedInstance[$name] instanceof MockInterface;
+ }
+
+ /**
+ * Get the mockable class for the bound instance.
+ *
+ * @return string|null
+ */
+ protected static function getMockableClass()
+ {
+ if ($root = static::getFacadeRoot()) {
+ return get_class($root);
+ }
+ }
+
+ /**
+ * Get the root object behind the facade.
+ *
+ * @return mixed
+ */
+ public static function getFacadeRoot()
+ {
+ return static::resolveFacadeInstance(static::getFacadeAccessor());
+ }
+
+ /**
+ * Get the registered name of the component.
+ *
+ * @return string
+ *
+ * @throws \RuntimeException
+ */
+ protected static function getFacadeAccessor()
+ {
+ throw new RuntimeException('Facade does not implement getFacadeAccessor method.');
+ }
+
+ /**
+ * Resolve the facade root instance from the container.
+ *
+ * @param string|object $name
+ * @return mixed
+ */
+ protected static function resolveFacadeInstance($name)
+ {
+ if (is_object($name)) {
+ return $name;
+ }
+
+ if (isset(static::$resolvedInstance[$name])) {
+ return static::$resolvedInstance[$name];
+ }
+
+ return static::$resolvedInstance[$name] = static::$app[$name];
+ }
+
+ /**
+ * Clear a resolved facade instance.
+ *
+ * @param string $name
+ * @return void
+ */
+ public static function clearResolvedInstance($name)
+ {
+ unset(static::$resolvedInstance[$name]);
+ }
+
+ /**
+ * Clear all of the resolved instances.
+ *
+ * @return void
+ */
+ public static function clearResolvedInstances()
+ {
+ static::$resolvedInstance = [];
+ }
+
+ /**
+ * Get the application instance behind the facade.
+ *
+ * @return \Illuminate\Contracts\Foundation\Application
+ */
+ public static function getFacadeApplication()
+ {
+ return static::$app;
+ }
+
+ /**
+ * Set the application instance.
+ *
+ * @param \Illuminate\Contracts\Foundation\Application $app
+ * @return void
+ */
+ public static function setFacadeApplication($app)
+ {
+ static::$app = $app;
+ }
+
+ /**
+ * Handle dynamic, static calls to the object.
+ *
+ * @param string $method
+ * @param array $args
+ * @return mixed
+ *
+ * @throws \RuntimeException
+ */
+ public static function __callStatic($method, $args)
+ {
+ $instance = static::getFacadeRoot();
+
+ if (! $instance) {
+ throw new RuntimeException('A facade root has not been set.');
+ }
+
+ switch (count($args)) {
+ case 0:
+ return $instance->$method();
+ case 1:
+ return $instance->$method($args[0]);
+ case 2:
+ return $instance->$method($args[0], $args[1]);
+ case 3:
+ return $instance->$method($args[0], $args[1], $args[2]);
+ case 4:
+ return $instance->$method($args[0], $args[1], $args[2], $args[3]);
+ default:
+ return call_user_func_array([$instance, $method], $args);
+ }
+ }
+}
diff --git a/vendor/illuminate/support/Facades/File.php b/vendor/illuminate/support/Facades/File.php
new file mode 100755
index 00000000..0f81bf62
--- /dev/null
+++ b/vendor/illuminate/support/Facades/File.php
@@ -0,0 +1,19 @@
+input($key, $default);
+ }
+
+ /**
+ * Get the registered name of the component.
+ *
+ * @return string
+ */
+ protected static function getFacadeAccessor()
+ {
+ return 'request';
+ }
+}
diff --git a/vendor/illuminate/support/Facades/Lang.php b/vendor/illuminate/support/Facades/Lang.php
new file mode 100755
index 00000000..e5862b99
--- /dev/null
+++ b/vendor/illuminate/support/Facades/Lang.php
@@ -0,0 +1,19 @@
+connection($name)->getSchemaBuilder();
+ }
+
+ /**
+ * Get a schema builder instance for the default connection.
+ *
+ * @return \Illuminate\Database\Schema\Builder
+ */
+ protected static function getFacadeAccessor()
+ {
+ return static::$app['db']->connection()->getSchemaBuilder();
+ }
+}
diff --git a/vendor/illuminate/support/Facades/Session.php b/vendor/illuminate/support/Facades/Session.php
new file mode 100755
index 00000000..bc9b5fd9
--- /dev/null
+++ b/vendor/illuminate/support/Facades/Session.php
@@ -0,0 +1,20 @@
+ $value) {
+ $this->attributes[$key] = $value;
+ }
+ }
+
+ /**
+ * Get an attribute from the container.
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function get($key, $default = null)
+ {
+ if (array_key_exists($key, $this->attributes)) {
+ return $this->attributes[$key];
+ }
+
+ return value($default);
+ }
+
+ /**
+ * Get the attributes from the container.
+ *
+ * @return array
+ */
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Convert the Fluent instance to an array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Convert the object into something JSON serializable.
+ *
+ * @return array
+ */
+ public function jsonSerialize()
+ {
+ return $this->toArray();
+ }
+
+ /**
+ * Convert the Fluent instance to JSON.
+ *
+ * @param int $options
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ return json_encode($this->jsonSerialize(), $options);
+ }
+
+ /**
+ * Determine if the given offset exists.
+ *
+ * @param string $offset
+ * @return bool
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->{$offset});
+ }
+
+ /**
+ * Get the value for a given offset.
+ *
+ * @param string $offset
+ * @return mixed
+ */
+ public function offsetGet($offset)
+ {
+ return $this->{$offset};
+ }
+
+ /**
+ * Set the value at the given offset.
+ *
+ * @param string $offset
+ * @param mixed $value
+ * @return void
+ */
+ public function offsetSet($offset, $value)
+ {
+ $this->{$offset} = $value;
+ }
+
+ /**
+ * Unset the value at the given offset.
+ *
+ * @param string $offset
+ * @return void
+ */
+ public function offsetUnset($offset)
+ {
+ unset($this->{$offset});
+ }
+
+ /**
+ * Handle dynamic calls to the container to set attributes.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return $this
+ */
+ public function __call($method, $parameters)
+ {
+ $this->attributes[$method] = count($parameters) > 0 ? $parameters[0] : true;
+
+ return $this;
+ }
+
+ /**
+ * Dynamically retrieve the value of an attribute.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function __get($key)
+ {
+ return $this->get($key);
+ }
+
+ /**
+ * Dynamically set the value of an attribute.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this->attributes[$key] = $value;
+ }
+
+ /**
+ * Dynamically check if an attribute is set.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function __isset($key)
+ {
+ return isset($this->attributes[$key]);
+ }
+
+ /**
+ * Dynamically unset an attribute.
+ *
+ * @param string $key
+ * @return void
+ */
+ public function __unset($key)
+ {
+ unset($this->attributes[$key]);
+ }
+}
diff --git a/vendor/illuminate/support/HtmlString.php b/vendor/illuminate/support/HtmlString.php
new file mode 100644
index 00000000..8d246cff
--- /dev/null
+++ b/vendor/illuminate/support/HtmlString.php
@@ -0,0 +1,46 @@
+html = $html;
+ }
+
+ /**
+ * Get the the HTML string.
+ *
+ * @return string
+ */
+ public function toHtml()
+ {
+ return $this->html;
+ }
+
+ /**
+ * Get the the HTML string.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->toHtml();
+ }
+}
diff --git a/vendor/illuminate/support/Manager.php b/vendor/illuminate/support/Manager.php
new file mode 100755
index 00000000..ce484f0c
--- /dev/null
+++ b/vendor/illuminate/support/Manager.php
@@ -0,0 +1,139 @@
+app = $app;
+ }
+
+ /**
+ * Get the default driver name.
+ *
+ * @return string
+ */
+ abstract public function getDefaultDriver();
+
+ /**
+ * Get a driver instance.
+ *
+ * @param string $driver
+ * @return mixed
+ */
+ public function driver($driver = null)
+ {
+ $driver = $driver ?: $this->getDefaultDriver();
+
+ // If the given driver has not been created before, we will create the instances
+ // here and cache it so we can return it next time very quickly. If there is
+ // already a driver created by this name, we'll just return that instance.
+ if (! isset($this->drivers[$driver])) {
+ $this->drivers[$driver] = $this->createDriver($driver);
+ }
+
+ return $this->drivers[$driver];
+ }
+
+ /**
+ * Create a new driver instance.
+ *
+ * @param string $driver
+ * @return mixed
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function createDriver($driver)
+ {
+ $method = 'create'.Str::studly($driver).'Driver';
+
+ // We'll check to see if a creator method exists for the given driver. If not we
+ // will check for a custom driver creator, which allows developers to create
+ // drivers using their own customized driver creator Closure to create it.
+ if (isset($this->customCreators[$driver])) {
+ return $this->callCustomCreator($driver);
+ } elseif (method_exists($this, $method)) {
+ return $this->$method();
+ }
+
+ throw new InvalidArgumentException("Driver [$driver] not supported.");
+ }
+
+ /**
+ * Call a custom driver creator.
+ *
+ * @param string $driver
+ * @return mixed
+ */
+ protected function callCustomCreator($driver)
+ {
+ return $this->customCreators[$driver]($this->app);
+ }
+
+ /**
+ * Register a custom driver creator Closure.
+ *
+ * @param string $driver
+ * @param \Closure $callback
+ * @return $this
+ */
+ public function extend($driver, Closure $callback)
+ {
+ $this->customCreators[$driver] = $callback;
+
+ return $this;
+ }
+
+ /**
+ * Get all of the created "drivers".
+ *
+ * @return array
+ */
+ public function getDrivers()
+ {
+ return $this->drivers;
+ }
+
+ /**
+ * Dynamically call the default driver instance.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ return call_user_func_array([$this->driver(), $method], $parameters);
+ }
+}
diff --git a/vendor/illuminate/support/MessageBag.php b/vendor/illuminate/support/MessageBag.php
new file mode 100755
index 00000000..575b8d19
--- /dev/null
+++ b/vendor/illuminate/support/MessageBag.php
@@ -0,0 +1,359 @@
+ $value) {
+ $this->messages[$key] = (array) $value;
+ }
+ }
+
+ /**
+ * Get the keys present in the message bag.
+ *
+ * @return array
+ */
+ public function keys()
+ {
+ return array_keys($this->messages);
+ }
+
+ /**
+ * Add a message to the bag.
+ *
+ * @param string $key
+ * @param string $message
+ * @return $this
+ */
+ public function add($key, $message)
+ {
+ if ($this->isUnique($key, $message)) {
+ $this->messages[$key][] = $message;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Merge a new array of messages into the bag.
+ *
+ * @param \Illuminate\Contracts\Support\MessageProvider|array $messages
+ * @return $this
+ */
+ public function merge($messages)
+ {
+ if ($messages instanceof MessageProvider) {
+ $messages = $messages->getMessageBag()->getMessages();
+ }
+
+ $this->messages = array_merge_recursive($this->messages, $messages);
+
+ return $this;
+ }
+
+ /**
+ * Determine if a key and message combination already exists.
+ *
+ * @param string $key
+ * @param string $message
+ * @return bool
+ */
+ protected function isUnique($key, $message)
+ {
+ $messages = (array) $this->messages;
+
+ return ! isset($messages[$key]) || ! in_array($message, $messages[$key]);
+ }
+
+ /**
+ * Determine if messages exist for all of the given keys.
+ *
+ * @param array|string $key
+ * @return bool
+ */
+ public function has($key = null)
+ {
+ if (is_null($key)) {
+ return $this->any();
+ }
+
+ $keys = is_array($key) ? $key : func_get_args();
+
+ foreach ($keys as $key) {
+ if ($this->first($key) === '') {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Determine if messages exist for any of the given keys.
+ *
+ * @param array $keys
+ * @return bool
+ */
+ public function hasAny($keys = [])
+ {
+ foreach ($keys as $key) {
+ if ($this->has($key)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the first message from the bag for a given key.
+ *
+ * @param string $key
+ * @param string $format
+ * @return string
+ */
+ public function first($key = null, $format = null)
+ {
+ $messages = is_null($key) ? $this->all($format) : $this->get($key, $format);
+
+ return count($messages) > 0 ? $messages[0] : '';
+ }
+
+ /**
+ * Get all of the messages from the bag for a given key.
+ *
+ * @param string $key
+ * @param string $format
+ * @return array
+ */
+ public function get($key, $format = null)
+ {
+ // If the message exists in the container, we will transform it and return
+ // the message. Otherwise, we'll return an empty array since the entire
+ // methods is to return back an array of messages in the first place.
+ if (array_key_exists($key, $this->messages)) {
+ return $this->transform($this->messages[$key], $this->checkFormat($format), $key);
+ }
+
+ return [];
+ }
+
+ /**
+ * Get all of the messages for every key in the bag.
+ *
+ * @param string $format
+ * @return array
+ */
+ public function all($format = null)
+ {
+ $format = $this->checkFormat($format);
+
+ $all = [];
+
+ foreach ($this->messages as $key => $messages) {
+ $all = array_merge($all, $this->transform($messages, $format, $key));
+ }
+
+ return $all;
+ }
+
+ /**
+ * Get all of the unique messages for every key in the bag.
+ *
+ * @param string $format
+ * @return array
+ */
+ public function unique($format = null)
+ {
+ return array_unique($this->all($format));
+ }
+
+ /**
+ * Format an array of messages.
+ *
+ * @param array $messages
+ * @param string $format
+ * @param string $messageKey
+ * @return array
+ */
+ protected function transform($messages, $format, $messageKey)
+ {
+ $messages = (array) $messages;
+
+ // We will simply spin through the given messages and transform each one
+ // replacing the :message place holder with the real message allowing
+ // the messages to be easily formatted to each developer's desires.
+ $replace = [':message', ':key'];
+
+ foreach ($messages as &$message) {
+ $message = str_replace($replace, [$message, $messageKey], $format);
+ }
+
+ return $messages;
+ }
+
+ /**
+ * Get the appropriate format based on the given format.
+ *
+ * @param string $format
+ * @return string
+ */
+ protected function checkFormat($format)
+ {
+ return $format ?: $this->format;
+ }
+
+ /**
+ * Get the raw messages in the container.
+ *
+ * @return array
+ */
+ public function messages()
+ {
+ return $this->messages;
+ }
+
+ /**
+ * Get the raw messages in the container.
+ *
+ * @return array
+ */
+ public function getMessages()
+ {
+ return $this->messages();
+ }
+
+ /**
+ * Get the messages for the instance.
+ *
+ * @return \Illuminate\Support\MessageBag
+ */
+ public function getMessageBag()
+ {
+ return $this;
+ }
+
+ /**
+ * Get the default message format.
+ *
+ * @return string
+ */
+ public function getFormat()
+ {
+ return $this->format;
+ }
+
+ /**
+ * Set the default message format.
+ *
+ * @param string $format
+ * @return \Illuminate\Support\MessageBag
+ */
+ public function setFormat($format = ':message')
+ {
+ $this->format = $format;
+
+ return $this;
+ }
+
+ /**
+ * Determine if the message bag has any messages.
+ *
+ * @return bool
+ */
+ public function isEmpty()
+ {
+ return ! $this->any();
+ }
+
+ /**
+ * Determine if the message bag has any messages.
+ *
+ * @return bool
+ */
+ public function any()
+ {
+ return $this->count() > 0;
+ }
+
+ /**
+ * Get the number of messages in the container.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->messages, COUNT_RECURSIVE) - count($this->messages);
+ }
+
+ /**
+ * Get the instance as an array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return $this->getMessages();
+ }
+
+ /**
+ * Convert the object into something JSON serializable.
+ *
+ * @return array
+ */
+ public function jsonSerialize()
+ {
+ return $this->toArray();
+ }
+
+ /**
+ * Convert the object to its JSON representation.
+ *
+ * @param int $options
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ return json_encode($this->jsonSerialize(), $options);
+ }
+
+ /**
+ * Convert the message bag to its string representation.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->toJson();
+ }
+}
diff --git a/vendor/illuminate/support/NamespacedItemResolver.php b/vendor/illuminate/support/NamespacedItemResolver.php
new file mode 100755
index 00000000..a111985e
--- /dev/null
+++ b/vendor/illuminate/support/NamespacedItemResolver.php
@@ -0,0 +1,104 @@
+parsed[$key])) {
+ return $this->parsed[$key];
+ }
+
+ // If the key does not contain a double colon, it means the key is not in a
+ // namespace, and is just a regular configuration item. Namespaces are a
+ // tool for organizing configuration items for things such as modules.
+ if (strpos($key, '::') === false) {
+ $segments = explode('.', $key);
+
+ $parsed = $this->parseBasicSegments($segments);
+ } else {
+ $parsed = $this->parseNamespacedSegments($key);
+ }
+
+ // Once we have the parsed array of this key's elements, such as its groups
+ // and namespace, we will cache each array inside a simple list that has
+ // the key and the parsed array for quick look-ups for later requests.
+ return $this->parsed[$key] = $parsed;
+ }
+
+ /**
+ * Parse an array of basic segments.
+ *
+ * @param array $segments
+ * @return array
+ */
+ protected function parseBasicSegments(array $segments)
+ {
+ // The first segment in a basic array will always be the group, so we can go
+ // ahead and grab that segment. If there is only one total segment we are
+ // just pulling an entire group out of the array and not a single item.
+ $group = $segments[0];
+
+ if (count($segments) == 1) {
+ return [null, $group, null];
+ }
+
+ // If there is more than one segment in this group, it means we are pulling
+ // a specific item out of a groups and will need to return the item name
+ // as well as the group so we know which item to pull from the arrays.
+ else {
+ $item = implode('.', array_slice($segments, 1));
+
+ return [null, $group, $item];
+ }
+ }
+
+ /**
+ * Parse an array of namespaced segments.
+ *
+ * @param string $key
+ * @return array
+ */
+ protected function parseNamespacedSegments($key)
+ {
+ list($namespace, $item) = explode('::', $key);
+
+ // First we'll just explode the first segment to get the namespace and group
+ // since the item should be in the remaining segments. Once we have these
+ // two pieces of data we can proceed with parsing out the item's value.
+ $itemSegments = explode('.', $item);
+
+ $groupAndItem = array_slice($this->parseBasicSegments($itemSegments), 1);
+
+ return array_merge([$namespace], $groupAndItem);
+ }
+
+ /**
+ * Set the parsed value of a key.
+ *
+ * @param string $key
+ * @param array $parsed
+ * @return void
+ */
+ public function setParsedKey($key, $parsed)
+ {
+ $this->parsed[$key] = $parsed;
+ }
+}
diff --git a/vendor/illuminate/support/Pluralizer.php b/vendor/illuminate/support/Pluralizer.php
new file mode 100755
index 00000000..87125722
--- /dev/null
+++ b/vendor/illuminate/support/Pluralizer.php
@@ -0,0 +1,106 @@
+app = $app;
+ }
+
+ /**
+ * Register the service provider.
+ *
+ * @return void
+ */
+ abstract public function register();
+
+ /**
+ * Merge the given configuration with the existing configuration.
+ *
+ * @param string $path
+ * @param string $key
+ * @return void
+ */
+ protected function mergeConfigFrom($path, $key)
+ {
+ $config = $this->app['config']->get($key, []);
+
+ $this->app['config']->set($key, array_merge(require $path, $config));
+ }
+
+ /**
+ * Register a view file namespace.
+ *
+ * @param string $path
+ * @param string $namespace
+ * @return void
+ */
+ protected function loadViewsFrom($path, $namespace)
+ {
+ if (is_dir($appPath = $this->app->basePath().'/resources/views/vendor/'.$namespace)) {
+ $this->app['view']->addNamespace($namespace, $appPath);
+ }
+
+ $this->app['view']->addNamespace($namespace, $path);
+ }
+
+ /**
+ * Register a translation file namespace.
+ *
+ * @param string $path
+ * @param string $namespace
+ * @return void
+ */
+ protected function loadTranslationsFrom($path, $namespace)
+ {
+ $this->app['translator']->addNamespace($namespace, $path);
+ }
+
+ /**
+ * Register paths to be published by the publish command.
+ *
+ * @param array $paths
+ * @param string $group
+ * @return void
+ */
+ protected function publishes(array $paths, $group = null)
+ {
+ $class = static::class;
+
+ if (! array_key_exists($class, static::$publishes)) {
+ static::$publishes[$class] = [];
+ }
+
+ static::$publishes[$class] = array_merge(static::$publishes[$class], $paths);
+
+ if ($group) {
+ if (! array_key_exists($group, static::$publishGroups)) {
+ static::$publishGroups[$group] = [];
+ }
+
+ static::$publishGroups[$group] = array_merge(static::$publishGroups[$group], $paths);
+ }
+ }
+
+ /**
+ * Get the paths to publish.
+ *
+ * @param string $provider
+ * @param string $group
+ * @return array
+ */
+ public static function pathsToPublish($provider = null, $group = null)
+ {
+ if ($provider && $group) {
+ if (empty(static::$publishes[$provider]) || empty(static::$publishGroups[$group])) {
+ return [];
+ }
+
+ return array_intersect_key(static::$publishes[$provider], static::$publishGroups[$group]);
+ }
+
+ if ($group && array_key_exists($group, static::$publishGroups)) {
+ return static::$publishGroups[$group];
+ }
+
+ if ($provider && array_key_exists($provider, static::$publishes)) {
+ return static::$publishes[$provider];
+ }
+
+ if ($group || $provider) {
+ return [];
+ }
+
+ $paths = [];
+
+ foreach (static::$publishes as $class => $publish) {
+ $paths = array_merge($paths, $publish);
+ }
+
+ return $paths;
+ }
+
+ /**
+ * Register the package's custom Artisan commands.
+ *
+ * @param array|mixed $commands
+ * @return void
+ */
+ public function commands($commands)
+ {
+ $commands = is_array($commands) ? $commands : func_get_args();
+
+ // To register the commands with Artisan, we will grab each of the arguments
+ // passed into the method and listen for Artisan "start" event which will
+ // give us the Artisan console instance which we will give commands to.
+ $events = $this->app['events'];
+
+ $events->listen(ArtisanStarting::class, function ($event) use ($commands) {
+ $event->artisan->resolveCommands($commands);
+ });
+ }
+
+ /**
+ * Get the services provided by the provider.
+ *
+ * @return array
+ */
+ public function provides()
+ {
+ return [];
+ }
+
+ /**
+ * Get the events that trigger this service provider to register.
+ *
+ * @return array
+ */
+ public function when()
+ {
+ return [];
+ }
+
+ /**
+ * Determine if the provider is deferred.
+ *
+ * @return bool
+ */
+ public function isDeferred()
+ {
+ return $this->defer;
+ }
+
+ /**
+ * Get a list of files that should be compiled for the package.
+ *
+ * @return array
+ */
+ public static function compiles()
+ {
+ return [];
+ }
+
+ /**
+ * Dynamically handle missing method calls.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __call($method, $parameters)
+ {
+ if ($method == 'boot') {
+ return;
+ }
+
+ throw new BadMethodCallException("Call to undefined method [{$method}]");
+ }
+}
diff --git a/vendor/illuminate/support/Str.php b/vendor/illuminate/support/Str.php
new file mode 100644
index 00000000..fe9eff0e
--- /dev/null
+++ b/vendor/illuminate/support/Str.php
@@ -0,0 +1,598 @@
+ $val) {
+ $value = str_replace($val, $key, $value);
+ }
+
+ return preg_replace('/[^\x20-\x7E]/u', '', $value);
+ }
+
+ /**
+ * Convert a value to camel case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function camel($value)
+ {
+ if (isset(static::$camelCache[$value])) {
+ return static::$camelCache[$value];
+ }
+
+ return static::$camelCache[$value] = lcfirst(static::studly($value));
+ }
+
+ /**
+ * Determine if a given string contains a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ public static function contains($haystack, $needles)
+ {
+ foreach ((array) $needles as $needle) {
+ if ($needle != '' && mb_strpos($haystack, $needle) !== false) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Determine if a given string ends with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ public static function endsWith($haystack, $needles)
+ {
+ foreach ((array) $needles as $needle) {
+ if ((string) $needle === static::substr($haystack, -static::length($needle))) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Cap a string with a single instance of a given value.
+ *
+ * @param string $value
+ * @param string $cap
+ * @return string
+ */
+ public static function finish($value, $cap)
+ {
+ $quoted = preg_quote($cap, '/');
+
+ return preg_replace('/(?:'.$quoted.')+$/u', '', $value).$cap;
+ }
+
+ /**
+ * Determine if a given string matches a given pattern.
+ *
+ * @param string $pattern
+ * @param string $value
+ * @return bool
+ */
+ public static function is($pattern, $value)
+ {
+ if ($pattern == $value) {
+ return true;
+ }
+
+ $pattern = preg_quote($pattern, '#');
+
+ // Asterisks are translated into zero-or-more regular expression wildcards
+ // to make it convenient to check if the strings starts with the given
+ // pattern such as "library/*", making any string check convenient.
+ $pattern = str_replace('\*', '.*', $pattern);
+
+ return (bool) preg_match('#^'.$pattern.'\z#u', $value);
+ }
+
+ /**
+ * Return the length of the given string.
+ *
+ * @param string $value
+ * @return int
+ */
+ public static function length($value)
+ {
+ return mb_strlen($value);
+ }
+
+ /**
+ * Limit the number of characters in a string.
+ *
+ * @param string $value
+ * @param int $limit
+ * @param string $end
+ * @return string
+ */
+ public static function limit($value, $limit = 100, $end = '...')
+ {
+ if (mb_strwidth($value, 'UTF-8') <= $limit) {
+ return $value;
+ }
+
+ return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')).$end;
+ }
+
+ /**
+ * Convert the given string to lower-case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function lower($value)
+ {
+ return mb_strtolower($value, 'UTF-8');
+ }
+
+ /**
+ * Limit the number of words in a string.
+ *
+ * @param string $value
+ * @param int $words
+ * @param string $end
+ * @return string
+ */
+ public static function words($value, $words = 100, $end = '...')
+ {
+ preg_match('/^\s*+(?:\S++\s*+){1,'.$words.'}/u', $value, $matches);
+
+ if (! isset($matches[0]) || static::length($value) === static::length($matches[0])) {
+ return $value;
+ }
+
+ return rtrim($matches[0]).$end;
+ }
+
+ /**
+ * Parse a Class@method style callback into class and method.
+ *
+ * @param string $callback
+ * @param string $default
+ * @return array
+ */
+ public static function parseCallback($callback, $default)
+ {
+ return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default];
+ }
+
+ /**
+ * Get the plural form of an English word.
+ *
+ * @param string $value
+ * @param int $count
+ * @return string
+ */
+ public static function plural($value, $count = 2)
+ {
+ return Pluralizer::plural($value, $count);
+ }
+
+ /**
+ * Generate a more truly "random" alpha-numeric string.
+ *
+ * @param int $length
+ * @return string
+ */
+ public static function random($length = 16)
+ {
+ $string = '';
+
+ while (($len = static::length($string)) < $length) {
+ $size = $length - $len;
+
+ $bytes = random_bytes($size);
+
+ $string .= static::substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
+ }
+
+ return $string;
+ }
+
+ /**
+ * Generate a more truly "random" bytes.
+ *
+ * @param int $length
+ * @return string
+ *
+ * @deprecated since version 5.2. Use random_bytes instead.
+ */
+ public static function randomBytes($length = 16)
+ {
+ return random_bytes($length);
+ }
+
+ /**
+ * Generate a "random" alpha-numeric string.
+ *
+ * Should not be considered sufficient for cryptography, etc.
+ *
+ * @param int $length
+ * @return string
+ */
+ public static function quickRandom($length = 16)
+ {
+ $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+
+ return static::substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
+ }
+
+ /**
+ * Compares two strings using a constant-time algorithm.
+ *
+ * Note: This method will leak length information.
+ *
+ * Note: Adapted from Symfony\Component\Security\Core\Util\StringUtils.
+ *
+ * @param string $knownString
+ * @param string $userInput
+ * @return bool
+ *
+ * @deprecated since version 5.2. Use hash_equals instead.
+ */
+ public static function equals($knownString, $userInput)
+ {
+ return hash_equals($knownString, $userInput);
+ }
+
+ /**
+ * Replace the first occurrence of a given value in the string.
+ *
+ * @param string $search
+ * @param string $replace
+ * @param string $subject
+ * @return string
+ */
+ public static function replaceFirst($search, $replace, $subject)
+ {
+ $position = strpos($subject, $search);
+
+ if ($position !== false) {
+ return substr_replace($subject, $replace, $position, strlen($search));
+ }
+
+ return $subject;
+ }
+
+ /**
+ * Replace the last occurrence of a given value in the string.
+ *
+ * @param string $search
+ * @param string $replace
+ * @param string $subject
+ * @return string
+ */
+ public static function replaceLast($search, $replace, $subject)
+ {
+ $position = strrpos($subject, $search);
+
+ if ($position !== false) {
+ return substr_replace($subject, $replace, $position, strlen($search));
+ }
+
+ return $subject;
+ }
+
+ /**
+ * Convert the given string to upper-case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function upper($value)
+ {
+ return mb_strtoupper($value, 'UTF-8');
+ }
+
+ /**
+ * Convert the given string to title case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function title($value)
+ {
+ return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
+ }
+
+ /**
+ * Get the singular form of an English word.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function singular($value)
+ {
+ return Pluralizer::singular($value);
+ }
+
+ /**
+ * Generate a URL friendly "slug" from a given string.
+ *
+ * @param string $title
+ * @param string $separator
+ * @return string
+ */
+ public static function slug($title, $separator = '-')
+ {
+ $title = static::ascii($title);
+
+ // Convert all dashes/underscores into separator
+ $flip = $separator == '-' ? '_' : '-';
+
+ $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title);
+
+ // Remove all characters that are not the separator, letters, numbers, or whitespace.
+ $title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', mb_strtolower($title));
+
+ // Replace all separator characters and whitespace by a single separator
+ $title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title);
+
+ return trim($title, $separator);
+ }
+
+ /**
+ * Convert a string to snake case.
+ *
+ * @param string $value
+ * @param string $delimiter
+ * @return string
+ */
+ public static function snake($value, $delimiter = '_')
+ {
+ $key = $value;
+
+ if (isset(static::$snakeCache[$key][$delimiter])) {
+ return static::$snakeCache[$key][$delimiter];
+ }
+
+ if (! ctype_lower($value)) {
+ $value = preg_replace('/\s+/u', '', $value);
+
+ $value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value));
+ }
+
+ return static::$snakeCache[$key][$delimiter] = $value;
+ }
+
+ /**
+ * Determine if a given string starts with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ public static function startsWith($haystack, $needles)
+ {
+ foreach ((array) $needles as $needle) {
+ if ($needle != '' && mb_strpos($haystack, $needle) === 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert a value to studly caps case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function studly($value)
+ {
+ $key = $value;
+
+ if (isset(static::$studlyCache[$key])) {
+ return static::$studlyCache[$key];
+ }
+
+ $value = ucwords(str_replace(['-', '_'], ' ', $value));
+
+ return static::$studlyCache[$key] = str_replace(' ', '', $value);
+ }
+
+ /**
+ * Returns the portion of string specified by the start and length parameters.
+ *
+ * @param string $string
+ * @param int $start
+ * @param int|null $length
+ * @return string
+ */
+ public static function substr($string, $start, $length = null)
+ {
+ return mb_substr($string, $start, $length, 'UTF-8');
+ }
+
+ /**
+ * Make a string's first character uppercase.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function ucfirst($string)
+ {
+ return static::upper(static::substr($string, 0, 1)).static::substr($string, 1);
+ }
+
+ /**
+ * Returns the replacements for the ascii method.
+ *
+ * Note: Adapted from Stringy\Stringy.
+ *
+ * @see https://github.com/danielstjules/Stringy/blob/2.3.1/LICENSE.txt
+ *
+ * @return array
+ */
+ protected static function charsArray()
+ {
+ static $charsArray;
+
+ if (isset($charsArray)) {
+ return $charsArray;
+ }
+
+ return $charsArray = [
+ '0' => ['°', '₀', '۰'],
+ '1' => ['¹', '₁', '۱'],
+ '2' => ['²', '₂', '۲'],
+ '3' => ['³', '₃', '۳'],
+ '4' => ['⁴', '₄', '۴', '٤'],
+ '5' => ['⁵', '₅', '۵', '٥'],
+ '6' => ['⁶', '₆', '۶', '٦'],
+ '7' => ['⁷', '₇', '۷'],
+ '8' => ['⁸', '₈', '۸'],
+ '9' => ['⁹', '₉', '۹'],
+ 'a' => ['à', 'á', 'ả', 'ã', 'ạ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ', 'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ā', 'ą', 'å', 'α', 'ά', 'ἀ', 'ἁ', 'ἂ', 'ἃ', 'ἄ', 'ἅ', 'ἆ', 'ἇ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ὰ', 'ά', 'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'а', 'أ', 'အ', 'ာ', 'ါ', 'ǻ', 'ǎ', 'ª', 'ა', 'अ', 'ا'],
+ 'b' => ['б', 'β', 'Ъ', 'Ь', 'ب', 'ဗ', 'ბ'],
+ 'c' => ['ç', 'ć', 'č', 'ĉ', 'ċ'],
+ 'd' => ['ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ', 'д', 'δ', 'د', 'ض', 'ဍ', 'ဒ', 'დ'],
+ 'e' => ['é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê', 'ế', 'ề', 'ể', 'ễ', 'ệ', 'ë', 'ē', 'ę', 'ě', 'ĕ', 'ė', 'ε', 'έ', 'ἐ', 'ἑ', 'ἒ', 'ἓ', 'ἔ', 'ἕ', 'ὲ', 'έ', 'е', 'ё', 'э', 'є', 'ə', 'ဧ', 'ေ', 'ဲ', 'ე', 'ए', 'إ', 'ئ'],
+ 'f' => ['ф', 'φ', 'ف', 'ƒ', 'ფ'],
+ 'g' => ['ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ဂ', 'გ', 'گ'],
+ 'h' => ['ĥ', 'ħ', 'η', 'ή', 'ح', 'ه', 'ဟ', 'ှ', 'ჰ'],
+ 'i' => ['í', 'ì', 'ỉ', 'ĩ', 'ị', 'î', 'ï', 'ī', 'ĭ', 'į', 'ı', 'ι', 'ί', 'ϊ', 'ΐ', 'ἰ', 'ἱ', 'ἲ', 'ἳ', 'ἴ', 'ἵ', 'ἶ', 'ἷ', 'ὶ', 'ί', 'ῐ', 'ῑ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'і', 'ї', 'и', 'ဣ', 'ိ', 'ီ', 'ည်', 'ǐ', 'ი', 'इ'],
+ 'j' => ['ĵ', 'ј', 'Ј', 'ჯ', 'ج'],
+ 'k' => ['ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك', 'က', 'კ', 'ქ', 'ک'],
+ 'l' => ['ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل', 'လ', 'ლ'],
+ 'm' => ['м', 'μ', 'م', 'မ', 'მ'],
+ 'n' => ['ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن', 'န', 'ნ'],
+ 'o' => ['ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ố', 'ồ', 'ổ', 'ỗ', 'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ', 'ø', 'ō', 'ő', 'ŏ', 'ο', 'ὀ', 'ὁ', 'ὂ', 'ὃ', 'ὄ', 'ὅ', 'ὸ', 'ό', 'о', 'و', 'θ', 'ို', 'ǒ', 'ǿ', 'º', 'ო', 'ओ'],
+ 'p' => ['п', 'π', 'ပ', 'პ', 'پ'],
+ 'q' => ['ყ'],
+ 'r' => ['ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر', 'რ'],
+ 's' => ['ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص', 'စ', 'ſ', 'ს'],
+ 't' => ['ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط', 'ဋ', 'တ', 'ŧ', 'თ', 'ტ'],
+ 'u' => ['ú', 'ù', 'ủ', 'ũ', 'ụ', 'ư', 'ứ', 'ừ', 'ử', 'ữ', 'ự', 'û', 'ū', 'ů', 'ű', 'ŭ', 'ų', 'µ', 'у', 'ဉ', 'ု', 'ူ', 'ǔ', 'ǖ', 'ǘ', 'ǚ', 'ǜ', 'უ', 'उ'],
+ 'v' => ['в', 'ვ', 'ϐ'],
+ 'w' => ['ŵ', 'ω', 'ώ', 'ဝ', 'ွ'],
+ 'x' => ['χ', 'ξ'],
+ 'y' => ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ', 'ϋ', 'ύ', 'ΰ', 'ي', 'ယ'],
+ 'z' => ['ź', 'ž', 'ż', 'з', 'ζ', 'ز', 'ဇ', 'ზ'],
+ 'aa' => ['ع', 'आ', 'آ'],
+ 'ae' => ['ä', 'æ', 'ǽ'],
+ 'ai' => ['ऐ'],
+ 'at' => ['@'],
+ 'ch' => ['ч', 'ჩ', 'ჭ', 'چ'],
+ 'dj' => ['ђ', 'đ'],
+ 'dz' => ['џ', 'ძ'],
+ 'ei' => ['ऍ'],
+ 'gh' => ['غ', 'ღ'],
+ 'ii' => ['ई'],
+ 'ij' => ['ij'],
+ 'kh' => ['х', 'خ', 'ხ'],
+ 'lj' => ['љ'],
+ 'nj' => ['њ'],
+ 'oe' => ['ö', 'œ', 'ؤ'],
+ 'oi' => ['ऑ'],
+ 'oii' => ['ऒ'],
+ 'ps' => ['ψ'],
+ 'sh' => ['ш', 'შ', 'ش'],
+ 'shch' => ['щ'],
+ 'ss' => ['ß'],
+ 'sx' => ['ŝ'],
+ 'th' => ['þ', 'ϑ', 'ث', 'ذ', 'ظ'],
+ 'ts' => ['ц', 'ც', 'წ'],
+ 'ue' => ['ü'],
+ 'uu' => ['ऊ'],
+ 'ya' => ['я'],
+ 'yu' => ['ю'],
+ 'zh' => ['ж', 'ჟ', 'ژ'],
+ '(c)' => ['©'],
+ 'A' => ['Á', 'À', 'Ả', 'Ã', 'Ạ', 'Ă', 'Ắ', 'Ằ', 'Ẳ', 'Ẵ', 'Ặ', 'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Å', 'Ā', 'Ą', 'Α', 'Ά', 'Ἀ', 'Ἁ', 'Ἂ', 'Ἃ', 'Ἄ', 'Ἅ', 'Ἆ', 'Ἇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'Ᾰ', 'Ᾱ', 'Ὰ', 'Ά', 'ᾼ', 'А', 'Ǻ', 'Ǎ'],
+ 'B' => ['Б', 'Β', 'ब'],
+ 'C' => ['Ç', 'Ć', 'Č', 'Ĉ', 'Ċ'],
+ 'D' => ['Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ'],
+ 'E' => ['É', 'È', 'Ẻ', 'Ẽ', 'Ẹ', 'Ê', 'Ế', 'Ề', 'Ể', 'Ễ', 'Ệ', 'Ë', 'Ē', 'Ę', 'Ě', 'Ĕ', 'Ė', 'Ε', 'Έ', 'Ἐ', 'Ἑ', 'Ἒ', 'Ἓ', 'Ἔ', 'Ἕ', 'Έ', 'Ὲ', 'Е', 'Ё', 'Э', 'Є', 'Ə'],
+ 'F' => ['Ф', 'Φ'],
+ 'G' => ['Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ'],
+ 'H' => ['Η', 'Ή', 'Ħ'],
+ 'I' => ['Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị', 'Î', 'Ï', 'Ī', 'Ĭ', 'Į', 'İ', 'Ι', 'Ί', 'Ϊ', 'Ἰ', 'Ἱ', 'Ἳ', 'Ἴ', 'Ἵ', 'Ἶ', 'Ἷ', 'Ῐ', 'Ῑ', 'Ὶ', 'Ί', 'И', 'І', 'Ї', 'Ǐ', 'ϒ'],
+ 'K' => ['К', 'Κ'],
+ 'L' => ['Ĺ', 'Ł', 'Л', 'Λ', 'Ļ', 'Ľ', 'Ŀ', 'ल'],
+ 'M' => ['М', 'Μ'],
+ 'N' => ['Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν'],
+ 'O' => ['Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ', 'Ô', 'Ố', 'Ồ', 'Ổ', 'Ỗ', 'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ', 'Ø', 'Ō', 'Ő', 'Ŏ', 'Ο', 'Ό', 'Ὀ', 'Ὁ', 'Ὂ', 'Ὃ', 'Ὄ', 'Ὅ', 'Ὸ', 'Ό', 'О', 'Θ', 'Ө', 'Ǒ', 'Ǿ'],
+ 'P' => ['П', 'Π'],
+ 'R' => ['Ř', 'Ŕ', 'Р', 'Ρ', 'Ŗ'],
+ 'S' => ['Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ'],
+ 'T' => ['Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ'],
+ 'U' => ['Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ', 'Ư', 'Ứ', 'Ừ', 'Ử', 'Ữ', 'Ự', 'Û', 'Ū', 'Ů', 'Ű', 'Ŭ', 'Ų', 'У', 'Ǔ', 'Ǖ', 'Ǘ', 'Ǚ', 'Ǜ'],
+ 'V' => ['В'],
+ 'W' => ['Ω', 'Ώ', 'Ŵ'],
+ 'X' => ['Χ', 'Ξ'],
+ 'Y' => ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ', 'Ы', 'Й', 'Υ', 'Ϋ', 'Ŷ'],
+ 'Z' => ['Ź', 'Ž', 'Ż', 'З', 'Ζ'],
+ 'AE' => ['Ä', 'Æ', 'Ǽ'],
+ 'CH' => ['Ч'],
+ 'DJ' => ['Ђ'],
+ 'DZ' => ['Џ'],
+ 'GX' => ['Ĝ'],
+ 'HX' => ['Ĥ'],
+ 'IJ' => ['IJ'],
+ 'JX' => ['Ĵ'],
+ 'KH' => ['Х'],
+ 'LJ' => ['Љ'],
+ 'NJ' => ['Њ'],
+ 'OE' => ['Ö', 'Œ'],
+ 'PS' => ['Ψ'],
+ 'SH' => ['Ш'],
+ 'SHCH' => ['Щ'],
+ 'SS' => ['ẞ'],
+ 'TH' => ['Þ'],
+ 'TS' => ['Ц'],
+ 'UE' => ['Ü'],
+ 'YA' => ['Я'],
+ 'YU' => ['Ю'],
+ 'ZH' => ['Ж'],
+ ' ' => ["\xC2\xA0", "\xE2\x80\x80", "\xE2\x80\x81", "\xE2\x80\x82", "\xE2\x80\x83", "\xE2\x80\x84", "\xE2\x80\x85", "\xE2\x80\x86", "\xE2\x80\x87", "\xE2\x80\x88", "\xE2\x80\x89", "\xE2\x80\x8A", "\xE2\x80\xAF", "\xE2\x81\x9F", "\xE3\x80\x80"],
+ ];
+ }
+}
diff --git a/vendor/illuminate/support/Traits/CapsuleManagerTrait.php b/vendor/illuminate/support/Traits/CapsuleManagerTrait.php
new file mode 100644
index 00000000..08089ef6
--- /dev/null
+++ b/vendor/illuminate/support/Traits/CapsuleManagerTrait.php
@@ -0,0 +1,69 @@
+container = $container;
+
+ if (! $this->container->bound('config')) {
+ $this->container->instance('config', new Fluent);
+ }
+ }
+
+ /**
+ * Make this capsule instance available globally.
+ *
+ * @return void
+ */
+ public function setAsGlobal()
+ {
+ static::$instance = $this;
+ }
+
+ /**
+ * Get the IoC container instance.
+ *
+ * @return \Illuminate\Contracts\Container\Container
+ */
+ public function getContainer()
+ {
+ return $this->container;
+ }
+
+ /**
+ * Set the IoC container instance.
+ *
+ * @param \Illuminate\Contracts\Container\Container $container
+ * @return void
+ */
+ public function setContainer(Container $container)
+ {
+ $this->container = $container;
+ }
+}
diff --git a/vendor/illuminate/support/Traits/Macroable.php b/vendor/illuminate/support/Traits/Macroable.php
new file mode 100644
index 00000000..2c103d4f
--- /dev/null
+++ b/vendor/illuminate/support/Traits/Macroable.php
@@ -0,0 +1,83 @@
+bindTo($this, static::class), $parameters);
+ }
+
+ return call_user_func_array(static::$macros[$method], $parameters);
+ }
+}
diff --git a/vendor/illuminate/support/ViewErrorBag.php b/vendor/illuminate/support/ViewErrorBag.php
new file mode 100644
index 00000000..9fe3b961
--- /dev/null
+++ b/vendor/illuminate/support/ViewErrorBag.php
@@ -0,0 +1,107 @@
+bags[$key]);
+ }
+
+ /**
+ * Get a MessageBag instance from the bags.
+ *
+ * @param string $key
+ * @return \Illuminate\Contracts\Support\MessageBag
+ */
+ public function getBag($key)
+ {
+ return Arr::get($this->bags, $key) ?: new MessageBag;
+ }
+
+ /**
+ * Get all the bags.
+ *
+ * @return array
+ */
+ public function getBags()
+ {
+ return $this->bags;
+ }
+
+ /**
+ * Add a new MessageBag instance to the bags.
+ *
+ * @param string $key
+ * @param \Illuminate\Contracts\Support\MessageBag $bag
+ * @return $this
+ */
+ public function put($key, MessageBagContract $bag)
+ {
+ $this->bags[$key] = $bag;
+
+ return $this;
+ }
+
+ /**
+ * Get the number of messages in the default bag.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return $this->default->count();
+ }
+
+ /**
+ * Dynamically call methods on the default bag.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ return call_user_func_array([$this->default, $method], $parameters);
+ }
+
+ /**
+ * Dynamically access a view error bag.
+ *
+ * @param string $key
+ * @return \Illuminate\Contracts\Support\MessageBag
+ */
+ public function __get($key)
+ {
+ return $this->getBag($key);
+ }
+
+ /**
+ * Dynamically set a view error bag.
+ *
+ * @param string $key
+ * @param \Illuminate\Contracts\Support\MessageBag $value
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this->put($key, $value);
+ }
+}
diff --git a/vendor/illuminate/support/composer.json b/vendor/illuminate/support/composer.json
new file mode 100644
index 00000000..625471b1
--- /dev/null
+++ b/vendor/illuminate/support/composer.json
@@ -0,0 +1,47 @@
+{
+ "name": "illuminate/support",
+ "description": "The Illuminate Support package.",
+ "license": "MIT",
+ "homepage": "http://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.5.9",
+ "ext-mbstring": "*",
+ "doctrine/inflector": "~1.0",
+ "illuminate/contracts": "5.2.*",
+ "paragonie/random_compat": "~1.4"
+ },
+ "replace": {
+ "tightenco/collect": "self.version"
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Support\\": ""
+ },
+ "files": [
+ "helpers.php"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.2-dev"
+ }
+ },
+ "suggest": {
+ "illuminate/filesystem": "Required to use the composer class (5.2.*).",
+ "jeremeamia/superclosure": "Required to be able to serialize closures (~2.2).",
+ "symfony/polyfill-php56": "Required to use the hash_equals function on PHP 5.5 (~1.0).",
+ "symfony/process": "Required to use the composer class (2.8.*|3.0.*).",
+ "symfony/var-dumper": "Improves the dd function (2.8.*|3.0.*)."
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/support/helpers.php b/vendor/illuminate/support/helpers.php
new file mode 100755
index 00000000..4294cfc8
--- /dev/null
+++ b/vendor/illuminate/support/helpers.php
@@ -0,0 +1,892 @@
+ $value) {
+ if (is_numeric($key)) {
+ $start++;
+
+ $array[$start] = Arr::pull($array, $key);
+ }
+ }
+
+ return $array;
+ }
+}
+
+if (! function_exists('array_add')) {
+ /**
+ * Add an element to an array using "dot" notation if it doesn't exist.
+ *
+ * @param array $array
+ * @param string $key
+ * @param mixed $value
+ * @return array
+ */
+ function array_add($array, $key, $value)
+ {
+ return Arr::add($array, $key, $value);
+ }
+}
+
+if (! function_exists('array_build')) {
+ /**
+ * Build a new array using a callback.
+ *
+ * @param array $array
+ * @param callable $callback
+ * @return array
+ *
+ * @deprecated since version 5.2.
+ */
+ function array_build($array, callable $callback)
+ {
+ return Arr::build($array, $callback);
+ }
+}
+
+if (! function_exists('array_collapse')) {
+ /**
+ * Collapse an array of arrays into a single array.
+ *
+ * @param array $array
+ * @return array
+ */
+ function array_collapse($array)
+ {
+ return Arr::collapse($array);
+ }
+}
+
+if (! function_exists('array_divide')) {
+ /**
+ * Divide an array into two arrays. One with keys and the other with values.
+ *
+ * @param array $array
+ * @return array
+ */
+ function array_divide($array)
+ {
+ return Arr::divide($array);
+ }
+}
+
+if (! function_exists('array_dot')) {
+ /**
+ * Flatten a multi-dimensional associative array with dots.
+ *
+ * @param array $array
+ * @param string $prepend
+ * @return array
+ */
+ function array_dot($array, $prepend = '')
+ {
+ return Arr::dot($array, $prepend);
+ }
+}
+
+if (! function_exists('array_except')) {
+ /**
+ * Get all of the given array except for a specified array of items.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return array
+ */
+ function array_except($array, $keys)
+ {
+ return Arr::except($array, $keys);
+ }
+}
+
+if (! function_exists('array_first')) {
+ /**
+ * Return the first element in an array passing a given truth test.
+ *
+ * @param array $array
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ function array_first($array, callable $callback = null, $default = null)
+ {
+ return Arr::first($array, $callback, $default);
+ }
+}
+
+if (! function_exists('array_flatten')) {
+ /**
+ * Flatten a multi-dimensional array into a single level.
+ *
+ * @param array $array
+ * @param int $depth
+ * @return array
+ */
+ function array_flatten($array, $depth = INF)
+ {
+ return Arr::flatten($array, $depth);
+ }
+}
+
+if (! function_exists('array_forget')) {
+ /**
+ * Remove one or many array items from a given array using "dot" notation.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return void
+ */
+ function array_forget(&$array, $keys)
+ {
+ return Arr::forget($array, $keys);
+ }
+}
+
+if (! function_exists('array_get')) {
+ /**
+ * Get an item from an array using "dot" notation.
+ *
+ * @param \ArrayAccess|array $array
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ function array_get($array, $key, $default = null)
+ {
+ return Arr::get($array, $key, $default);
+ }
+}
+
+if (! function_exists('array_has')) {
+ /**
+ * Check if an item exists in an array using "dot" notation.
+ *
+ * @param \ArrayAccess|array $array
+ * @param string $key
+ * @return bool
+ */
+ function array_has($array, $key)
+ {
+ return Arr::has($array, $key);
+ }
+}
+
+if (! function_exists('array_last')) {
+ /**
+ * Return the last element in an array passing a given truth test.
+ *
+ * @param array $array
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ function array_last($array, callable $callback = null, $default = null)
+ {
+ return Arr::last($array, $callback, $default);
+ }
+}
+
+if (! function_exists('array_only')) {
+ /**
+ * Get a subset of the items from the given array.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return array
+ */
+ function array_only($array, $keys)
+ {
+ return Arr::only($array, $keys);
+ }
+}
+
+if (! function_exists('array_pluck')) {
+ /**
+ * Pluck an array of values from an array.
+ *
+ * @param array $array
+ * @param string|array $value
+ * @param string|array|null $key
+ * @return array
+ */
+ function array_pluck($array, $value, $key = null)
+ {
+ return Arr::pluck($array, $value, $key);
+ }
+}
+
+if (! function_exists('array_prepend')) {
+ /**
+ * Push an item onto the beginning of an array.
+ *
+ * @param array $array
+ * @param mixed $value
+ * @param mixed $key
+ * @return array
+ */
+ function array_prepend($array, $value, $key = null)
+ {
+ return Arr::prepend($array, $value, $key);
+ }
+}
+
+if (! function_exists('array_pull')) {
+ /**
+ * Get a value from the array, and remove it.
+ *
+ * @param array $array
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ function array_pull(&$array, $key, $default = null)
+ {
+ return Arr::pull($array, $key, $default);
+ }
+}
+
+if (! function_exists('array_set')) {
+ /**
+ * Set an array item to a given value using "dot" notation.
+ *
+ * If no key is given to the method, the entire array will be replaced.
+ *
+ * @param array $array
+ * @param string $key
+ * @param mixed $value
+ * @return array
+ */
+ function array_set(&$array, $key, $value)
+ {
+ return Arr::set($array, $key, $value);
+ }
+}
+
+if (! function_exists('array_sort')) {
+ /**
+ * Sort the array using the given callback.
+ *
+ * @param array $array
+ * @param callable $callback
+ * @return array
+ */
+ function array_sort($array, callable $callback)
+ {
+ return Arr::sort($array, $callback);
+ }
+}
+
+if (! function_exists('array_sort_recursive')) {
+ /**
+ * Recursively sort an array by keys and values.
+ *
+ * @param array $array
+ * @return array
+ */
+ function array_sort_recursive($array)
+ {
+ return Arr::sortRecursive($array);
+ }
+}
+
+if (! function_exists('array_where')) {
+ /**
+ * Filter the array using the given callback.
+ *
+ * @param array $array
+ * @param callable $callback
+ * @return array
+ */
+ function array_where($array, callable $callback)
+ {
+ return Arr::where($array, $callback);
+ }
+}
+
+if (! function_exists('camel_case')) {
+ /**
+ * Convert a value to camel case.
+ *
+ * @param string $value
+ * @return string
+ */
+ function camel_case($value)
+ {
+ return Str::camel($value);
+ }
+}
+
+if (! function_exists('class_basename')) {
+ /**
+ * Get the class "basename" of the given object / class.
+ *
+ * @param string|object $class
+ * @return string
+ */
+ function class_basename($class)
+ {
+ $class = is_object($class) ? get_class($class) : $class;
+
+ return basename(str_replace('\\', '/', $class));
+ }
+}
+
+if (! function_exists('class_uses_recursive')) {
+ /**
+ * Returns all traits used by a class, its subclasses and trait of their traits.
+ *
+ * @param string $class
+ * @return array
+ */
+ function class_uses_recursive($class)
+ {
+ $results = [];
+
+ foreach (array_merge([$class => $class], class_parents($class)) as $class) {
+ $results += trait_uses_recursive($class);
+ }
+
+ return array_unique($results);
+ }
+}
+
+if (! function_exists('collect')) {
+ /**
+ * Create a collection from the given value.
+ *
+ * @param mixed $value
+ * @return \Illuminate\Support\Collection
+ */
+ function collect($value = null)
+ {
+ return new Collection($value);
+ }
+}
+
+if (! function_exists('data_fill')) {
+ /**
+ * Fill in data where it's missing.
+ *
+ * @param mixed $target
+ * @param string|array $key
+ * @param mixed $value
+ * @return mixed
+ */
+ function data_fill(&$target, $key, $value)
+ {
+ return data_set($target, $key, $value, false);
+ }
+}
+
+if (! function_exists('data_get')) {
+ /**
+ * Get an item from an array or object using "dot" notation.
+ *
+ * @param mixed $target
+ * @param string|array $key
+ * @param mixed $default
+ * @return mixed
+ */
+ function data_get($target, $key, $default = null)
+ {
+ if (is_null($key)) {
+ return $target;
+ }
+
+ $key = is_array($key) ? $key : explode('.', $key);
+
+ while (($segment = array_shift($key)) !== null) {
+ if ($segment === '*') {
+ if ($target instanceof Collection) {
+ $target = $target->all();
+ } elseif (! is_array($target)) {
+ return value($default);
+ }
+
+ $result = Arr::pluck($target, $key);
+
+ return in_array('*', $key) ? Arr::collapse($result) : $result;
+ }
+
+ if (Arr::accessible($target) && Arr::exists($target, $segment)) {
+ $target = $target[$segment];
+ } elseif (is_object($target) && isset($target->{$segment})) {
+ $target = $target->{$segment};
+ } else {
+ return value($default);
+ }
+ }
+
+ return $target;
+ }
+}
+
+if (! function_exists('data_set')) {
+ /**
+ * Set an item on an array or object using dot notation.
+ *
+ * @param mixed $target
+ * @param string|array $key
+ * @param mixed $value
+ * @param bool $overwrite
+ * @return mixed
+ */
+ function data_set(&$target, $key, $value, $overwrite = true)
+ {
+ $segments = is_array($key) ? $key : explode('.', $key);
+
+ if (($segment = array_shift($segments)) === '*') {
+ if (! Arr::accessible($target)) {
+ $target = [];
+ }
+
+ if ($segments) {
+ foreach ($target as &$inner) {
+ data_set($inner, $segments, $value, $overwrite);
+ }
+ } elseif ($overwrite) {
+ foreach ($target as &$inner) {
+ $inner = $value;
+ }
+ }
+ } elseif (Arr::accessible($target)) {
+ if ($segments) {
+ if (! Arr::exists($target, $segment)) {
+ $target[$segment] = [];
+ }
+
+ data_set($target[$segment], $segments, $value, $overwrite);
+ } elseif ($overwrite || ! Arr::exists($target, $segment)) {
+ $target[$segment] = $value;
+ }
+ } elseif (is_object($target)) {
+ if ($segments) {
+ if (! isset($target->{$segment})) {
+ $target->{$segment} = [];
+ }
+
+ data_set($target->{$segment}, $segments, $value, $overwrite);
+ } elseif ($overwrite || ! isset($target->{$segment})) {
+ $target->{$segment} = $value;
+ }
+ } else {
+ $target = [];
+
+ if ($segments) {
+ data_set($target[$segment], $segments, $value, $overwrite);
+ } elseif ($overwrite) {
+ $target[$segment] = $value;
+ }
+ }
+
+ return $target;
+ }
+}
+
+if (! function_exists('dd')) {
+ /**
+ * Dump the passed variables and end the script.
+ *
+ * @param mixed
+ * @return void
+ */
+ function dd()
+ {
+ array_map(function ($x) {
+ (new Dumper)->dump($x);
+ }, func_get_args());
+
+ die(1);
+ }
+}
+
+if (! function_exists('e')) {
+ /**
+ * Escape HTML entities in a string.
+ *
+ * @param \Illuminate\Contracts\Support\Htmlable|string $value
+ * @return string
+ */
+ function e($value)
+ {
+ if ($value instanceof Htmlable) {
+ return $value->toHtml();
+ }
+
+ return htmlentities($value, ENT_QUOTES, 'UTF-8', false);
+ }
+}
+
+if (! function_exists('ends_with')) {
+ /**
+ * Determine if a given string ends with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ function ends_with($haystack, $needles)
+ {
+ return Str::endsWith($haystack, $needles);
+ }
+}
+
+if (! function_exists('head')) {
+ /**
+ * Get the first element of an array. Useful for method chaining.
+ *
+ * @param array $array
+ * @return mixed
+ */
+ function head($array)
+ {
+ return reset($array);
+ }
+}
+
+if (! function_exists('last')) {
+ /**
+ * Get the last element from an array.
+ *
+ * @param array $array
+ * @return mixed
+ */
+ function last($array)
+ {
+ return end($array);
+ }
+}
+
+if (! function_exists('object_get')) {
+ /**
+ * Get an item from an object using "dot" notation.
+ *
+ * @param object $object
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ function object_get($object, $key, $default = null)
+ {
+ if (is_null($key) || trim($key) == '') {
+ return $object;
+ }
+
+ foreach (explode('.', $key) as $segment) {
+ if (! is_object($object) || ! isset($object->{$segment})) {
+ return value($default);
+ }
+
+ $object = $object->{$segment};
+ }
+
+ return $object;
+ }
+}
+
+if (! function_exists('preg_replace_sub')) {
+ /**
+ * Replace a given pattern with each value in the array in sequentially.
+ *
+ * @param string $pattern
+ * @param array $replacements
+ * @param string $subject
+ * @return string
+ */
+ function preg_replace_sub($pattern, &$replacements, $subject)
+ {
+ return preg_replace_callback($pattern, function ($match) use (&$replacements) {
+ foreach ($replacements as $key => $value) {
+ return array_shift($replacements);
+ }
+ }, $subject);
+ }
+}
+
+if (! function_exists('snake_case')) {
+ /**
+ * Convert a string to snake case.
+ *
+ * @param string $value
+ * @param string $delimiter
+ * @return string
+ */
+ function snake_case($value, $delimiter = '_')
+ {
+ return Str::snake($value, $delimiter);
+ }
+}
+
+if (! function_exists('starts_with')) {
+ /**
+ * Determine if a given string starts with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ function starts_with($haystack, $needles)
+ {
+ return Str::startsWith($haystack, $needles);
+ }
+}
+
+if (! function_exists('str_contains')) {
+ /**
+ * Determine if a given string contains a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ function str_contains($haystack, $needles)
+ {
+ return Str::contains($haystack, $needles);
+ }
+}
+
+if (! function_exists('str_finish')) {
+ /**
+ * Cap a string with a single instance of a given value.
+ *
+ * @param string $value
+ * @param string $cap
+ * @return string
+ */
+ function str_finish($value, $cap)
+ {
+ return Str::finish($value, $cap);
+ }
+}
+
+if (! function_exists('str_is')) {
+ /**
+ * Determine if a given string matches a given pattern.
+ *
+ * @param string $pattern
+ * @param string $value
+ * @return bool
+ */
+ function str_is($pattern, $value)
+ {
+ return Str::is($pattern, $value);
+ }
+}
+
+if (! function_exists('str_limit')) {
+ /**
+ * Limit the number of characters in a string.
+ *
+ * @param string $value
+ * @param int $limit
+ * @param string $end
+ * @return string
+ */
+ function str_limit($value, $limit = 100, $end = '...')
+ {
+ return Str::limit($value, $limit, $end);
+ }
+}
+
+if (! function_exists('str_plural')) {
+ /**
+ * Get the plural form of an English word.
+ *
+ * @param string $value
+ * @param int $count
+ * @return string
+ */
+ function str_plural($value, $count = 2)
+ {
+ return Str::plural($value, $count);
+ }
+}
+
+if (! function_exists('str_random')) {
+ /**
+ * Generate a more truly "random" alpha-numeric string.
+ *
+ * @param int $length
+ * @return string
+ *
+ * @throws \RuntimeException
+ */
+ function str_random($length = 16)
+ {
+ return Str::random($length);
+ }
+}
+
+if (! function_exists('str_replace_array')) {
+ /**
+ * Replace a given value in the string sequentially with an array.
+ *
+ * @param string $search
+ * @param array $replace
+ * @param string $subject
+ * @return string
+ */
+ function str_replace_array($search, array $replace, $subject)
+ {
+ foreach ($replace as $value) {
+ $subject = preg_replace('/'.$search.'/', $value, $subject, 1);
+ }
+
+ return $subject;
+ }
+}
+
+if (! function_exists('str_replace_first')) {
+ /**
+ * Replace the first occurrence of a given value in the string.
+ *
+ * @param string $search
+ * @param string $replace
+ * @param string $subject
+ * @return string
+ */
+ function str_replace_first($search, $replace, $subject)
+ {
+ return Str::replaceFirst($search, $replace, $subject);
+ }
+}
+
+if (! function_exists('str_replace_last')) {
+ /**
+ * Replace the last occurrence of a given value in the string.
+ *
+ * @param string $search
+ * @param string $replace
+ * @param string $subject
+ * @return string
+ */
+ function str_replace_last($search, $replace, $subject)
+ {
+ return Str::replaceLast($search, $replace, $subject);
+ }
+}
+
+if (! function_exists('str_singular')) {
+ /**
+ * Get the singular form of an English word.
+ *
+ * @param string $value
+ * @return string
+ */
+ function str_singular($value)
+ {
+ return Str::singular($value);
+ }
+}
+
+if (! function_exists('str_slug')) {
+ /**
+ * Generate a URL friendly "slug" from a given string.
+ *
+ * @param string $title
+ * @param string $separator
+ * @return string
+ */
+ function str_slug($title, $separator = '-')
+ {
+ return Str::slug($title, $separator);
+ }
+}
+
+if (! function_exists('studly_case')) {
+ /**
+ * Convert a value to studly caps case.
+ *
+ * @param string $value
+ * @return string
+ */
+ function studly_case($value)
+ {
+ return Str::studly($value);
+ }
+}
+
+if (! function_exists('title_case')) {
+ /**
+ * Convert a value to title case.
+ *
+ * @param string $value
+ * @return string
+ */
+ function title_case($value)
+ {
+ return Str::title($value);
+ }
+}
+
+if (! function_exists('trait_uses_recursive')) {
+ /**
+ * Returns all traits used by a trait and its traits.
+ *
+ * @param string $trait
+ * @return array
+ */
+ function trait_uses_recursive($trait)
+ {
+ $traits = class_uses($trait);
+
+ foreach ($traits as $trait) {
+ $traits += trait_uses_recursive($trait);
+ }
+
+ return $traits;
+ }
+}
+
+if (! function_exists('value')) {
+ /**
+ * Return the default value of the given value.
+ *
+ * @param mixed $value
+ * @return mixed
+ */
+ function value($value)
+ {
+ return $value instanceof Closure ? $value() : $value;
+ }
+}
+
+if (! function_exists('windows_os')) {
+ /**
+ * Determine whether the current environment is Windows based.
+ *
+ * @return bool
+ */
+ function windows_os()
+ {
+ return strtolower(substr(PHP_OS, 0, 3)) === 'win';
+ }
+}
+
+if (! function_exists('with')) {
+ /**
+ * Return the given object. Useful for chaining.
+ *
+ * @param mixed $object
+ * @return mixed
+ */
+ function with($object)
+ {
+ return $object;
+ }
+}
diff --git a/vendor/nesbot/carbon/.php_cs.dist b/vendor/nesbot/carbon/.php_cs.dist
new file mode 100644
index 00000000..ff8b56f0
--- /dev/null
+++ b/vendor/nesbot/carbon/.php_cs.dist
@@ -0,0 +1,57 @@
+ true,
+ 'array_syntax' => [
+ 'syntax' => 'long',
+ ],
+ 'binary_operator_spaces' => [
+ 'align_double_arrow' => false,
+ 'align_equals' => false,
+ ],
+ 'blank_line_before_return' => true,
+ 'cast_spaces' => true,
+ 'concat_space' => [
+ 'spacing' => 'none',
+ ],
+ 'ereg_to_preg' => true,
+ 'method_separation' => true,
+ 'no_blank_lines_after_phpdoc' => true,
+ 'no_extra_consecutive_blank_lines' => true,
+ 'no_short_bool_cast' => true,
+ 'no_unneeded_control_parentheses' => true,
+ 'no_unused_imports' => true,
+ 'no_whitespace_in_blank_line' => true,
+ 'ordered_imports' => true,
+ 'phpdoc_align' => true,
+ 'phpdoc_indent' => true,
+ 'phpdoc_inline_tag' => true,
+ 'phpdoc_no_access' => true,
+ 'phpdoc_no_alias_tag' => [
+ 'type' => 'var',
+ ],
+ 'phpdoc_no_package' => true,
+ 'phpdoc_order' => true,
+ 'phpdoc_scalar' => true,
+ 'phpdoc_separation' => true,
+ 'phpdoc_to_comment' => true,
+ 'phpdoc_trim' => true,
+ 'phpdoc_types' => true,
+ 'phpdoc_var_without_name' => true,
+ 'self_accessor' => true,
+ 'single_quote' => true,
+ 'space_after_semicolon' => true,
+ 'standardize_not_equals' => true,
+ 'ternary_operator_spaces' => true,
+ 'trailing_comma_in_multiline_array' => true,
+ 'trim_array_spaces' => true,
+ 'unary_operator_spaces' => true,
+];
+
+return Config::create()->setRules($rules)
+ ->setFinder(Finder::create()->in(__DIR__))
+ ->setUsingCache(true)
+ ->setRiskyAllowed(true);
\ No newline at end of file
diff --git a/vendor/nesbot/carbon/LICENSE b/vendor/nesbot/carbon/LICENSE
new file mode 100644
index 00000000..6de45ebf
--- /dev/null
+++ b/vendor/nesbot/carbon/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) Brian Nesbitt
+
+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/nesbot/carbon/composer.json b/vendor/nesbot/carbon/composer.json
new file mode 100644
index 00000000..63d576d1
--- /dev/null
+++ b/vendor/nesbot/carbon/composer.json
@@ -0,0 +1,54 @@
+{
+ "name": "nesbot/carbon",
+ "type": "library",
+ "description": "A simple API extension for DateTime.",
+ "keywords": [
+ "date",
+ "time",
+ "DateTime"
+ ],
+ "homepage": "http://carbon.nesbot.com",
+ "support": {
+ "issues": "https://github.com/briannesbitt/Carbon/issues",
+ "source": "https://github.com/briannesbitt/Carbon"
+ },
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Brian Nesbitt",
+ "email": "brian@nesbot.com",
+ "homepage": "http://nesbot.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0",
+ "symfony/translation": "~2.6 || ~3.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "~2",
+ "phpunit/phpunit": "~4.0 || ~5.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Carbon\\": "src/Carbon/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\": "tests/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.23-dev"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "scripts": {
+ "test": "./vendor/bin/phpunit; ./vendor/bin/php-cs-fixer fix -v --diff --dry-run;",
+ "phpunit": "./vendor/bin/phpunit;",
+ "phpcs": "./vendor/bin/php-cs-fixer fix -v --diff --dry-run;"
+ }
+}
diff --git a/vendor/nesbot/carbon/readme.md b/vendor/nesbot/carbon/readme.md
new file mode 100644
index 00000000..57836c3a
--- /dev/null
+++ b/vendor/nesbot/carbon/readme.md
@@ -0,0 +1,92 @@
+# Carbon
+
+[](https://packagist.org/packages/nesbot/carbon)
+[](https://packagist.org/packages/nesbot/carbon)
+[](https://travis-ci.org/briannesbitt/Carbon)
+[](https://styleci.io/repos/5724990)
+[](https://codecov.io/github/briannesbitt/Carbon?branch=master)
+[](https://php-eye.com/package/nesbot/carbon)
+
+A simple PHP API extension for DateTime. [http://carbon.nesbot.com](http://carbon.nesbot.com)
+
+```php
+use Carbon\Carbon;
+
+printf("Right now is %s", Carbon::now()->toDateTimeString());
+printf("Right now in Vancouver is %s", Carbon::now('America/Vancouver')); //implicit __toString()
+$tomorrow = Carbon::now()->addDay();
+$lastWeek = Carbon::now()->subWeek();
+$nextSummerOlympics = Carbon::createFromDate(2012)->addYears(4);
+
+$officialDate = Carbon::now()->toRfc2822String();
+
+$howOldAmI = Carbon::createFromDate(1975, 5, 21)->age;
+
+$noonTodayLondonTime = Carbon::createFromTime(12, 0, 0, 'Europe/London');
+
+$worldWillEnd = Carbon::createFromDate(2012, 12, 21, 'GMT');
+
+// Don't really want to die so mock now
+Carbon::setTestNow(Carbon::createFromDate(2000, 1, 1));
+
+// comparisons are always done in UTC
+if (Carbon::now()->gte($worldWillEnd)) {
+ die();
+}
+
+// Phew! Return to normal behaviour
+Carbon::setTestNow();
+
+if (Carbon::now()->isWeekend()) {
+ echo 'Party!';
+}
+echo Carbon::now()->subMinutes(2)->diffForHumans(); // '2 minutes ago'
+
+// ... but also does 'from now', 'after' and 'before'
+// rolling up to seconds, minutes, hours, days, months, years
+
+$daysSinceEpoch = Carbon::createFromTimestamp(0)->diffInDays();
+```
+
+## Installation
+
+### With Composer
+
+```
+$ composer require nesbot/carbon
+```
+
+```json
+{
+ "require": {
+ "nesbot/carbon": "~1.21"
+ }
+}
+```
+
+```php
+
+### Without Composer
+
+Why are you not using [composer](http://getcomposer.org/)? Download [Carbon.php](https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Carbon.php) from the repo and save the file into your project path somewhere.
+
+```php
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Carbon;
+
+use Carbon\Exceptions\InvalidDateException;
+use Closure;
+use DatePeriod;
+use DateTime;
+use DateTimeZone;
+use InvalidArgumentException;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * A simple API extension for DateTime
+ *
+ * @property int $year
+ * @property int $yearIso
+ * @property int $month
+ * @property int $day
+ * @property int $hour
+ * @property int $minute
+ * @property int $second
+ * @property int $timestamp seconds since the Unix Epoch
+ * @property \DateTimeZone $timezone the current timezone
+ * @property \DateTimeZone $tz alias of timezone
+ * @property-read int $micro
+ * @property-read int $dayOfWeek 0 (for Sunday) through 6 (for Saturday)
+ * @property-read int $dayOfYear 0 through 365
+ * @property-read int $weekOfMonth 1 through 5
+ * @property-read int $weekOfYear ISO-8601 week number of year, weeks starting on Monday
+ * @property-read int $daysInMonth number of days in the given month
+ * @property-read int $age does a diffInYears() with default parameters
+ * @property-read int $quarter the quarter of this instance, 1 - 4
+ * @property-read int $offset the timezone offset in seconds from UTC
+ * @property-read int $offsetHours the timezone offset in hours from UTC
+ * @property-read bool $dst daylight savings time indicator, true if DST, false otherwise
+ * @property-read bool $local checks if the timezone is local, true if local, false otherwise
+ * @property-read bool $utc checks if the timezone is UTC, true if UTC, false otherwise
+ * @property-read string $timezoneName
+ * @property-read string $tzName
+ */
+class Carbon extends DateTime
+{
+ /**
+ * The day constants.
+ */
+ const SUNDAY = 0;
+ const MONDAY = 1;
+ const TUESDAY = 2;
+ const WEDNESDAY = 3;
+ const THURSDAY = 4;
+ const FRIDAY = 5;
+ const SATURDAY = 6;
+
+ /**
+ * Names of days of the week.
+ *
+ * @var array
+ */
+ protected static $days = array(
+ self::SUNDAY => 'Sunday',
+ self::MONDAY => 'Monday',
+ self::TUESDAY => 'Tuesday',
+ self::WEDNESDAY => 'Wednesday',
+ self::THURSDAY => 'Thursday',
+ self::FRIDAY => 'Friday',
+ self::SATURDAY => 'Saturday',
+ );
+
+ /**
+ * Terms used to detect if a time passed is a relative date.
+ *
+ * This is here for testing purposes.
+ *
+ * @var array
+ */
+ protected static $relativeKeywords = array(
+ '+',
+ '-',
+ 'ago',
+ 'first',
+ 'last',
+ 'next',
+ 'this',
+ 'today',
+ 'tomorrow',
+ 'yesterday',
+ );
+
+ /**
+ * Number of X in Y.
+ */
+ const YEARS_PER_CENTURY = 100;
+ const YEARS_PER_DECADE = 10;
+ const MONTHS_PER_YEAR = 12;
+ const MONTHS_PER_QUARTER = 3;
+ const WEEKS_PER_YEAR = 52;
+ const DAYS_PER_WEEK = 7;
+ const HOURS_PER_DAY = 24;
+ const MINUTES_PER_HOUR = 60;
+ const SECONDS_PER_MINUTE = 60;
+
+ /**
+ * Default format to use for __toString method when type juggling occurs.
+ *
+ * @var string
+ */
+ const DEFAULT_TO_STRING_FORMAT = 'Y-m-d H:i:s';
+
+ /**
+ * Format to use for __toString method when type juggling occurs.
+ *
+ * @var string
+ */
+ protected static $toStringFormat = self::DEFAULT_TO_STRING_FORMAT;
+
+ /**
+ * First day of week.
+ *
+ * @var int
+ */
+ protected static $weekStartsAt = self::MONDAY;
+
+ /**
+ * Last day of week.
+ *
+ * @var int
+ */
+ protected static $weekEndsAt = self::SUNDAY;
+
+ /**
+ * Days of weekend.
+ *
+ * @var array
+ */
+ protected static $weekendDays = array(
+ self::SATURDAY,
+ self::SUNDAY,
+ );
+
+ /**
+ * A test Carbon instance to be returned when now instances are created.
+ *
+ * @var \Carbon\Carbon
+ */
+ protected static $testNow;
+
+ /**
+ * A translator to ... er ... translate stuff.
+ *
+ * @var \Symfony\Component\Translation\TranslatorInterface
+ */
+ protected static $translator;
+
+ /**
+ * The errors that can occur.
+ *
+ * @var array
+ */
+ protected static $lastErrors;
+
+ /**
+ * Will UTF8 encoding be used to print localized date/time ?
+ *
+ * @var bool
+ */
+ protected static $utf8 = false;
+
+ /*
+ * Indicates if months should be calculated with overflow.
+ *
+ * @var bool
+ */
+ protected static $monthsOverflow = true;
+
+ /**
+ * Indicates if months should be calculated with overflow.
+ *
+ * @param bool $monthsOverflow
+ *
+ * @return void
+ */
+ public static function useMonthsOverflow($monthsOverflow = true)
+ {
+ static::$monthsOverflow = $monthsOverflow;
+ }
+
+ /**
+ * Reset the month overflow behavior.
+ *
+ * @return void
+ */
+ public static function resetMonthsOverflow()
+ {
+ static::$monthsOverflow = true;
+ }
+
+ /**
+ * Get the month overflow behavior.
+ *
+ * @return bool
+ */
+ public static function shouldOverflowMonths()
+ {
+ return static::$monthsOverflow;
+ }
+
+ /**
+ * Creates a DateTimeZone from a string, DateTimeZone or integer offset.
+ *
+ * @param \DateTimeZone|string|int|null $object
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return \DateTimeZone
+ */
+ protected static function safeCreateDateTimeZone($object)
+ {
+ if ($object === null) {
+ // Don't return null... avoid Bug #52063 in PHP <5.3.6
+ return new DateTimeZone(date_default_timezone_get());
+ }
+
+ if ($object instanceof DateTimeZone) {
+ return $object;
+ }
+
+ if (is_numeric($object)) {
+ $tzName = timezone_name_from_abbr(null, $object * 3600, true);
+
+ if ($tzName === false) {
+ throw new InvalidArgumentException('Unknown or bad timezone ('.$object.')');
+ }
+
+ $object = $tzName;
+ }
+
+ $tz = @timezone_open((string) $object);
+
+ if ($tz === false) {
+ throw new InvalidArgumentException('Unknown or bad timezone ('.$object.')');
+ }
+
+ return $tz;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //////////////////////////// CONSTRUCTORS /////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Create a new Carbon instance.
+ *
+ * Please see the testing aids section (specifically static::setTestNow())
+ * for more on the possibility of this constructor returning a test instance.
+ *
+ * @param string|null $time
+ * @param \DateTimeZone|string|null $tz
+ */
+ public function __construct($time = null, $tz = null)
+ {
+ // If the class has a test now set and we are trying to create a now()
+ // instance then override as required
+ if (static::hasTestNow() && (empty($time) || $time === 'now' || static::hasRelativeKeywords($time))) {
+ $testInstance = clone static::getTestNow();
+ if (static::hasRelativeKeywords($time)) {
+ $testInstance->modify($time);
+ }
+
+ //shift the time according to the given time zone
+ if ($tz !== null && $tz !== static::getTestNow()->getTimezone()) {
+ $testInstance->setTimezone($tz);
+ } else {
+ $tz = $testInstance->getTimezone();
+ }
+
+ $time = $testInstance->toDateTimeString();
+ }
+
+ parent::__construct($time, static::safeCreateDateTimeZone($tz));
+ }
+
+ /**
+ * Create a Carbon instance from a DateTime one.
+ *
+ * @param \DateTime $dt
+ *
+ * @return static
+ */
+ public static function instance(DateTime $dt)
+ {
+ if ($dt instanceof static) {
+ return clone $dt;
+ }
+
+ return new static($dt->format('Y-m-d H:i:s.u'), $dt->getTimezone());
+ }
+
+ /**
+ * Create a carbon instance from a string.
+ *
+ * This is an alias for the constructor that allows better fluent syntax
+ * as it allows you to do Carbon::parse('Monday next week')->fn() rather
+ * than (new Carbon('Monday next week'))->fn().
+ *
+ * @param string|null $time
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @return static
+ */
+ public static function parse($time = null, $tz = null)
+ {
+ return new static($time, $tz);
+ }
+
+ /**
+ * Get a Carbon instance for the current date and time.
+ *
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @return static
+ */
+ public static function now($tz = null)
+ {
+ return new static(null, $tz);
+ }
+
+ /**
+ * Create a Carbon instance for today.
+ *
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @return static
+ */
+ public static function today($tz = null)
+ {
+ return static::now($tz)->startOfDay();
+ }
+
+ /**
+ * Create a Carbon instance for tomorrow.
+ *
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @return static
+ */
+ public static function tomorrow($tz = null)
+ {
+ return static::today($tz)->addDay();
+ }
+
+ /**
+ * Create a Carbon instance for yesterday.
+ *
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @return static
+ */
+ public static function yesterday($tz = null)
+ {
+ return static::today($tz)->subDay();
+ }
+
+ /**
+ * Create a Carbon instance for the greatest supported date.
+ *
+ * @return static
+ */
+ public static function maxValue()
+ {
+ if (PHP_INT_SIZE === 4) {
+ // 32 bit (and additionally Windows 64 bit)
+ return static::createFromTimestamp(PHP_INT_MAX);
+ }
+
+ // 64 bit
+ return static::create(9999, 12, 31, 23, 59, 59);
+ }
+
+ /**
+ * Create a Carbon instance for the lowest supported date.
+ *
+ * @return static
+ */
+ public static function minValue()
+ {
+ if (PHP_INT_SIZE === 4) {
+ // 32 bit (and additionally Windows 64 bit)
+ return static::createFromTimestamp(~PHP_INT_MAX);
+ }
+
+ // 64 bit
+ return static::create(1, 1, 1, 0, 0, 0);
+ }
+
+ /**
+ * Create a new Carbon instance from a specific date and time.
+ *
+ * If any of $year, $month or $day are set to null their now() values will
+ * be used.
+ *
+ * If $hour is null it will be set to its now() value and the default
+ * values for $minute and $second will be their now() values.
+ *
+ * If $hour is not null then the default values for $minute and $second
+ * will be 0.
+ *
+ * @param int|null $year
+ * @param int|null $month
+ * @param int|null $day
+ * @param int|null $hour
+ * @param int|null $minute
+ * @param int|null $second
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @return static
+ */
+ public static function create($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null)
+ {
+ $now = static::hasTestNow() ? static::getTestNow()->getTimestamp() : time();
+
+ $defaults = array_combine(array(
+ 'year',
+ 'month',
+ 'day',
+ 'hour',
+ 'minute',
+ 'second',
+ ), explode('-', date('Y-n-j-G-i-s', $now)));
+
+ $year = $year === null ? $defaults['year'] : $year;
+ $month = $month === null ? $defaults['month'] : $month;
+ $day = $day === null ? $defaults['day'] : $day;
+
+ if ($hour === null) {
+ $hour = $defaults['hour'];
+ $minute = $minute === null ? $defaults['minute'] : $minute;
+ $second = $second === null ? $defaults['second'] : $second;
+ } else {
+ $minute = $minute === null ? 0 : $minute;
+ $second = $second === null ? 0 : $second;
+ }
+
+ $fixYear = null;
+
+ if ($year < 0) {
+ $fixYear = $year;
+ $year = 0;
+ } elseif ($year > 9999) {
+ $fixYear = $year - 9999;
+ $year = 9999;
+ }
+
+ $instance = static::createFromFormat('Y-n-j G:i:s', sprintf('%s-%s-%s %s:%02s:%02s', $year, $month, $day, $hour, $minute, $second), $tz);
+
+ if ($fixYear !== null) {
+ $instance->addYears($fixYear);
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Create a new safe Carbon instance from a specific date and time.
+ *
+ * If any of $year, $month or $day are set to null their now() values will
+ * be used.
+ *
+ * If $hour is null it will be set to its now() value and the default
+ * values for $minute and $second will be their now() values.
+ *
+ * If $hour is not null then the default values for $minute and $second
+ * will be 0.
+ *
+ * If one of the set values is not valid, an \InvalidArgumentException
+ * will be thrown.
+ *
+ * @param int|null $year
+ * @param int|null $month
+ * @param int|null $day
+ * @param int|null $hour
+ * @param int|null $minute
+ * @param int|null $second
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @throws \Carbon\Exceptions\InvalidDateException
+ *
+ * @return static
+ */
+ public static function createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null)
+ {
+ $fields = array(
+ 'year' => array(0, 9999),
+ 'month' => array(0, 12),
+ 'day' => array(0, 31),
+ 'hour' => array(0, 24),
+ 'minute' => array(0, 59),
+ 'second' => array(0, 59),
+ );
+
+ foreach ($fields as $field => $range) {
+ if ($$field !== null && (!is_int($$field) || $$field < $range[0] || $$field > $range[1])) {
+ throw new InvalidDateException($field, $$field);
+ }
+ }
+
+ $instance = static::create($year, $month, 1, $hour, $minute, $second, $tz);
+
+ if ($day !== null && $day > $instance->daysInMonth) {
+ throw new InvalidDateException('day', $day);
+ }
+
+ return $instance->day($day);
+ }
+
+ /**
+ * Create a Carbon instance from just a date. The time portion is set to now.
+ *
+ * @param int|null $year
+ * @param int|null $month
+ * @param int|null $day
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @return static
+ */
+ public static function createFromDate($year = null, $month = null, $day = null, $tz = null)
+ {
+ return static::create($year, $month, $day, null, null, null, $tz);
+ }
+
+ /**
+ * Create a Carbon instance from just a time. The date portion is set to today.
+ *
+ * @param int|null $hour
+ * @param int|null $minute
+ * @param int|null $second
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @return static
+ */
+ public static function createFromTime($hour = null, $minute = null, $second = null, $tz = null)
+ {
+ return static::create(null, null, null, $hour, $minute, $second, $tz);
+ }
+
+ /**
+ * Create a Carbon instance from a specific format.
+ *
+ * @param string $format
+ * @param string $time
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return static
+ */
+ public static function createFromFormat($format, $time, $tz = null)
+ {
+ if ($tz !== null) {
+ $dt = parent::createFromFormat($format, $time, static::safeCreateDateTimeZone($tz));
+ } else {
+ $dt = parent::createFromFormat($format, $time);
+ }
+
+ static::setLastErrors($lastErrors = parent::getLastErrors());
+
+ if ($dt instanceof DateTime) {
+ return static::instance($dt);
+ }
+
+ throw new InvalidArgumentException(implode(PHP_EOL, $lastErrors['errors']));
+ }
+
+ /**
+ * Set last errors.
+ *
+ * @param array $lastErrors
+ *
+ * @return void
+ */
+ private static function setLastErrors(array $lastErrors)
+ {
+ static::$lastErrors = $lastErrors;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getLastErrors()
+ {
+ return static::$lastErrors;
+ }
+
+ /**
+ * Create a Carbon instance from a timestamp.
+ *
+ * @param int $timestamp
+ * @param \DateTimeZone|string|null $tz
+ *
+ * @return static
+ */
+ public static function createFromTimestamp($timestamp, $tz = null)
+ {
+ return static::now($tz)->setTimestamp($timestamp);
+ }
+
+ /**
+ * Create a Carbon instance from an UTC timestamp.
+ *
+ * @param int $timestamp
+ *
+ * @return static
+ */
+ public static function createFromTimestampUTC($timestamp)
+ {
+ return new static('@'.$timestamp);
+ }
+
+ /**
+ * Get a copy of the instance.
+ *
+ * @return static
+ */
+ public function copy()
+ {
+ return clone $this;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ ///////////////////////// GETTERS AND SETTERS /////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Get a part of the Carbon object
+ *
+ * @param string $name
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return string|int|\DateTimeZone
+ */
+ public function __get($name)
+ {
+ switch (true) {
+ case array_key_exists($name, $formats = array(
+ 'year' => 'Y',
+ 'yearIso' => 'o',
+ 'month' => 'n',
+ 'day' => 'j',
+ 'hour' => 'G',
+ 'minute' => 'i',
+ 'second' => 's',
+ 'micro' => 'u',
+ 'dayOfWeek' => 'w',
+ 'dayOfYear' => 'z',
+ 'weekOfYear' => 'W',
+ 'daysInMonth' => 't',
+ 'timestamp' => 'U',
+ )):
+ return (int) $this->format($formats[$name]);
+
+ case $name === 'weekOfMonth':
+ return (int) ceil($this->day / static::DAYS_PER_WEEK);
+
+ case $name === 'age':
+ return $this->diffInYears();
+
+ case $name === 'quarter':
+ return (int) ceil($this->month / static::MONTHS_PER_QUARTER);
+
+ case $name === 'offset':
+ return $this->getOffset();
+
+ case $name === 'offsetHours':
+ return $this->getOffset() / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR;
+
+ case $name === 'dst':
+ return $this->format('I') === '1';
+
+ case $name === 'local':
+ return $this->getOffset() === $this->copy()->setTimezone(date_default_timezone_get())->getOffset();
+
+ case $name === 'utc':
+ return $this->getOffset() === 0;
+
+ case $name === 'timezone' || $name === 'tz':
+ return $this->getTimezone();
+
+ case $name === 'timezoneName' || $name === 'tzName':
+ return $this->getTimezone()->getName();
+
+ default:
+ throw new InvalidArgumentException(sprintf("Unknown getter '%s'", $name));
+ }
+ }
+
+ /**
+ * Check if an attribute exists on the object
+ *
+ * @param string $name
+ *
+ * @return bool
+ */
+ public function __isset($name)
+ {
+ try {
+ $this->__get($name);
+ } catch (InvalidArgumentException $e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Set a part of the Carbon object
+ *
+ * @param string $name
+ * @param string|int|\DateTimeZone $value
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function __set($name, $value)
+ {
+ switch ($name) {
+ case 'year':
+ case 'month':
+ case 'day':
+ case 'hour':
+ case 'minute':
+ case 'second':
+ list($year, $month, $day, $hour, $minute, $second) = explode('-', $this->format('Y-n-j-G-i-s'));
+ $$name = $value;
+ $this->setDateTime($year, $month, $day, $hour, $minute, $second);
+ break;
+
+ case 'timestamp':
+ parent::setTimestamp($value);
+ break;
+
+ case 'timezone':
+ case 'tz':
+ $this->setTimezone($value);
+ break;
+
+ default:
+ throw new InvalidArgumentException(sprintf("Unknown setter '%s'", $name));
+ }
+ }
+
+ /**
+ * Set the instance's year
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function year($value)
+ {
+ $this->year = $value;
+
+ return $this;
+ }
+
+ /**
+ * Set the instance's month
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function month($value)
+ {
+ $this->month = $value;
+
+ return $this;
+ }
+
+ /**
+ * Set the instance's day
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function day($value)
+ {
+ $this->day = $value;
+
+ return $this;
+ }
+
+ /**
+ * Set the instance's hour
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function hour($value)
+ {
+ $this->hour = $value;
+
+ return $this;
+ }
+
+ /**
+ * Set the instance's minute
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function minute($value)
+ {
+ $this->minute = $value;
+
+ return $this;
+ }
+
+ /**
+ * Set the instance's second
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function second($value)
+ {
+ $this->second = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets the current date of the DateTime object to a different date.
+ * Calls modify as a workaround for a php bug
+ *
+ * @param int $year
+ * @param int $month
+ * @param int $day
+ *
+ * @return static
+ *
+ * @see https://github.com/briannesbitt/Carbon/issues/539
+ * @see https://bugs.php.net/bug.php?id=63863
+ */
+ public function setDate($year, $month, $day)
+ {
+ $this->modify('+0 day');
+
+ return parent::setDate($year, $month, $day);
+ }
+
+ /**
+ * Set the date and time all together
+ *
+ * @param int $year
+ * @param int $month
+ * @param int $day
+ * @param int $hour
+ * @param int $minute
+ * @param int $second
+ *
+ * @return static
+ */
+ public function setDateTime($year, $month, $day, $hour, $minute, $second = 0)
+ {
+ return $this->setDate($year, $month, $day)->setTime($hour, $minute, $second);
+ }
+
+ /**
+ * Set the time by time string
+ *
+ * @param string $time
+ *
+ * @return static
+ */
+ public function setTimeFromTimeString($time)
+ {
+ $time = explode(':', $time);
+
+ $hour = $time[0];
+ $minute = isset($time[1]) ? $time[1] : 0;
+ $second = isset($time[2]) ? $time[2] : 0;
+
+ return $this->setTime($hour, $minute, $second);
+ }
+
+ /**
+ * Set the instance's timestamp
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function timestamp($value)
+ {
+ return $this->setTimestamp($value);
+ }
+
+ /**
+ * Alias for setTimezone()
+ *
+ * @param \DateTimeZone|string $value
+ *
+ * @return static
+ */
+ public function timezone($value)
+ {
+ return $this->setTimezone($value);
+ }
+
+ /**
+ * Alias for setTimezone()
+ *
+ * @param \DateTimeZone|string $value
+ *
+ * @return static
+ */
+ public function tz($value)
+ {
+ return $this->setTimezone($value);
+ }
+
+ /**
+ * Set the instance's timezone from a string or object
+ *
+ * @param \DateTimeZone|string $value
+ *
+ * @return static
+ */
+ public function setTimezone($value)
+ {
+ return parent::setTimezone(static::safeCreateDateTimeZone($value));
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////// WEEK SPECIAL DAYS /////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Get the first day of week
+ *
+ * @return int
+ */
+ public static function getWeekStartsAt()
+ {
+ return static::$weekStartsAt;
+ }
+
+ /**
+ * Set the first day of week
+ *
+ * @param int
+ */
+ public static function setWeekStartsAt($day)
+ {
+ static::$weekStartsAt = $day;
+ }
+
+ /**
+ * Get the last day of week
+ *
+ * @return int
+ */
+ public static function getWeekEndsAt()
+ {
+ return static::$weekEndsAt;
+ }
+
+ /**
+ * Set the last day of week
+ *
+ * @param int
+ */
+ public static function setWeekEndsAt($day)
+ {
+ static::$weekEndsAt = $day;
+ }
+
+ /**
+ * Get weekend days
+ *
+ * @return array
+ */
+ public static function getWeekendDays()
+ {
+ return static::$weekendDays;
+ }
+
+ /**
+ * Set weekend days
+ *
+ * @param array
+ */
+ public static function setWeekendDays($days)
+ {
+ static::$weekendDays = $days;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ ///////////////////////// TESTING AIDS ////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Set a Carbon instance (real or mock) to be returned when a "now"
+ * instance is created. The provided instance will be returned
+ * specifically under the following conditions:
+ * - A call to the static now() method, ex. Carbon::now()
+ * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null)
+ * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now')
+ * - When a string containing the desired time is passed to Carbon::parse().
+ *
+ * Note the timezone parameter was left out of the examples above and
+ * has no affect as the mock value will be returned regardless of its value.
+ *
+ * To clear the test instance call this method using the default
+ * parameter of null.
+ *
+ * @param \Carbon\Carbon|string|null $testNow
+ */
+ public static function setTestNow($testNow = null)
+ {
+ static::$testNow = is_string($testNow) ? static::parse($testNow) : $testNow;
+ }
+
+ /**
+ * Get the Carbon instance (real or mock) to be returned when a "now"
+ * instance is created.
+ *
+ * @return static the current instance used for testing
+ */
+ public static function getTestNow()
+ {
+ return static::$testNow;
+ }
+
+ /**
+ * Determine if there is a valid test instance set. A valid test instance
+ * is anything that is not null.
+ *
+ * @return bool true if there is a test instance, otherwise false
+ */
+ public static function hasTestNow()
+ {
+ return static::getTestNow() !== null;
+ }
+
+ /**
+ * Determine if there is a relative keyword in the time string, this is to
+ * create dates relative to now for test instances. e.g.: next tuesday
+ *
+ * @param string $time
+ *
+ * @return bool true if there is a keyword, otherwise false
+ */
+ public static function hasRelativeKeywords($time)
+ {
+ // skip common format with a '-' in it
+ if (preg_match('/\d{4}-\d{1,2}-\d{1,2}/', $time) !== 1) {
+ foreach (static::$relativeKeywords as $keyword) {
+ if (stripos($time, $keyword) !== false) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////// LOCALIZATION //////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Initialize the translator instance if necessary.
+ *
+ * @return \Symfony\Component\Translation\TranslatorInterface
+ */
+ protected static function translator()
+ {
+ if (static::$translator === null) {
+ static::$translator = new Translator('en');
+ static::$translator->addLoader('array', new ArrayLoader());
+ static::setLocale('en');
+ }
+
+ return static::$translator;
+ }
+
+ /**
+ * Get the translator instance in use
+ *
+ * @return \Symfony\Component\Translation\TranslatorInterface
+ */
+ public static function getTranslator()
+ {
+ return static::translator();
+ }
+
+ /**
+ * Set the translator instance to use
+ *
+ * @param \Symfony\Component\Translation\TranslatorInterface $translator
+ */
+ public static function setTranslator(TranslatorInterface $translator)
+ {
+ static::$translator = $translator;
+ }
+
+ /**
+ * Get the current translator locale
+ *
+ * @return string
+ */
+ public static function getLocale()
+ {
+ return static::translator()->getLocale();
+ }
+
+ /**
+ * Set the current translator locale and indicate if the source locale file exists
+ *
+ * @param string $locale
+ *
+ * @return bool
+ */
+ public static function setLocale($locale)
+ {
+ $locale = preg_replace_callback('/\b([a-z]{2})[-_](?:([a-z]{4})[-_])?([a-z]{2})\b/', function ($matches) {
+ return $matches[1].'_'.(!empty($matches[2]) ? ucfirst($matches[2]).'_' : '').strtoupper($matches[3]);
+ }, strtolower($locale));
+
+ if (file_exists($filename = __DIR__.'/Lang/'.$locale.'.php')) {
+ static::translator()->setLocale($locale);
+ // Ensure the locale has been loaded.
+ static::translator()->addResource('array', require $filename, $locale);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////// STRING FORMATTING /////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Set if UTF8 will be used for localized date/time
+ *
+ * @param bool $utf8
+ */
+ public static function setUtf8($utf8)
+ {
+ static::$utf8 = $utf8;
+ }
+
+ /**
+ * Format the instance with the current locale. You can set the current
+ * locale using setlocale() http://php.net/setlocale.
+ *
+ * @param string $format
+ *
+ * @return string
+ */
+ public function formatLocalized($format)
+ {
+ // Check for Windows to find and replace the %e
+ // modifier correctly
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+ $format = preg_replace('#(?format(static::$toStringFormat);
+ }
+
+ /**
+ * Format the instance as date
+ *
+ * @return string
+ */
+ public function toDateString()
+ {
+ return $this->format('Y-m-d');
+ }
+
+ /**
+ * Format the instance as a readable date
+ *
+ * @return string
+ */
+ public function toFormattedDateString()
+ {
+ return $this->format('M j, Y');
+ }
+
+ /**
+ * Format the instance as time
+ *
+ * @return string
+ */
+ public function toTimeString()
+ {
+ return $this->format('H:i:s');
+ }
+
+ /**
+ * Format the instance as date and time
+ *
+ * @return string
+ */
+ public function toDateTimeString()
+ {
+ return $this->format('Y-m-d H:i:s');
+ }
+
+ /**
+ * Format the instance with day, date and time
+ *
+ * @return string
+ */
+ public function toDayDateTimeString()
+ {
+ return $this->format('D, M j, Y g:i A');
+ }
+
+ /**
+ * Format the instance as ATOM
+ *
+ * @return string
+ */
+ public function toAtomString()
+ {
+ return $this->format(static::ATOM);
+ }
+
+ /**
+ * Format the instance as COOKIE
+ *
+ * @return string
+ */
+ public function toCookieString()
+ {
+ return $this->format(static::COOKIE);
+ }
+
+ /**
+ * Format the instance as ISO8601
+ *
+ * @return string
+ */
+ public function toIso8601String()
+ {
+ return $this->toAtomString();
+ }
+
+ /**
+ * Format the instance as RFC822
+ *
+ * @return string
+ */
+ public function toRfc822String()
+ {
+ return $this->format(static::RFC822);
+ }
+
+ /**
+ * Format the instance as RFC850
+ *
+ * @return string
+ */
+ public function toRfc850String()
+ {
+ return $this->format(static::RFC850);
+ }
+
+ /**
+ * Format the instance as RFC1036
+ *
+ * @return string
+ */
+ public function toRfc1036String()
+ {
+ return $this->format(static::RFC1036);
+ }
+
+ /**
+ * Format the instance as RFC1123
+ *
+ * @return string
+ */
+ public function toRfc1123String()
+ {
+ return $this->format(static::RFC1123);
+ }
+
+ /**
+ * Format the instance as RFC2822
+ *
+ * @return string
+ */
+ public function toRfc2822String()
+ {
+ return $this->format(static::RFC2822);
+ }
+
+ /**
+ * Format the instance as RFC3339
+ *
+ * @return string
+ */
+ public function toRfc3339String()
+ {
+ return $this->format(static::RFC3339);
+ }
+
+ /**
+ * Format the instance as RSS
+ *
+ * @return string
+ */
+ public function toRssString()
+ {
+ return $this->format(static::RSS);
+ }
+
+ /**
+ * Format the instance as W3C
+ *
+ * @return string
+ */
+ public function toW3cString()
+ {
+ return $this->format(static::W3C);
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ ////////////////////////// COMPARISONS ////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Determines if the instance is equal to another
+ *
+ * @param Carbon $dt
+ *
+ * @return bool
+ */
+ public function eq(Carbon $dt)
+ {
+ return $this == $dt;
+ }
+
+ /**
+ * Determines if the instance is equal to another
+ *
+ * @param Carbon $dt
+ *
+ * @see eq()
+ *
+ * @return bool
+ */
+ public function equalTo(Carbon $dt)
+ {
+ return $this->eq($dt);
+ }
+
+ /**
+ * Determines if the instance is not equal to another
+ *
+ * @param Carbon $dt
+ *
+ * @return bool
+ */
+ public function ne(Carbon $dt)
+ {
+ return !$this->eq($dt);
+ }
+
+ /**
+ * Determines if the instance is not equal to another
+ *
+ * @param Carbon $dt
+ *
+ * @see ne()
+ *
+ * @return bool
+ */
+ public function notEqualTo(Carbon $dt)
+ {
+ return $this->ne($dt);
+ }
+
+ /**
+ * Determines if the instance is greater (after) than another
+ *
+ * @param Carbon $dt
+ *
+ * @return bool
+ */
+ public function gt(Carbon $dt)
+ {
+ return $this > $dt;
+ }
+
+ /**
+ * Determines if the instance is greater (after) than another
+ *
+ * @param Carbon $dt
+ *
+ * @see gt()
+ *
+ * @return bool
+ */
+ public function greaterThan(Carbon $dt)
+ {
+ return $this->gt($dt);
+ }
+
+ /**
+ * Determines if the instance is greater (after) than or equal to another
+ *
+ * @param Carbon $dt
+ *
+ * @return bool
+ */
+ public function gte(Carbon $dt)
+ {
+ return $this >= $dt;
+ }
+
+ /**
+ * Determines if the instance is greater (after) than or equal to another
+ *
+ * @param Carbon $dt
+ *
+ * @see gte()
+ *
+ * @return bool
+ */
+ public function greaterThanOrEqualTo(Carbon $dt)
+ {
+ return $this->gte($dt);
+ }
+
+ /**
+ * Determines if the instance is less (before) than another
+ *
+ * @param Carbon $dt
+ *
+ * @return bool
+ */
+ public function lt(Carbon $dt)
+ {
+ return $this < $dt;
+ }
+
+ /**
+ * Determines if the instance is less (before) than another
+ *
+ * @param Carbon $dt
+ *
+ * @see lt()
+ *
+ * @return bool
+ */
+ public function lessThan(Carbon $dt)
+ {
+ return $this->lt($dt);
+ }
+
+ /**
+ * Determines if the instance is less (before) or equal to another
+ *
+ * @param Carbon $dt
+ *
+ * @return bool
+ */
+ public function lte(Carbon $dt)
+ {
+ return $this <= $dt;
+ }
+
+ /**
+ * Determines if the instance is less (before) or equal to another
+ *
+ * @param Carbon $dt
+ *
+ * @see lte()
+ *
+ * @return bool
+ */
+ public function lessThanOrEqualTo(Carbon $dt)
+ {
+ return $this->lte($dt);
+ }
+
+ /**
+ * Determines if the instance is between two others
+ *
+ * @param Carbon $dt1
+ * @param Carbon $dt2
+ * @param bool $equal Indicates if a > and < comparison should be used or <= or >=
+ *
+ * @return bool
+ */
+ public function between(Carbon $dt1, Carbon $dt2, $equal = true)
+ {
+ if ($dt1->gt($dt2)) {
+ $temp = $dt1;
+ $dt1 = $dt2;
+ $dt2 = $temp;
+ }
+
+ if ($equal) {
+ return $this->gte($dt1) && $this->lte($dt2);
+ }
+
+ return $this->gt($dt1) && $this->lt($dt2);
+ }
+
+ /**
+ * Get the closest date from the instance.
+ *
+ * @param Carbon $dt1
+ * @param Carbon $dt2
+ *
+ * @return static
+ */
+ public function closest(Carbon $dt1, Carbon $dt2)
+ {
+ return $this->diffInSeconds($dt1) < $this->diffInSeconds($dt2) ? $dt1 : $dt2;
+ }
+
+ /**
+ * Get the farthest date from the instance.
+ *
+ * @param Carbon $dt1
+ * @param Carbon $dt2
+ *
+ * @return static
+ */
+ public function farthest(Carbon $dt1, Carbon $dt2)
+ {
+ return $this->diffInSeconds($dt1) > $this->diffInSeconds($dt2) ? $dt1 : $dt2;
+ }
+
+ /**
+ * Get the minimum instance between a given instance (default now) and the current instance.
+ *
+ * @param \Carbon\Carbon|null $dt
+ *
+ * @return static
+ */
+ public function min(Carbon $dt = null)
+ {
+ $dt = $dt ?: static::now($this->getTimezone());
+
+ return $this->lt($dt) ? $this : $dt;
+ }
+
+ /**
+ * Get the minimum instance between a given instance (default now) and the current instance.
+ *
+ * @param \Carbon\Carbon|null $dt
+ *
+ * @see min()
+ *
+ * @return static
+ */
+ public function minimum(Carbon $dt = null)
+ {
+ return $this->min($dt);
+ }
+
+ /**
+ * Get the maximum instance between a given instance (default now) and the current instance.
+ *
+ * @param \Carbon\Carbon|null $dt
+ *
+ * @return static
+ */
+ public function max(Carbon $dt = null)
+ {
+ $dt = $dt ?: static::now($this->getTimezone());
+
+ return $this->gt($dt) ? $this : $dt;
+ }
+
+ /**
+ * Get the maximum instance between a given instance (default now) and the current instance.
+ *
+ * @param \Carbon\Carbon|null $dt
+ *
+ * @see max()
+ *
+ * @return static
+ */
+ public function maximum(Carbon $dt = null)
+ {
+ return $this->max($dt);
+ }
+
+ /**
+ * Determines if the instance is a weekday
+ *
+ * @return bool
+ */
+ public function isWeekday()
+ {
+ return !$this->isWeekend();
+ }
+
+ /**
+ * Determines if the instance is a weekend day
+ *
+ * @return bool
+ */
+ public function isWeekend()
+ {
+ return in_array($this->dayOfWeek, static::$weekendDays);
+ }
+
+ /**
+ * Determines if the instance is yesterday
+ *
+ * @return bool
+ */
+ public function isYesterday()
+ {
+ return $this->toDateString() === static::yesterday($this->getTimezone())->toDateString();
+ }
+
+ /**
+ * Determines if the instance is today
+ *
+ * @return bool
+ */
+ public function isToday()
+ {
+ return $this->toDateString() === static::now($this->getTimezone())->toDateString();
+ }
+
+ /**
+ * Determines if the instance is tomorrow
+ *
+ * @return bool
+ */
+ public function isTomorrow()
+ {
+ return $this->toDateString() === static::tomorrow($this->getTimezone())->toDateString();
+ }
+
+ /**
+ * Determines if the instance is within the next week
+ *
+ * @return bool
+ */
+ public function isNextWeek()
+ {
+ return $this->weekOfYear === static::now($this->getTimezone())->addWeek()->weekOfYear;
+ }
+
+ /**
+ * Determines if the instance is within the last week
+ *
+ * @return bool
+ */
+ public function isLastWeek()
+ {
+ return $this->weekOfYear === static::now($this->getTimezone())->subWeek()->weekOfYear;
+ }
+
+ /**
+ * Determines if the instance is within the next month
+ *
+ * @return bool
+ */
+ public function isNextMonth()
+ {
+ return $this->month === static::now($this->getTimezone())->addMonthNoOverflow()->month;
+ }
+
+ /**
+ * Determines if the instance is within the last month
+ *
+ * @return bool
+ */
+ public function isLastMonth()
+ {
+ return $this->month === static::now($this->getTimezone())->subMonthNoOverflow()->month;
+ }
+
+ /**
+ * Determines if the instance is within next year
+ *
+ * @return bool
+ */
+ public function isNextYear()
+ {
+ return $this->year === static::now($this->getTimezone())->addYear()->year;
+ }
+
+ /**
+ * Determines if the instance is within the previous year
+ *
+ * @return bool
+ */
+ public function isLastYear()
+ {
+ return $this->year === static::now($this->getTimezone())->subYear()->year;
+ }
+
+ /**
+ * Determines if the instance is in the future, ie. greater (after) than now
+ *
+ * @return bool
+ */
+ public function isFuture()
+ {
+ return $this->gt(static::now($this->getTimezone()));
+ }
+
+ /**
+ * Determines if the instance is in the past, ie. less (before) than now
+ *
+ * @return bool
+ */
+ public function isPast()
+ {
+ return $this->lt(static::now($this->getTimezone()));
+ }
+
+ /**
+ * Determines if the instance is a leap year
+ *
+ * @return bool
+ */
+ public function isLeapYear()
+ {
+ return $this->format('L') === '1';
+ }
+
+ /**
+ * Determines if the instance is a long year
+ *
+ * @see https://en.wikipedia.org/wiki/ISO_8601#Week_dates
+ *
+ * @return bool
+ */
+ public function isLongYear()
+ {
+ return static::create($this->year, 12, 28, 0, 0, 0, $this->tz)->weekOfYear === 53;
+ }
+
+ /*
+ * Compares the formatted values of the two dates.
+ *
+ * @param string $format The date formats to compare.
+ * @param \Carbon\Carbon|null $dt The instance to compare with or null to use current day.
+ *
+ * @return bool
+ */
+ public function isSameAs($format, Carbon $dt = null)
+ {
+ $dt = $dt ?: static::now($this->tz);
+
+ return $this->format($format) === $dt->format($format);
+ }
+
+ /**
+ * Determines if the instance is in the current year
+ *
+ * @return bool
+ */
+ public function isCurrentYear()
+ {
+ return $this->isSameYear();
+ }
+
+ /**
+ * Checks if the passed in date is in the same year as the instance year.
+ *
+ * @param \Carbon\Carbon|null $dt The instance to compare with or null to use current day.
+ *
+ * @return bool
+ */
+ public function isSameYear(Carbon $dt = null)
+ {
+ return $this->isSameAs('Y', $dt);
+ }
+
+ /**
+ * Determines if the instance is in the current month
+ *
+ * @return bool
+ */
+ public function isCurrentMonth()
+ {
+ return $this->isSameMonth();
+ }
+
+ /**
+ * Checks if the passed in date is in the same month as the instance month (and year if needed).
+ *
+ * @param \Carbon\Carbon|null $dt The instance to compare with or null to use current day.
+ * @param bool $ofSameYear Check if it is the same month in the same year.
+ *
+ * @return bool
+ */
+ public function isSameMonth(Carbon $dt = null, $ofSameYear = false)
+ {
+ $format = $ofSameYear ? 'Y-m' : 'm';
+
+ return $this->isSameAs($format, $dt);
+ }
+
+ /**
+ * Checks if the passed in date is the same day as the instance current day.
+ *
+ * @param \Carbon\Carbon $dt
+ *
+ * @return bool
+ */
+ public function isSameDay(Carbon $dt)
+ {
+ return $this->toDateString() === $dt->toDateString();
+ }
+
+ /**
+ * Checks if this day is a Sunday.
+ *
+ * @return bool
+ */
+ public function isSunday()
+ {
+ return $this->dayOfWeek === static::SUNDAY;
+ }
+
+ /**
+ * Checks if this day is a Monday.
+ *
+ * @return bool
+ */
+ public function isMonday()
+ {
+ return $this->dayOfWeek === static::MONDAY;
+ }
+
+ /**
+ * Checks if this day is a Tuesday.
+ *
+ * @return bool
+ */
+ public function isTuesday()
+ {
+ return $this->dayOfWeek === static::TUESDAY;
+ }
+
+ /**
+ * Checks if this day is a Wednesday.
+ *
+ * @return bool
+ */
+ public function isWednesday()
+ {
+ return $this->dayOfWeek === static::WEDNESDAY;
+ }
+
+ /**
+ * Checks if this day is a Thursday.
+ *
+ * @return bool
+ */
+ public function isThursday()
+ {
+ return $this->dayOfWeek === static::THURSDAY;
+ }
+
+ /**
+ * Checks if this day is a Friday.
+ *
+ * @return bool
+ */
+ public function isFriday()
+ {
+ return $this->dayOfWeek === static::FRIDAY;
+ }
+
+ /**
+ * Checks if this day is a Saturday.
+ *
+ * @return bool
+ */
+ public function isSaturday()
+ {
+ return $this->dayOfWeek === static::SATURDAY;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ /////////////////// ADDITIONS AND SUBTRACTIONS ////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Add years to the instance. Positive $value travel forward while
+ * negative $value travel into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addYears($value)
+ {
+ return $this->modify((int) $value.' year');
+ }
+
+ /**
+ * Add a year to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addYear($value = 1)
+ {
+ return $this->addYears($value);
+ }
+
+ /**
+ * Remove a year from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subYear($value = 1)
+ {
+ return $this->subYears($value);
+ }
+
+ /**
+ * Remove years from the instance.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subYears($value)
+ {
+ return $this->addYears(-1 * $value);
+ }
+
+ /**
+ * Add quarters to the instance. Positive $value travels forward while
+ * negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addQuarters($value)
+ {
+ return $this->addMonths(static::MONTHS_PER_QUARTER * $value);
+ }
+
+ /**
+ * Add a quarter to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addQuarter($value = 1)
+ {
+ return $this->addQuarters($value);
+ }
+
+ /**
+ * Remove a quarter from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subQuarter($value = 1)
+ {
+ return $this->subQuarters($value);
+ }
+
+ /**
+ * Remove quarters from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subQuarters($value)
+ {
+ return $this->addQuarters(-1 * $value);
+ }
+
+ /**
+ * Add centuries to the instance. Positive $value travels forward while
+ * negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addCenturies($value)
+ {
+ return $this->addYears(static::YEARS_PER_CENTURY * $value);
+ }
+
+ /**
+ * Add a century to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addCentury($value = 1)
+ {
+ return $this->addCenturies($value);
+ }
+
+ /**
+ * Remove a century from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subCentury($value = 1)
+ {
+ return $this->subCenturies($value);
+ }
+
+ /**
+ * Remove centuries from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subCenturies($value)
+ {
+ return $this->addCenturies(-1 * $value);
+ }
+
+ /**
+ * Add months to the instance. Positive $value travels forward while
+ * negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addMonths($value)
+ {
+ if (static::shouldOverflowMonths()) {
+ return $this->addMonthsWithOverflow($value);
+ }
+
+ return $this->addMonthsNoOverflow($value);
+ }
+
+ /**
+ * Add a month to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addMonth($value = 1)
+ {
+ return $this->addMonths($value);
+ }
+
+ /**
+ * Remove a month from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subMonth($value = 1)
+ {
+ return $this->subMonths($value);
+ }
+
+ /**
+ * Remove months from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subMonths($value)
+ {
+ return $this->addMonths(-1 * $value);
+ }
+
+ /**
+ * Add months to the instance. Positive $value travels forward while
+ * negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addMonthsWithOverflow($value)
+ {
+ return $this->modify((int) $value.' month');
+ }
+
+ /**
+ * Add a month to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addMonthWithOverflow($value = 1)
+ {
+ return $this->addMonthsWithOverflow($value);
+ }
+
+ /**
+ * Remove a month from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subMonthWithOverflow($value = 1)
+ {
+ return $this->subMonthsWithOverflow($value);
+ }
+
+ /**
+ * Remove months from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subMonthsWithOverflow($value)
+ {
+ return $this->addMonthsWithOverflow(-1 * $value);
+ }
+
+ /**
+ * Add months without overflowing to the instance. Positive $value
+ * travels forward while negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addMonthsNoOverflow($value)
+ {
+ $day = $this->day;
+
+ $this->modify((int) $value.' month');
+
+ if ($day !== $this->day) {
+ $this->modify('last day of previous month');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a month with no overflow to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addMonthNoOverflow($value = 1)
+ {
+ return $this->addMonthsNoOverflow($value);
+ }
+
+ /**
+ * Remove a month with no overflow from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subMonthNoOverflow($value = 1)
+ {
+ return $this->subMonthsNoOverflow($value);
+ }
+
+ /**
+ * Remove months with no overflow from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subMonthsNoOverflow($value)
+ {
+ return $this->addMonthsNoOverflow(-1 * $value);
+ }
+
+ /**
+ * Add days to the instance. Positive $value travels forward while
+ * negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addDays($value)
+ {
+ return $this->modify((int) $value.' day');
+ }
+
+ /**
+ * Add a day to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addDay($value = 1)
+ {
+ return $this->addDays($value);
+ }
+
+ /**
+ * Remove a day from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subDay($value = 1)
+ {
+ return $this->subDays($value);
+ }
+
+ /**
+ * Remove days from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subDays($value)
+ {
+ return $this->addDays(-1 * $value);
+ }
+
+ /**
+ * Add weekdays to the instance. Positive $value travels forward while
+ * negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addWeekdays($value)
+ {
+ // fix for https://bugs.php.net/bug.php?id=54909
+ $t = $this->toTimeString();
+ $this->modify((int) $value.' weekday');
+
+ return $this->setTimeFromTimeString($t);
+ }
+
+ /**
+ * Add a weekday to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addWeekday($value = 1)
+ {
+ return $this->addWeekdays($value);
+ }
+
+ /**
+ * Remove a weekday from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subWeekday($value = 1)
+ {
+ return $this->subWeekdays($value);
+ }
+
+ /**
+ * Remove weekdays from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subWeekdays($value)
+ {
+ return $this->addWeekdays(-1 * $value);
+ }
+
+ /**
+ * Add weeks to the instance. Positive $value travels forward while
+ * negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addWeeks($value)
+ {
+ return $this->modify((int) $value.' week');
+ }
+
+ /**
+ * Add a week to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addWeek($value = 1)
+ {
+ return $this->addWeeks($value);
+ }
+
+ /**
+ * Remove a week from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subWeek($value = 1)
+ {
+ return $this->subWeeks($value);
+ }
+
+ /**
+ * Remove weeks to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subWeeks($value)
+ {
+ return $this->addWeeks(-1 * $value);
+ }
+
+ /**
+ * Add hours to the instance. Positive $value travels forward while
+ * negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addHours($value)
+ {
+ return $this->modify((int) $value.' hour');
+ }
+
+ /**
+ * Add an hour to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addHour($value = 1)
+ {
+ return $this->addHours($value);
+ }
+
+ /**
+ * Remove an hour from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subHour($value = 1)
+ {
+ return $this->subHours($value);
+ }
+
+ /**
+ * Remove hours from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subHours($value)
+ {
+ return $this->addHours(-1 * $value);
+ }
+
+ /**
+ * Add minutes to the instance. Positive $value travels forward while
+ * negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addMinutes($value)
+ {
+ return $this->modify((int) $value.' minute');
+ }
+
+ /**
+ * Add a minute to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addMinute($value = 1)
+ {
+ return $this->addMinutes($value);
+ }
+
+ /**
+ * Remove a minute from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subMinute($value = 1)
+ {
+ return $this->subMinutes($value);
+ }
+
+ /**
+ * Remove minutes from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subMinutes($value)
+ {
+ return $this->addMinutes(-1 * $value);
+ }
+
+ /**
+ * Add seconds to the instance. Positive $value travels forward while
+ * negative $value travels into the past.
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addSeconds($value)
+ {
+ return $this->modify((int) $value.' second');
+ }
+
+ /**
+ * Add a second to the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function addSecond($value = 1)
+ {
+ return $this->addSeconds($value);
+ }
+
+ /**
+ * Remove a second from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subSecond($value = 1)
+ {
+ return $this->subSeconds($value);
+ }
+
+ /**
+ * Remove seconds from the instance
+ *
+ * @param int $value
+ *
+ * @return static
+ */
+ public function subSeconds($value)
+ {
+ return $this->addSeconds(-1 * $value);
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////// DIFFERENCES ///////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Get the difference in years
+ *
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInYears(Carbon $dt = null, $abs = true)
+ {
+ $dt = $dt ?: static::now($this->getTimezone());
+
+ return (int) $this->diff($dt, $abs)->format('%r%y');
+ }
+
+ /**
+ * Get the difference in months
+ *
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInMonths(Carbon $dt = null, $abs = true)
+ {
+ $dt = $dt ?: static::now($this->getTimezone());
+
+ return $this->diffInYears($dt, $abs) * static::MONTHS_PER_YEAR + (int) $this->diff($dt, $abs)->format('%r%m');
+ }
+
+ /**
+ * Get the difference in weeks
+ *
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInWeeks(Carbon $dt = null, $abs = true)
+ {
+ return (int) ($this->diffInDays($dt, $abs) / static::DAYS_PER_WEEK);
+ }
+
+ /**
+ * Get the difference in days
+ *
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInDays(Carbon $dt = null, $abs = true)
+ {
+ $dt = $dt ?: static::now($this->getTimezone());
+
+ return (int) $this->diff($dt, $abs)->format('%r%a');
+ }
+
+ /**
+ * Get the difference in days using a filter closure
+ *
+ * @param Closure $callback
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInDaysFiltered(Closure $callback, Carbon $dt = null, $abs = true)
+ {
+ return $this->diffFiltered(CarbonInterval::day(), $callback, $dt, $abs);
+ }
+
+ /**
+ * Get the difference in hours using a filter closure
+ *
+ * @param Closure $callback
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInHoursFiltered(Closure $callback, Carbon $dt = null, $abs = true)
+ {
+ return $this->diffFiltered(CarbonInterval::hour(), $callback, $dt, $abs);
+ }
+
+ /**
+ * Get the difference by the given interval using a filter closure
+ *
+ * @param CarbonInterval $ci An interval to traverse by
+ * @param Closure $callback
+ * @param Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffFiltered(CarbonInterval $ci, Closure $callback, Carbon $dt = null, $abs = true)
+ {
+ $start = $this;
+ $end = $dt ?: static::now($this->getTimezone());
+ $inverse = false;
+
+ if ($end < $start) {
+ $start = $end;
+ $end = $this;
+ $inverse = true;
+ }
+
+ $period = new DatePeriod($start, $ci, $end);
+ $vals = array_filter(iterator_to_array($period), function (DateTime $date) use ($callback) {
+ return call_user_func($callback, Carbon::instance($date));
+ });
+
+ $diff = count($vals);
+
+ return $inverse && !$abs ? -$diff : $diff;
+ }
+
+ /**
+ * Get the difference in weekdays
+ *
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInWeekdays(Carbon $dt = null, $abs = true)
+ {
+ return $this->diffInDaysFiltered(function (Carbon $date) {
+ return $date->isWeekday();
+ }, $dt, $abs);
+ }
+
+ /**
+ * Get the difference in weekend days using a filter
+ *
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInWeekendDays(Carbon $dt = null, $abs = true)
+ {
+ return $this->diffInDaysFiltered(function (Carbon $date) {
+ return $date->isWeekend();
+ }, $dt, $abs);
+ }
+
+ /**
+ * Get the difference in hours
+ *
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInHours(Carbon $dt = null, $abs = true)
+ {
+ return (int) ($this->diffInSeconds($dt, $abs) / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR);
+ }
+
+ /**
+ * Get the difference in minutes
+ *
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInMinutes(Carbon $dt = null, $abs = true)
+ {
+ return (int) ($this->diffInSeconds($dt, $abs) / static::SECONDS_PER_MINUTE);
+ }
+
+ /**
+ * Get the difference in seconds
+ *
+ * @param \Carbon\Carbon|null $dt
+ * @param bool $abs Get the absolute of the difference
+ *
+ * @return int
+ */
+ public function diffInSeconds(Carbon $dt = null, $abs = true)
+ {
+ $dt = $dt ?: static::now($this->getTimezone());
+ $value = $dt->getTimestamp() - $this->getTimestamp();
+
+ return $abs ? abs($value) : $value;
+ }
+
+ /**
+ * The number of seconds since midnight.
+ *
+ * @return int
+ */
+ public function secondsSinceMidnight()
+ {
+ return $this->diffInSeconds($this->copy()->startOfDay());
+ }
+
+ /**
+ * The number of seconds until 23:23:59.
+ *
+ * @return int
+ */
+ public function secondsUntilEndOfDay()
+ {
+ return $this->diffInSeconds($this->copy()->endOfDay());
+ }
+
+ /**
+ * Get the difference in a human readable format in the current locale.
+ *
+ * When comparing a value in the past to default now:
+ * 1 hour ago
+ * 5 months ago
+ *
+ * When comparing a value in the future to default now:
+ * 1 hour from now
+ * 5 months from now
+ *
+ * When comparing a value in the past to another value:
+ * 1 hour before
+ * 5 months before
+ *
+ * When comparing a value in the future to another value:
+ * 1 hour after
+ * 5 months after
+ *
+ * @param Carbon|null $other
+ * @param bool $absolute removes time difference modifiers ago, after, etc
+ * @param bool $short displays short format of time units
+ *
+ * @return string
+ */
+ public function diffForHumans(Carbon $other = null, $absolute = false, $short = false)
+ {
+ $isNow = $other === null;
+
+ if ($isNow) {
+ $other = static::now($this->getTimezone());
+ }
+
+ $diffInterval = $this->diff($other);
+
+ switch (true) {
+ case $diffInterval->y > 0:
+ $unit = $short ? 'y' : 'year';
+ $count = $diffInterval->y;
+ break;
+
+ case $diffInterval->m > 0:
+ $unit = $short ? 'm' : 'month';
+ $count = $diffInterval->m;
+ break;
+
+ case $diffInterval->d > 0:
+ $unit = $short ? 'd' : 'day';
+ $count = $diffInterval->d;
+
+ if ($count >= static::DAYS_PER_WEEK) {
+ $unit = $short ? 'w' : 'week';
+ $count = (int) ($count / static::DAYS_PER_WEEK);
+ }
+ break;
+
+ case $diffInterval->h > 0:
+ $unit = $short ? 'h' : 'hour';
+ $count = $diffInterval->h;
+ break;
+
+ case $diffInterval->i > 0:
+ $unit = $short ? 'min' : 'minute';
+ $count = $diffInterval->i;
+ break;
+
+ default:
+ $count = $diffInterval->s;
+ $unit = $short ? 's' : 'second';
+ break;
+ }
+
+ if ($count === 0) {
+ $count = 1;
+ }
+
+ $time = static::translator()->transChoice($unit, $count, array(':count' => $count));
+
+ if ($absolute) {
+ return $time;
+ }
+
+ $isFuture = $diffInterval->invert === 1;
+
+ $transId = $isNow ? ($isFuture ? 'from_now' : 'ago') : ($isFuture ? 'after' : 'before');
+
+ // Some langs have special pluralization for past and future tense.
+ $tryKeyExists = $unit.'_'.$transId;
+ if ($tryKeyExists !== static::translator()->transChoice($tryKeyExists, $count)) {
+ $time = static::translator()->transChoice($tryKeyExists, $count, array(':count' => $count));
+ }
+
+ return static::translator()->trans($transId, array(':time' => $time));
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //////////////////////////// MODIFIERS ////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Resets the time to 00:00:00
+ *
+ * @return static
+ */
+ public function startOfDay()
+ {
+ return $this->setTime(0, 0, 0);
+ }
+
+ /**
+ * Resets the time to 23:59:59
+ *
+ * @return static
+ */
+ public function endOfDay()
+ {
+ return $this->setTime(23, 59, 59);
+ }
+
+ /**
+ * Resets the date to the first day of the month and the time to 00:00:00
+ *
+ * @return static
+ */
+ public function startOfMonth()
+ {
+ return $this->setDateTime($this->year, $this->month, 1, 0, 0, 0);
+ }
+
+ /**
+ * Resets the date to end of the month and time to 23:59:59
+ *
+ * @return static
+ */
+ public function endOfMonth()
+ {
+ return $this->setDateTime($this->year, $this->month, $this->daysInMonth, 23, 59, 59);
+ }
+
+ /**
+ * Resets the date to the first day of the quarter and the time to 00:00:00
+ *
+ * @return static
+ */
+ public function startOfQuarter()
+ {
+ $month = ($this->quarter - 1) * static::MONTHS_PER_QUARTER + 1;
+
+ return $this->setDateTime($this->year, $month, 1, 0, 0, 0);
+ }
+
+ /**
+ * Resets the date to end of the quarter and time to 23:59:59
+ *
+ * @return static
+ */
+ public function endOfQuarter()
+ {
+ return $this->startOfQuarter()->addMonths(static::MONTHS_PER_QUARTER - 1)->endOfMonth();
+ }
+
+ /**
+ * Resets the date to the first day of the year and the time to 00:00:00
+ *
+ * @return static
+ */
+ public function startOfYear()
+ {
+ return $this->setDateTime($this->year, 1, 1, 0, 0, 0);
+ }
+
+ /**
+ * Resets the date to end of the year and time to 23:59:59
+ *
+ * @return static
+ */
+ public function endOfYear()
+ {
+ return $this->setDateTime($this->year, 12, 31, 23, 59, 59);
+ }
+
+ /**
+ * Resets the date to the first day of the decade and the time to 00:00:00
+ *
+ * @return static
+ */
+ public function startOfDecade()
+ {
+ $year = $this->year - $this->year % static::YEARS_PER_DECADE;
+
+ return $this->setDateTime($year, 1, 1, 0, 0, 0);
+ }
+
+ /**
+ * Resets the date to end of the decade and time to 23:59:59
+ *
+ * @return static
+ */
+ public function endOfDecade()
+ {
+ $year = $this->year - $this->year % static::YEARS_PER_DECADE + static::YEARS_PER_DECADE - 1;
+
+ return $this->setDateTime($year, 12, 31, 23, 59, 59);
+ }
+
+ /**
+ * Resets the date to the first day of the century and the time to 00:00:00
+ *
+ * @return static
+ */
+ public function startOfCentury()
+ {
+ $year = $this->year - ($this->year - 1) % static::YEARS_PER_CENTURY;
+
+ return $this->setDateTime($year, 1, 1, 0, 0, 0);
+ }
+
+ /**
+ * Resets the date to end of the century and time to 23:59:59
+ *
+ * @return static
+ */
+ public function endOfCentury()
+ {
+ $year = $this->year - 1 - ($this->year - 1) % static::YEARS_PER_CENTURY + static::YEARS_PER_CENTURY;
+
+ return $this->setDateTime($year, 12, 31, 23, 59, 59);
+ }
+
+ /**
+ * Resets the date to the first day of week (defined in $weekStartsAt) and the time to 00:00:00
+ *
+ * @return static
+ */
+ public function startOfWeek()
+ {
+ while ($this->dayOfWeek !== static::$weekStartsAt) {
+ $this->subDay();
+ }
+
+ return $this->startOfDay();
+ }
+
+ /**
+ * Resets the date to end of week (defined in $weekEndsAt) and time to 23:59:59
+ *
+ * @return static
+ */
+ public function endOfWeek()
+ {
+ while ($this->dayOfWeek !== static::$weekEndsAt) {
+ $this->addDay();
+ }
+
+ return $this->endOfDay();
+ }
+
+ /**
+ * Modify to the next occurrence of a given day of the week.
+ * If no dayOfWeek is provided, modify to the next occurrence
+ * of the current day of the week. Use the supplied constants
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int|null $dayOfWeek
+ *
+ * @return static
+ */
+ public function next($dayOfWeek = null)
+ {
+ if ($dayOfWeek === null) {
+ $dayOfWeek = $this->dayOfWeek;
+ }
+
+ return $this->startOfDay()->modify('next '.static::$days[$dayOfWeek]);
+ }
+
+ /**
+ * Go forward or backward to the next week- or weekend-day.
+ *
+ * @param bool $weekday
+ * @param bool $forward
+ *
+ * @return static
+ */
+ private function nextOrPreviousDay($weekday = true, $forward = true)
+ {
+ $step = $forward ? 1 : -1;
+
+ do {
+ $this->addDay($step);
+ } while ($weekday ? $this->isWeekend() : $this->isWeekday());
+
+ return $this;
+ }
+
+ /**
+ * Go forward to the next weekday.
+ *
+ * @return $this
+ */
+ public function nextWeekday()
+ {
+ return $this->nextOrPreviousDay();
+ }
+
+ /**
+ * Go backward to the previous weekday.
+ *
+ * @return static
+ */
+ public function previousWeekday()
+ {
+ return $this->nextOrPreviousDay(true, false);
+ }
+
+ /**
+ * Go forward to the next weekend day.
+ *
+ * @return static
+ */
+ public function nextWeekendDay()
+ {
+ return $this->nextOrPreviousDay(false);
+ }
+
+ /**
+ * Go backward to the previous weekend day.
+ *
+ * @return static
+ */
+ public function previousWeekendDay()
+ {
+ return $this->nextOrPreviousDay(false, false);
+ }
+
+ /**
+ * Modify to the previous occurrence of a given day of the week.
+ * If no dayOfWeek is provided, modify to the previous occurrence
+ * of the current day of the week. Use the supplied constants
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int|null $dayOfWeek
+ *
+ * @return static
+ */
+ public function previous($dayOfWeek = null)
+ {
+ if ($dayOfWeek === null) {
+ $dayOfWeek = $this->dayOfWeek;
+ }
+
+ return $this->startOfDay()->modify('last '.static::$days[$dayOfWeek]);
+ }
+
+ /**
+ * Modify to the first occurrence of a given day of the week
+ * in the current month. If no dayOfWeek is provided, modify to the
+ * first day of the current month. Use the supplied constants
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int|null $dayOfWeek
+ *
+ * @return static
+ */
+ public function firstOfMonth($dayOfWeek = null)
+ {
+ $this->startOfDay();
+
+ if ($dayOfWeek === null) {
+ return $this->day(1);
+ }
+
+ return $this->modify('first '.static::$days[$dayOfWeek].' of '.$this->format('F').' '.$this->year);
+ }
+
+ /**
+ * Modify to the last occurrence of a given day of the week
+ * in the current month. If no dayOfWeek is provided, modify to the
+ * last day of the current month. Use the supplied constants
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int|null $dayOfWeek
+ *
+ * @return static
+ */
+ public function lastOfMonth($dayOfWeek = null)
+ {
+ $this->startOfDay();
+
+ if ($dayOfWeek === null) {
+ return $this->day($this->daysInMonth);
+ }
+
+ return $this->modify('last '.static::$days[$dayOfWeek].' of '.$this->format('F').' '.$this->year);
+ }
+
+ /**
+ * Modify to the given occurrence of a given day of the week
+ * in the current month. If the calculated occurrence is outside the scope
+ * of the current month, then return false and no modifications are made.
+ * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int $nth
+ * @param int $dayOfWeek
+ *
+ * @return mixed
+ */
+ public function nthOfMonth($nth, $dayOfWeek)
+ {
+ $dt = $this->copy()->firstOfMonth();
+ $check = $dt->format('Y-m');
+ $dt->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
+
+ return $dt->format('Y-m') === $check ? $this->modify($dt) : false;
+ }
+
+ /**
+ * Modify to the first occurrence of a given day of the week
+ * in the current quarter. If no dayOfWeek is provided, modify to the
+ * first day of the current quarter. Use the supplied constants
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int|null $dayOfWeek
+ *
+ * @return static
+ */
+ public function firstOfQuarter($dayOfWeek = null)
+ {
+ return $this->setDate($this->year, $this->quarter * static::MONTHS_PER_QUARTER - 2, 1)->firstOfMonth($dayOfWeek);
+ }
+
+ /**
+ * Modify to the last occurrence of a given day of the week
+ * in the current quarter. If no dayOfWeek is provided, modify to the
+ * last day of the current quarter. Use the supplied constants
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int|null $dayOfWeek
+ *
+ * @return static
+ */
+ public function lastOfQuarter($dayOfWeek = null)
+ {
+ return $this->setDate($this->year, $this->quarter * static::MONTHS_PER_QUARTER, 1)->lastOfMonth($dayOfWeek);
+ }
+
+ /**
+ * Modify to the given occurrence of a given day of the week
+ * in the current quarter. If the calculated occurrence is outside the scope
+ * of the current quarter, then return false and no modifications are made.
+ * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int $nth
+ * @param int $dayOfWeek
+ *
+ * @return mixed
+ */
+ public function nthOfQuarter($nth, $dayOfWeek)
+ {
+ $dt = $this->copy()->day(1)->month($this->quarter * static::MONTHS_PER_QUARTER);
+ $lastMonth = $dt->month;
+ $year = $dt->year;
+ $dt->firstOfQuarter()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
+
+ return ($lastMonth < $dt->month || $year !== $dt->year) ? false : $this->modify($dt);
+ }
+
+ /**
+ * Modify to the first occurrence of a given day of the week
+ * in the current year. If no dayOfWeek is provided, modify to the
+ * first day of the current year. Use the supplied constants
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int|null $dayOfWeek
+ *
+ * @return static
+ */
+ public function firstOfYear($dayOfWeek = null)
+ {
+ return $this->month(1)->firstOfMonth($dayOfWeek);
+ }
+
+ /**
+ * Modify to the last occurrence of a given day of the week
+ * in the current year. If no dayOfWeek is provided, modify to the
+ * last day of the current year. Use the supplied constants
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int|null $dayOfWeek
+ *
+ * @return static
+ */
+ public function lastOfYear($dayOfWeek = null)
+ {
+ return $this->month(static::MONTHS_PER_YEAR)->lastOfMonth($dayOfWeek);
+ }
+
+ /**
+ * Modify to the given occurrence of a given day of the week
+ * in the current year. If the calculated occurrence is outside the scope
+ * of the current year, then return false and no modifications are made.
+ * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
+ *
+ * @param int $nth
+ * @param int $dayOfWeek
+ *
+ * @return mixed
+ */
+ public function nthOfYear($nth, $dayOfWeek)
+ {
+ $dt = $this->copy()->firstOfYear()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
+
+ return $this->year === $dt->year ? $this->modify($dt) : false;
+ }
+
+ /**
+ * Modify the current instance to the average of a given instance (default now) and the current instance.
+ *
+ * @param \Carbon\Carbon|null $dt
+ *
+ * @return static
+ */
+ public function average(Carbon $dt = null)
+ {
+ $dt = $dt ?: static::now($this->getTimezone());
+
+ return $this->addSeconds((int) ($this->diffInSeconds($dt, false) / 2));
+ }
+
+ /**
+ * Check if its the birthday. Compares the date/month values of the two dates.
+ *
+ * @param \Carbon\Carbon|null $dt The instance to compare with or null to use current day.
+ *
+ * @return bool
+ */
+ public function isBirthday(Carbon $dt = null)
+ {
+ return $this->isSameAs('md', $dt);
+ }
+
+ /**
+ * Consider the timezone when modifying the instance.
+ *
+ * @param string $modify
+ *
+ * @return static
+ */
+ public function modify($modify)
+ {
+ if ($this->local) {
+ return parent::modify($modify);
+ }
+
+ $timezone = $this->getTimezone();
+ $this->setTimezone('UTC');
+ $instance = parent::modify($modify);
+ $this->setTimezone($timezone);
+
+ return $instance;
+ }
+
+ /**
+ * Return a serialized string of the instance.
+ *
+ * @return string
+ */
+ public function serialize()
+ {
+ return serialize($this);
+ }
+
+ /**
+ * Create an instance form a serialized string.
+ *
+ * @param string $value
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return static
+ */
+ public static function fromSerialized($value)
+ {
+ $instance = @unserialize($value);
+
+ if (!$instance instanceof static) {
+ throw new InvalidArgumentException('Invalid serialized value.');
+ }
+
+ return $instance;
+ }
+}
diff --git a/vendor/nesbot/carbon/src/Carbon/CarbonInterval.php b/vendor/nesbot/carbon/src/Carbon/CarbonInterval.php
new file mode 100644
index 00000000..514ca6e8
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/CarbonInterval.php
@@ -0,0 +1,557 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Carbon;
+
+use DateInterval;
+use InvalidArgumentException;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * A simple API extension for DateInterval.
+ * The implementation provides helpers to handle weeks but only days are saved.
+ * Weeks are calculated based on the total days of the current instance.
+ *
+ * @property int $years Total years of the current interval.
+ * @property int $months Total months of the current interval.
+ * @property int $weeks Total weeks of the current interval calculated from the days.
+ * @property int $dayz Total days of the current interval (weeks * 7 + days).
+ * @property int $hours Total hours of the current interval.
+ * @property int $minutes Total minutes of the current interval.
+ * @property int $seconds Total seconds of the current interval.
+ * @property-read int $dayzExcludeWeeks Total days remaining in the final week of the current instance (days % 7).
+ * @property-read int $daysExcludeWeeks alias of dayzExcludeWeeks
+ *
+ * @method static CarbonInterval years($years = 1) Create instance specifying a number of years.
+ * @method static CarbonInterval year($years = 1) Alias for years()
+ * @method static CarbonInterval months($months = 1) Create instance specifying a number of months.
+ * @method static CarbonInterval month($months = 1) Alias for months()
+ * @method static CarbonInterval weeks($weeks = 1) Create instance specifying a number of weeks.
+ * @method static CarbonInterval week($weeks = 1) Alias for weeks()
+ * @method static CarbonInterval days($days = 1) Create instance specifying a number of days.
+ * @method static CarbonInterval dayz($days = 1) Alias for days()
+ * @method static CarbonInterval day($days = 1) Alias for days()
+ * @method static CarbonInterval hours($hours = 1) Create instance specifying a number of hours.
+ * @method static CarbonInterval hour($hours = 1) Alias for hours()
+ * @method static CarbonInterval minutes($minutes = 1) Create instance specifying a number of minutes.
+ * @method static CarbonInterval minute($minutes = 1) Alias for minutes()
+ * @method static CarbonInterval seconds($seconds = 1) Create instance specifying a number of seconds.
+ * @method static CarbonInterval second($seconds = 1) Alias for seconds()
+ * @method CarbonInterval years() years($years = 1) Set the years portion of the current interval.
+ * @method CarbonInterval year() year($years = 1) Alias for years().
+ * @method CarbonInterval months() months($months = 1) Set the months portion of the current interval.
+ * @method CarbonInterval month() month($months = 1) Alias for months().
+ * @method CarbonInterval weeks() weeks($weeks = 1) Set the weeks portion of the current interval. Will overwrite dayz value.
+ * @method CarbonInterval week() week($weeks = 1) Alias for weeks().
+ * @method CarbonInterval days() days($days = 1) Set the days portion of the current interval.
+ * @method CarbonInterval dayz() dayz($days = 1) Alias for days().
+ * @method CarbonInterval day() day($days = 1) Alias for days().
+ * @method CarbonInterval hours() hours($hours = 1) Set the hours portion of the current interval.
+ * @method CarbonInterval hour() hour($hours = 1) Alias for hours().
+ * @method CarbonInterval minutes() minutes($minutes = 1) Set the minutes portion of the current interval.
+ * @method CarbonInterval minute() minute($minutes = 1) Alias for minutes().
+ * @method CarbonInterval seconds() seconds($seconds = 1) Set the seconds portion of the current interval.
+ * @method CarbonInterval second() second($seconds = 1) Alias for seconds().
+ */
+class CarbonInterval extends DateInterval
+{
+ /**
+ * Interval spec period designators
+ */
+ const PERIOD_PREFIX = 'P';
+ const PERIOD_YEARS = 'Y';
+ const PERIOD_MONTHS = 'M';
+ const PERIOD_DAYS = 'D';
+ const PERIOD_TIME_PREFIX = 'T';
+ const PERIOD_HOURS = 'H';
+ const PERIOD_MINUTES = 'M';
+ const PERIOD_SECONDS = 'S';
+
+ /**
+ * A translator to ... er ... translate stuff
+ *
+ * @var \Symfony\Component\Translation\TranslatorInterface
+ */
+ protected static $translator;
+
+ /**
+ * Before PHP 5.4.20/5.5.4 instead of FALSE days will be set to -99999 when the interval instance
+ * was created by DateTime:diff().
+ */
+ const PHP_DAYS_FALSE = -99999;
+
+ /**
+ * Determine if the interval was created via DateTime:diff() or not.
+ *
+ * @param DateInterval $interval
+ *
+ * @return bool
+ */
+ private static function wasCreatedFromDiff(DateInterval $interval)
+ {
+ return $interval->days !== false && $interval->days !== static::PHP_DAYS_FALSE;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //////////////////////////// CONSTRUCTORS /////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Create a new CarbonInterval instance.
+ *
+ * @param int $years
+ * @param int $months
+ * @param int $weeks
+ * @param int $days
+ * @param int $hours
+ * @param int $minutes
+ * @param int $seconds
+ */
+ public function __construct($years = 1, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null)
+ {
+ $spec = static::PERIOD_PREFIX;
+
+ $spec .= $years > 0 ? $years.static::PERIOD_YEARS : '';
+ $spec .= $months > 0 ? $months.static::PERIOD_MONTHS : '';
+
+ $specDays = 0;
+ $specDays += $weeks > 0 ? $weeks * Carbon::DAYS_PER_WEEK : 0;
+ $specDays += $days > 0 ? $days : 0;
+
+ $spec .= $specDays > 0 ? $specDays.static::PERIOD_DAYS : '';
+
+ if ($hours > 0 || $minutes > 0 || $seconds > 0) {
+ $spec .= static::PERIOD_TIME_PREFIX;
+ $spec .= $hours > 0 ? $hours.static::PERIOD_HOURS : '';
+ $spec .= $minutes > 0 ? $minutes.static::PERIOD_MINUTES : '';
+ $spec .= $seconds > 0 ? $seconds.static::PERIOD_SECONDS : '';
+ }
+
+ if ($spec === static::PERIOD_PREFIX) {
+ // Allow the zero interval.
+ $spec .= '0'.static::PERIOD_YEARS;
+ }
+
+ parent::__construct($spec);
+ }
+
+ /**
+ * Create a new CarbonInterval instance from specific values.
+ * This is an alias for the constructor that allows better fluent
+ * syntax as it allows you to do CarbonInterval::create(1)->fn() rather than
+ * (new CarbonInterval(1))->fn().
+ *
+ * @param int $years
+ * @param int $months
+ * @param int $weeks
+ * @param int $days
+ * @param int $hours
+ * @param int $minutes
+ * @param int $seconds
+ *
+ * @return static
+ */
+ public static function create($years = 1, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null)
+ {
+ return new static($years, $months, $weeks, $days, $hours, $minutes, $seconds);
+ }
+
+ /**
+ * Provide static helpers to create instances. Allows CarbonInterval::years(3).
+ *
+ * Note: This is done using the magic method to allow static and instance methods to
+ * have the same names.
+ *
+ * @param string $name
+ * @param array $args
+ *
+ * @return static
+ */
+ public static function __callStatic($name, $args)
+ {
+ $arg = count($args) === 0 ? 1 : $args[0];
+
+ switch ($name) {
+ case 'years':
+ case 'year':
+ return new static($arg);
+
+ case 'months':
+ case 'month':
+ return new static(null, $arg);
+
+ case 'weeks':
+ case 'week':
+ return new static(null, null, $arg);
+
+ case 'days':
+ case 'dayz':
+ case 'day':
+ return new static(null, null, null, $arg);
+
+ case 'hours':
+ case 'hour':
+ return new static(null, null, null, null, $arg);
+
+ case 'minutes':
+ case 'minute':
+ return new static(null, null, null, null, null, $arg);
+
+ case 'seconds':
+ case 'second':
+ return new static(null, null, null, null, null, null, $arg);
+ }
+ }
+
+ /**
+ * Create a CarbonInterval instance from a DateInterval one. Can not instance
+ * DateInterval objects created from DateTime::diff() as you can't externally
+ * set the $days field.
+ *
+ * @param DateInterval $di
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return static
+ */
+ public static function instance(DateInterval $di)
+ {
+ if (static::wasCreatedFromDiff($di)) {
+ throw new InvalidArgumentException('Can not instance a DateInterval object created from DateTime::diff().');
+ }
+
+ $instance = new static($di->y, $di->m, 0, $di->d, $di->h, $di->i, $di->s);
+ $instance->invert = $di->invert;
+ $instance->days = $di->days;
+
+ return $instance;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////// LOCALIZATION //////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Initialize the translator instance if necessary.
+ *
+ * @return \Symfony\Component\Translation\TranslatorInterface
+ */
+ protected static function translator()
+ {
+ if (static::$translator === null) {
+ static::$translator = new Translator('en');
+ static::$translator->addLoader('array', new ArrayLoader());
+ static::setLocale('en');
+ }
+
+ return static::$translator;
+ }
+
+ /**
+ * Get the translator instance in use
+ *
+ * @return \Symfony\Component\Translation\TranslatorInterface
+ */
+ public static function getTranslator()
+ {
+ return static::translator();
+ }
+
+ /**
+ * Set the translator instance to use
+ *
+ * @param TranslatorInterface $translator
+ */
+ public static function setTranslator(TranslatorInterface $translator)
+ {
+ static::$translator = $translator;
+ }
+
+ /**
+ * Get the current translator locale
+ *
+ * @return string
+ */
+ public static function getLocale()
+ {
+ return static::translator()->getLocale();
+ }
+
+ /**
+ * Set the current translator locale
+ *
+ * @param string $locale
+ */
+ public static function setLocale($locale)
+ {
+ static::translator()->setLocale($locale);
+
+ // Ensure the locale has been loaded.
+ static::translator()->addResource('array', require __DIR__.'/Lang/'.$locale.'.php', $locale);
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ ///////////////////////// GETTERS AND SETTERS /////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Get a part of the CarbonInterval object
+ *
+ * @param string $name
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return int
+ */
+ public function __get($name)
+ {
+ switch ($name) {
+ case 'years':
+ return $this->y;
+
+ case 'months':
+ return $this->m;
+
+ case 'dayz':
+ return $this->d;
+
+ case 'hours':
+ return $this->h;
+
+ case 'minutes':
+ return $this->i;
+
+ case 'seconds':
+ return $this->s;
+
+ case 'weeks':
+ return (int) floor($this->d / Carbon::DAYS_PER_WEEK);
+
+ case 'daysExcludeWeeks':
+ case 'dayzExcludeWeeks':
+ return $this->d % Carbon::DAYS_PER_WEEK;
+
+ default:
+ throw new InvalidArgumentException(sprintf("Unknown getter '%s'", $name));
+ }
+ }
+
+ /**
+ * Set a part of the CarbonInterval object
+ *
+ * @param string $name
+ * @param int $val
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function __set($name, $val)
+ {
+ switch ($name) {
+ case 'years':
+ $this->y = $val;
+ break;
+
+ case 'months':
+ $this->m = $val;
+ break;
+
+ case 'weeks':
+ $this->d = $val * Carbon::DAYS_PER_WEEK;
+ break;
+
+ case 'dayz':
+ $this->d = $val;
+ break;
+
+ case 'hours':
+ $this->h = $val;
+ break;
+
+ case 'minutes':
+ $this->i = $val;
+ break;
+
+ case 'seconds':
+ $this->s = $val;
+ break;
+ }
+ }
+
+ /**
+ * Allow setting of weeks and days to be cumulative.
+ *
+ * @param int $weeks Number of weeks to set
+ * @param int $days Number of days to set
+ *
+ * @return static
+ */
+ public function weeksAndDays($weeks, $days)
+ {
+ $this->dayz = ($weeks * Carbon::DAYS_PER_WEEK) + $days;
+
+ return $this;
+ }
+
+ /**
+ * Allow fluent calls on the setters... CarbonInterval::years(3)->months(5)->day().
+ *
+ * Note: This is done using the magic method to allow static and instance methods to
+ * have the same names.
+ *
+ * @param string $name
+ * @param array $args
+ *
+ * @return static
+ */
+ public function __call($name, $args)
+ {
+ $arg = count($args) === 0 ? 1 : $args[0];
+
+ switch ($name) {
+ case 'years':
+ case 'year':
+ $this->years = $arg;
+ break;
+
+ case 'months':
+ case 'month':
+ $this->months = $arg;
+ break;
+
+ case 'weeks':
+ case 'week':
+ $this->dayz = $arg * Carbon::DAYS_PER_WEEK;
+ break;
+
+ case 'days':
+ case 'dayz':
+ case 'day':
+ $this->dayz = $arg;
+ break;
+
+ case 'hours':
+ case 'hour':
+ $this->hours = $arg;
+ break;
+
+ case 'minutes':
+ case 'minute':
+ $this->minutes = $arg;
+ break;
+
+ case 'seconds':
+ case 'second':
+ $this->seconds = $arg;
+ break;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get the current interval in a human readable format in the current locale.
+ *
+ * @return string
+ */
+ public function forHumans()
+ {
+ $periods = array(
+ 'year' => $this->years,
+ 'month' => $this->months,
+ 'week' => $this->weeks,
+ 'day' => $this->daysExcludeWeeks,
+ 'hour' => $this->hours,
+ 'minute' => $this->minutes,
+ 'second' => $this->seconds,
+ );
+
+ $parts = array();
+ foreach ($periods as $unit => $count) {
+ if ($count > 0) {
+ array_push($parts, static::translator()->transChoice($unit, $count, array(':count' => $count)));
+ }
+ }
+
+ return implode(' ', $parts);
+ }
+
+ /**
+ * Format the instance as a string using the forHumans() function.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->forHumans();
+ }
+
+ /**
+ * Add the passed interval to the current instance
+ *
+ * @param DateInterval $interval
+ *
+ * @return static
+ */
+ public function add(DateInterval $interval)
+ {
+ $sign = $interval->invert === 1 ? -1 : 1;
+
+ if (static::wasCreatedFromDiff($interval)) {
+ $this->dayz += $interval->days * $sign;
+ } else {
+ $this->years += $interval->y * $sign;
+ $this->months += $interval->m * $sign;
+ $this->dayz += $interval->d * $sign;
+ $this->hours += $interval->h * $sign;
+ $this->minutes += $interval->i * $sign;
+ $this->seconds += $interval->s * $sign;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get the interval_spec string
+ *
+ * @return string
+ */
+ public function spec()
+ {
+ $date = array_filter(array(
+ static::PERIOD_YEARS => $this->y,
+ static::PERIOD_MONTHS => $this->m,
+ static::PERIOD_DAYS => $this->d,
+ ));
+
+ $time = array_filter(array(
+ static::PERIOD_HOURS => $this->h,
+ static::PERIOD_MINUTES => $this->i,
+ static::PERIOD_SECONDS => $this->s,
+ ));
+
+ $specString = static::PERIOD_PREFIX;
+
+ foreach ($date as $key => $value) {
+ $specString .= $value.$key;
+ }
+
+ if (count($time) > 0) {
+ $specString .= static::PERIOD_TIME_PREFIX;
+ foreach ($time as $key => $value) {
+ $specString .= $value.$key;
+ }
+ }
+
+ return $specString === static::PERIOD_PREFIX ? 'PT0S' : $specString;
+ }
+}
diff --git a/vendor/nesbot/carbon/src/Carbon/Exceptions/InvalidDateException.php b/vendor/nesbot/carbon/src/Carbon/Exceptions/InvalidDateException.php
new file mode 100644
index 00000000..1b0d4737
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Exceptions/InvalidDateException.php
@@ -0,0 +1,67 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Carbon\Exceptions;
+
+use Exception;
+use InvalidArgumentException;
+
+class InvalidDateException extends InvalidArgumentException
+{
+ /**
+ * The invalid field.
+ *
+ * @var string
+ */
+ private $field;
+
+ /**
+ * The invalid value.
+ *
+ * @var mixed
+ */
+ private $value;
+
+ /**
+ * Constructor.
+ *
+ * @param string $field
+ * @param mixed $value
+ * @param int $code
+ * @param \Exception|null $previous
+ */
+ public function __construct($field, $value, $code = 0, Exception $previous = null)
+ {
+ $this->field = $field;
+ $this->value = $value;
+ parent::__construct($field.' : '.$value.' is not a valid value.', $code, $previous);
+ }
+
+ /**
+ * Get the invalid field.
+ *
+ * @return string
+ */
+ public function getField()
+ {
+ return $this->field;
+ }
+
+ /**
+ * Get the invalid value.
+ *
+ * @return mixed
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+}
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/af.php b/vendor/nesbot/carbon/src/Carbon/Lang/af.php
new file mode 100644
index 00000000..a8610d6d
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/af.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 jaar|:count jare',
+ 'y' => '1 jaar|:count jare',
+ 'month' => '1 maand|:count maande',
+ 'm' => '1 maand|:count maande',
+ 'week' => '1 week|:count weke',
+ 'w' => '1 week|:count weke',
+ 'day' => '1 dag|:count dae',
+ 'd' => '1 dag|:count dae',
+ 'hour' => '1 uur|:count ure',
+ 'h' => '1 uur|:count ure',
+ 'minute' => '1 minuut|:count minute',
+ 'min' => '1 minuut|:count minute',
+ 'second' => '1 sekond|:count sekondes',
+ 's' => '1 sekond|:count sekondes',
+ 'ago' => ':time terug',
+ 'from_now' => ':time van nou af',
+ 'after' => ':time na',
+ 'before' => ':time voor',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ar.php b/vendor/nesbot/carbon/src/Carbon/Lang/ar.php
new file mode 100644
index 00000000..253cf503
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/ar.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '{0}سنة|{1}سنة|{2}سنتين|[3,10]:count سنوات|[11,Inf]:count سنة',
+ 'y' => '{0}سنة|{1}سنة|{2}سنتين|[3,10]:count سنوات|[11,Inf]:count سنة',
+ 'month' => '{0}شهر|{1} شهر|{2}شهرين|[3,10]:count أشهر|[11,Inf]:count شهر',
+ 'm' => '{0}شهر|{1} شهر|{2}شهرين|[3,10]:count أشهر|[11,Inf]:count شهر',
+ 'week' => '{0}إسبوع|{1}إسبوع|{2}إسبوعين|[3,10]:count أسابيع|[11,Inf]:count إسبوع',
+ 'w' => '{0}إسبوع|{1}إسبوع|{2}إسبوعين|[3,10]:count أسابيع|[11,Inf]:count إسبوع',
+ 'day' => '{0}يوم|{1}يوم|{2}يومين|[3,10]:count أيام|[11,Inf] يوم',
+ 'd' => '{0}يوم|{1}يوم|{2}يومين|[3,10]:count أيام|[11,Inf] يوم',
+ 'hour' => '{0}ساعة|{1}ساعة|{2}ساعتين|[3,10]:count ساعات|[11,Inf]:count ساعة',
+ 'h' => '{0}ساعة|{1}ساعة|{2}ساعتين|[3,10]:count ساعات|[11,Inf]:count ساعة',
+ 'minute' => '{0}دقيقة|{1}دقيقة|{2}دقيقتين|[3,10]:count دقائق|[11,Inf]:count دقيقة',
+ 'min' => '{0}دقيقة|{1}دقيقة|{2}دقيقتين|[3,10]:count دقائق|[11,Inf]:count دقيقة',
+ 'second' => '{0}ثانية|{1}ثانية|{2}ثانيتين|[3,10]:count ثوان|[11,Inf]:count ثانية',
+ 's' => '{0}ثانية|{1}ثانية|{2}ثانيتين|[3,10]:count ثوان|[11,Inf]:count ثانية',
+ 'ago' => 'منذ :time',
+ 'from_now' => 'من الآن :time',
+ 'after' => 'بعد :time',
+ 'before' => 'قبل :time',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/az.php b/vendor/nesbot/carbon/src/Carbon/Lang/az.php
new file mode 100644
index 00000000..e4f3789a
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/az.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count il',
+ 'y' => ':count il',
+ 'month' => ':count ay',
+ 'm' => ':count ay',
+ 'week' => ':count həftə',
+ 'w' => ':count həftə',
+ 'day' => ':count gün',
+ 'd' => ':count gün',
+ 'hour' => ':count saat',
+ 'h' => ':count saat',
+ 'minute' => ':count dəqiqə',
+ 'min' => ':count dəqiqə',
+ 'second' => ':count saniyə',
+ 's' => ':count saniyə',
+ 'ago' => ':time öncə',
+ 'from_now' => ':time sonra',
+ 'after' => ':time sonra',
+ 'before' => ':time öncə',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/bg.php b/vendor/nesbot/carbon/src/Carbon/Lang/bg.php
new file mode 100644
index 00000000..309934b5
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/bg.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 година|:count години',
+ 'y' => '1 година|:count години',
+ 'month' => '1 месец|:count месеца',
+ 'm' => '1 месец|:count месеца',
+ 'week' => '1 седмица|:count седмици',
+ 'w' => '1 седмица|:count седмици',
+ 'day' => '1 ден|:count дни',
+ 'd' => '1 ден|:count дни',
+ 'hour' => '1 час|:count часа',
+ 'h' => '1 час|:count часа',
+ 'minute' => '1 минута|:count минути',
+ 'm' => '1 минута|:count минути',
+ 'second' => '1 секунда|:count секунди',
+ 's' => '1 секунда|:count секунди',
+ 'ago' => 'преди :time',
+ 'from_now' => ':time от сега',
+ 'after' => 'след :time',
+ 'before' => 'преди :time',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/bn.php b/vendor/nesbot/carbon/src/Carbon/Lang/bn.php
new file mode 100644
index 00000000..a930df38
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/bn.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '১ বছর|:count বছর',
+ 'y' => '১ বছর|:count বছর',
+ 'month' => '১ মাস|:count মাস',
+ 'm' => '১ মাস|:count মাস',
+ 'week' => '১ সপ্তাহ|:count সপ্তাহ',
+ 'w' => '১ সপ্তাহ|:count সপ্তাহ',
+ 'day' => '১ দিন|:count দিন',
+ 'd' => '১ দিন|:count দিন',
+ 'hour' => '১ ঘন্টা|:count ঘন্টা',
+ 'h' => '১ ঘন্টা|:count ঘন্টা',
+ 'minute' => '১ মিনিট|:count মিনিট',
+ 'min' => '১ মিনিট|:count মিনিট',
+ 'second' => '১ সেকেন্ড|:count সেকেন্ড',
+ 's' => '১ সেকেন্ড|:count সেকেন্ড',
+ 'ago' => ':time পূর্বে',
+ 'from_now' => 'এখন থেকে :time',
+ 'after' => ':time পরে',
+ 'before' => ':time আগে',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ca.php b/vendor/nesbot/carbon/src/Carbon/Lang/ca.php
new file mode 100644
index 00000000..91262e76
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/ca.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 any|:count anys',
+ 'y' => '1 any|:count anys',
+ 'month' => '1 mes|:count mesos',
+ 'm' => '1 mes|:count mesos',
+ 'week' => '1 setmana|:count setmanes',
+ 'w' => '1 setmana|:count setmanes',
+ 'day' => '1 dia|:count dies',
+ 'd' => '1 dia|:count dies',
+ 'hour' => '1 hora|:count hores',
+ 'h' => '1 hora|:count hores',
+ 'minute' => '1 minut|:count minuts',
+ 'min' => '1 minut|:count minuts',
+ 'second' => '1 segon|:count segons',
+ 's' => '1 segon|:count segons',
+ 'ago' => 'fa :time',
+ 'from_now' => 'dins de :time',
+ 'after' => ':time després',
+ 'before' => ':time abans',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/cs.php b/vendor/nesbot/carbon/src/Carbon/Lang/cs.php
new file mode 100644
index 00000000..f4aba76c
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/cs.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 rok|:count roky|:count let',
+ 'y' => '1 rok|:count roky|:count let',
+ 'month' => '1 měsíc|:count měsíce|:count měsíců',
+ 'm' => '1 měsíc|:count měsíce|:count měsíců',
+ 'week' => '1 týden|:count týdny|:count týdnů',
+ 'w' => '1 týden|:count týdny|:count týdnů',
+ 'day' => '1 den|:count dny|:count dní',
+ 'd' => '1 den|:count dny|:count dní',
+ 'hour' => '1 hodinu|:count hodiny|:count hodin',
+ 'h' => '1 hodinu|:count hodiny|:count hodin',
+ 'minute' => '1 minutu|:count minuty|:count minut',
+ 'min' => '1 minutu|:count minuty|:count minut',
+ 'second' => '1 sekundu|:count sekundy|:count sekund',
+ 's' => '1 sekundu|:count sekundy|:count sekund',
+ 'ago' => ':time nazpět',
+ 'from_now' => 'za :time',
+ 'after' => ':time později',
+ 'before' => ':time předtím',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/da.php b/vendor/nesbot/carbon/src/Carbon/Lang/da.php
new file mode 100644
index 00000000..67104741
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/da.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 år|:count år',
+ 'y' => '1 år|:count år',
+ 'month' => '1 måned|:count måneder',
+ 'm' => '1 måned|:count måneder',
+ 'week' => '1 uge|:count uger',
+ 'w' => '1 uge|:count uger',
+ 'day' => '1 dag|:count dage',
+ 'd' => '1 dag|:count dage',
+ 'hour' => '1 time|:count timer',
+ 'h' => '1 time|:count timer',
+ 'minute' => '1 minut|:count minutter',
+ 'min' => '1 minut|:count minutter',
+ 'second' => '1 sekund|:count sekunder',
+ 's' => '1 sekund|:count sekunder',
+ 'ago' => ':time siden',
+ 'from_now' => 'om :time',
+ 'after' => ':time efter',
+ 'before' => ':time før',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/de.php b/vendor/nesbot/carbon/src/Carbon/Lang/de.php
new file mode 100644
index 00000000..d1c572ac
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/de.php
@@ -0,0 +1,40 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 Jahr|:count Jahre',
+ 'y' => '1J|:countJ',
+ 'month' => '1 Monat|:count Monate',
+ 'm' => '1Mon|:countMon',
+ 'week' => '1 Woche|:count Wochen',
+ 'w' => '1Wo|:countWo',
+ 'day' => '1 Tag|:count Tage',
+ 'd' => '1Tg|:countTg',
+ 'hour' => '1 Stunde|:count Stunden',
+ 'h' => '1Std|:countStd',
+ 'minute' => '1 Minute|:count Minuten',
+ 'min' => '1Min|:countMin',
+ 'second' => '1 Sekunde|:count Sekunden',
+ 's' => '1Sek|:countSek',
+ 'ago' => 'vor :time',
+ 'from_now' => 'in :time',
+ 'after' => ':time später',
+ 'before' => ':time zuvor',
+
+ 'year_from_now' => '1 Jahr|:count Jahren',
+ 'month_from_now' => '1 Monat|:count Monaten',
+ 'week_from_now' => '1 Woche|:count Wochen',
+ 'day_from_now' => '1 Tag|:count Tagen',
+ 'year_ago' => '1 Jahr|:count Jahren',
+ 'month_ago' => '1 Monat|:count Monaten',
+ 'week_ago' => '1 Woche|:count Wochen',
+ 'day_ago' => '1 Tag|:count Tagen',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/el.php b/vendor/nesbot/carbon/src/Carbon/Lang/el.php
new file mode 100644
index 00000000..6028074d
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/el.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 χρόνος|:count χρόνια',
+ 'y' => '1 χρόνος|:count χρόνια',
+ 'month' => '1 μήνας|:count μήνες',
+ 'm' => '1 μήνας|:count μήνες',
+ 'week' => '1 εβδομάδα|:count εβδομάδες',
+ 'w' => '1 εβδομάδα|:count εβδομάδες',
+ 'day' => '1 μέρα|:count μέρες',
+ 'd' => '1 μέρα|:count μέρες',
+ 'hour' => '1 ώρα|:count ώρες',
+ 'h' => '1 ώρα|:count ώρες',
+ 'minute' => '1 λεπτό|:count λεπτά',
+ 'min' => '1 λεπτό|:count λεπτά',
+ 'second' => '1 δευτερόλεπτο|:count δευτερόλεπτα',
+ 's' => '1 δευτερόλεπτο|:count δευτερόλεπτα',
+ 'ago' => 'πρίν απο :time',
+ 'from_now' => 'σε :time απο τώρα',
+ 'after' => ':time μετά',
+ 'before' => ':time πρίν',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/en.php b/vendor/nesbot/carbon/src/Carbon/Lang/en.php
new file mode 100644
index 00000000..181c59be
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/en.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 year|:count years',
+ 'y' => '1yr|:countyrs',
+ 'month' => '1 month|:count months',
+ 'm' => '1mo|:countmos',
+ 'week' => '1 week|:count weeks',
+ 'w' => '1w|:countw',
+ 'day' => '1 day|:count days',
+ 'd' => '1d|:countd',
+ 'hour' => '1 hour|:count hours',
+ 'h' => '1h|:counth',
+ 'minute' => '1 minute|:count minutes',
+ 'min' => '1m|:countm',
+ 'second' => '1 second|:count seconds',
+ 's' => '1s|:counts',
+ 'ago' => ':time ago',
+ 'from_now' => ':time from now',
+ 'after' => ':time after',
+ 'before' => ':time before',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/eo.php b/vendor/nesbot/carbon/src/Carbon/Lang/eo.php
new file mode 100644
index 00000000..ff1f5311
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/eo.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 jaro|:count jaroj',
+ 'y' => '1 jaro|:count jaroj',
+ 'month' => '1 monato|:count monatoj',
+ 'm' => '1 monato|:count monatoj',
+ 'week' => '1 semajno|:count semajnoj',
+ 'w' => '1 semajno|:count semajnoj',
+ 'day' => '1 tago|:count tagoj',
+ 'd' => '1 tago|:count tagoj',
+ 'hour' => '1 horo|:count horoj',
+ 'h' => '1 horo|:count horoj',
+ 'minute' => '1 minuto|:count minutoj',
+ 'min' => '1 minuto|:count minutoj',
+ 'second' => '1 sekundo|:count sekundoj',
+ 's' => '1 sekundo|:count sekundoj',
+ 'ago' => 'antaŭ :time',
+ 'from_now' => 'je :time',
+ 'after' => ':time poste',
+ 'before' => ':time antaŭe',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/es.php b/vendor/nesbot/carbon/src/Carbon/Lang/es.php
new file mode 100644
index 00000000..fb0aff19
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/es.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 año|:count años',
+ 'y' => '1 año|:count años',
+ 'month' => '1 mes|:count meses',
+ 'm' => '1 mes|:count meses',
+ 'week' => '1 semana|:count semanas',
+ 'w' => '1 semana|:count semanas',
+ 'day' => '1 día|:count días',
+ 'd' => '1 día|:count días',
+ 'hour' => '1 hora|:count horas',
+ 'h' => '1 hora|:count horas',
+ 'minute' => '1 minuto|:count minutos',
+ 'min' => '1 minuto|:count minutos',
+ 'second' => '1 segundo|:count segundos',
+ 's' => '1 segundo|:count segundos',
+ 'ago' => 'hace :time',
+ 'from_now' => 'dentro de :time',
+ 'after' => ':time después',
+ 'before' => ':time antes',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/et.php b/vendor/nesbot/carbon/src/Carbon/Lang/et.php
new file mode 100644
index 00000000..70d682de
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/et.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 aasta|:count aastat',
+ 'y' => '1 aasta|:count aastat',
+ 'month' => '1 kuu|:count kuud',
+ 'm' => '1 kuu|:count kuud',
+ 'week' => '1 nädal|:count nädalat',
+ 'w' => '1 nädal|:count nädalat',
+ 'day' => '1 päev|:count päeva',
+ 'd' => '1 päev|:count päeva',
+ 'hour' => '1 tund|:count tundi',
+ 'h' => '1 tund|:count tundi',
+ 'minute' => '1 minut|:count minutit',
+ 'min' => '1 minut|:count minutit',
+ 'second' => '1 sekund|:count sekundit',
+ 's' => '1 sekund|:count sekundit',
+ 'ago' => ':time tagasi',
+ 'from_now' => ':time pärast',
+ 'after' => ':time pärast',
+ 'before' => ':time enne',
+ 'year_from_now' => ':count aasta',
+ 'month_from_now' => ':count kuu',
+ 'week_from_now' => ':count nädala',
+ 'day_from_now' => ':count päeva',
+ 'hour_from_now' => ':count tunni',
+ 'minute_from_now' => ':count minuti',
+ 'second_from_now' => ':count sekundi',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/eu.php b/vendor/nesbot/carbon/src/Carbon/Lang/eu.php
new file mode 100644
index 00000000..1cb6b7cd
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/eu.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => 'Urte 1|:count urte',
+ 'y' => 'Urte 1|:count urte',
+ 'month' => 'Hile 1|:count hile',
+ 'm' => 'Hile 1|:count hile',
+ 'week' => 'Aste 1|:count aste',
+ 'w' => 'Aste 1|:count aste',
+ 'day' => 'Egun 1|:count egun',
+ 'd' => 'Egun 1|:count egun',
+ 'hour' => 'Ordu 1|:count ordu',
+ 'h' => 'Ordu 1|:count ordu',
+ 'minute' => 'Minutu 1|:count minutu',
+ 'min' => 'Minutu 1|:count minutu',
+ 'second' => 'Segundu 1|:count segundu',
+ 's' => 'Segundu 1|:count segundu',
+ 'ago' => 'Orain dela :time',
+ 'from_now' => ':time barru',
+ 'after' => ':time geroago',
+ 'before' => ':time lehenago',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/fa.php b/vendor/nesbot/carbon/src/Carbon/Lang/fa.php
new file mode 100644
index 00000000..31bec886
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/fa.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count سال',
+ 'y' => ':count سال',
+ 'month' => ':count ماه',
+ 'm' => ':count ماه',
+ 'week' => ':count هفته',
+ 'w' => ':count هفته',
+ 'day' => ':count روز',
+ 'd' => ':count روز',
+ 'hour' => ':count ساعت',
+ 'h' => ':count ساعت',
+ 'minute' => ':count دقیقه',
+ 'min' => ':count دقیقه',
+ 'second' => ':count ثانیه',
+ 's' => ':count ثانیه',
+ 'ago' => ':time پیش',
+ 'from_now' => ':time بعد',
+ 'after' => ':time پس از',
+ 'before' => ':time پیش از',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/fi.php b/vendor/nesbot/carbon/src/Carbon/Lang/fi.php
new file mode 100644
index 00000000..46794fa5
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/fi.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 vuosi|:count vuotta',
+ 'y' => '1 vuosi|:count vuotta',
+ 'month' => '1 kuukausi|:count kuukautta',
+ 'm' => '1 kuukausi|:count kuukautta',
+ 'week' => '1 viikko|:count viikkoa',
+ 'w' => '1 viikko|:count viikkoa',
+ 'day' => '1 päivä|:count päivää',
+ 'd' => '1 päivä|:count päivää',
+ 'hour' => '1 tunti|:count tuntia',
+ 'h' => '1 tunti|:count tuntia',
+ 'minute' => '1 minuutti|:count minuuttia',
+ 'min' => '1 minuutti|:count minuuttia',
+ 'second' => '1 sekunti|:count sekuntia',
+ 's' => '1 sekunti|:count sekuntia',
+ 'ago' => ':time sitten',
+ 'from_now' => ':time tästä hetkestä',
+ 'after' => ':time sen jälkeen',
+ 'before' => ':time ennen',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/fo.php b/vendor/nesbot/carbon/src/Carbon/Lang/fo.php
new file mode 100644
index 00000000..d4d68232
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/fo.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 ár|:count ár',
+ 'y' => '1 ár|:count ár',
+ 'month' => '1 mánaður|:count mánaðir',
+ 'm' => '1 mánaður|:count mánaðir',
+ 'week' => '1 vika|:count vikur',
+ 'w' => '1 vika|:count vikur',
+ 'day' => '1 dag|:count dagar',
+ 'd' => '1 dag|:count dagar',
+ 'hour' => '1 tími|:count tímar',
+ 'h' => '1 tími|:count tímar',
+ 'minute' => '1 minutt|:count minuttir',
+ 'min' => '1 minutt|:count minuttir',
+ 'second' => '1 sekund|:count sekundir',
+ 's' => '1 sekund|:count sekundir',
+ 'ago' => ':time síðan',
+ 'from_now' => 'um :time',
+ 'after' => ':time aftaná',
+ 'before' => ':time áðrenn',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/fr.php b/vendor/nesbot/carbon/src/Carbon/Lang/fr.php
new file mode 100644
index 00000000..be79738c
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/fr.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 an|:count ans',
+ 'y' => '1 an|:count ans',
+ 'month' => ':count mois',
+ 'm' => ':count mois',
+ 'week' => '1 semaine|:count semaines',
+ 'w' => '1 semaine|:count semaines',
+ 'day' => '1 jour|:count jours',
+ 'd' => '1 jour|:count jours',
+ 'hour' => '1 heure|:count heures',
+ 'h' => '1 heure|:count heures',
+ 'minute' => '1 minute|:count minutes',
+ 'min' => '1 minute|:count minutes',
+ 'second' => '1 seconde|:count secondes',
+ 's' => '1 seconde|:count secondes',
+ 'ago' => 'il y a :time',
+ 'from_now' => 'dans :time',
+ 'after' => ':time après',
+ 'before' => ':time avant',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/gl.php b/vendor/nesbot/carbon/src/Carbon/Lang/gl.php
new file mode 100644
index 00000000..609bf752
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/gl.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 ano|:count anos',
+ 'month' => '1 mes|:count meses',
+ 'week' => '1 semana|:count semanas',
+ 'day' => '1 día|:count días',
+ 'hour' => '1 hora|:count horas',
+ 'minute' => '1 minuto|:count minutos',
+ 'second' => '1 segundo|:count segundos',
+ 'ago' => 'fai :time',
+ 'from_now' => 'dentro de :time',
+ 'after' => ':time despois',
+ 'before' => ':time antes',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/he.php b/vendor/nesbot/carbon/src/Carbon/Lang/he.php
new file mode 100644
index 00000000..2d4f4f88
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/he.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => 'שנה|{2}שנתיים|:count שנים',
+ 'y' => 'שנה|{2}שנתיים|:count שנים',
+ 'month' => 'חודש|{2}חודשיים|:count חודשים',
+ 'm' => 'חודש|{2}חודשיים|:count חודשים',
+ 'week' => 'שבוע|{2}שבועיים|:count שבועות',
+ 'w' => 'שבוע|{2}שבועיים|:count שבועות',
+ 'day' => 'יום|{2}יומיים|:count ימים',
+ 'd' => 'יום|{2}יומיים|:count ימים',
+ 'hour' => 'שעה|{2}שעתיים|:count שעות',
+ 'h' => 'שעה|{2}שעתיים|:count שעות',
+ 'minute' => 'דקה|{2}דקותיים|:count דקות',
+ 'min' => 'דקה|{2}דקותיים|:count דקות',
+ 'second' => 'שניה|:count שניות',
+ 's' => 'שניה|:count שניות',
+ 'ago' => 'לפני :time',
+ 'from_now' => 'בעוד :time',
+ 'after' => 'אחרי :time',
+ 'before' => 'לפני :time',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/hr.php b/vendor/nesbot/carbon/src/Carbon/Lang/hr.php
new file mode 100644
index 00000000..1a339de7
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/hr.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count godinu|:count godine|:count godina',
+ 'y' => ':count godinu|:count godine|:count godina',
+ 'month' => ':count mjesec|:count mjeseca|:count mjeseci',
+ 'm' => ':count mjesec|:count mjeseca|:count mjeseci',
+ 'week' => ':count tjedan|:count tjedna|:count tjedana',
+ 'w' => ':count tjedan|:count tjedna|:count tjedana',
+ 'day' => ':count dan|:count dana|:count dana',
+ 'd' => ':count dan|:count dana|:count dana',
+ 'hour' => ':count sat|:count sata|:count sati',
+ 'h' => ':count sat|:count sata|:count sati',
+ 'minute' => ':count minutu|:count minute |:count minuta',
+ 'min' => ':count minutu|:count minute |:count minuta',
+ 'second' => ':count sekundu|:count sekunde|:count sekundi',
+ 's' => ':count sekundu|:count sekunde|:count sekundi',
+ 'ago' => 'prije :time',
+ 'from_now' => 'za :time',
+ 'after' => 'za :time',
+ 'before' => 'prije :time',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/hu.php b/vendor/nesbot/carbon/src/Carbon/Lang/hu.php
new file mode 100644
index 00000000..45daf41a
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/hu.php
@@ -0,0 +1,52 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count év',
+ 'y' => ':count év',
+ 'month' => ':count hónap',
+ 'm' => ':count hónap',
+ 'week' => ':count hét',
+ 'w' => ':count hét',
+ 'day' => ':count nap',
+ 'd' => ':count nap',
+ 'hour' => ':count óra',
+ 'h' => ':count óra',
+ 'minute' => ':count perc',
+ 'min' => ':count perc',
+ 'second' => ':count másodperc',
+ 's' => ':count másodperc',
+ 'ago' => ':time',
+ 'from_now' => ':time múlva',
+ 'after' => ':time később',
+ 'before' => ':time korábban',
+ 'year_ago' => ':count éve',
+ 'month_ago' => ':count hónapja',
+ 'week_ago' => ':count hete',
+ 'day_ago' => ':count napja',
+ 'hour_ago' => ':count órája',
+ 'minute_ago' => ':count perce',
+ 'second_ago' => ':count másodperce',
+ 'year_after' => ':count évvel',
+ 'month_after' => ':count hónappal',
+ 'week_after' => ':count héttel',
+ 'day_after' => ':count nappal',
+ 'hour_after' => ':count órával',
+ 'minute_after' => ':count perccel',
+ 'second_after' => ':count másodperccel',
+ 'year_before' => ':count évvel',
+ 'month_before' => ':count hónappal',
+ 'week_before' => ':count héttel',
+ 'day_before' => ':count nappal',
+ 'hour_before' => ':count órával',
+ 'minute_before' => ':count perccel',
+ 'second_before' => ':count másodperccel',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/hy.php b/vendor/nesbot/carbon/src/Carbon/Lang/hy.php
new file mode 100644
index 00000000..4b4545d7
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/hy.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count տարի',
+ 'y' => ':count տարի',
+ 'month' => ':count ամիս',
+ 'm' => ':count ամիս',
+ 'week' => ':count շաբաթ',
+ 'w' => ':count շաբաթ',
+ 'day' => ':count օր',
+ 'd' => ':count օր',
+ 'hour' => ':count ժամ',
+ 'h' => ':count ժամ',
+ 'minute' => ':count րոպե',
+ 'min' => ':count րոպե',
+ 'second' => ':count վայրկյան',
+ 's' => ':count վայրկյան',
+ 'ago' => ':time առաջ',
+ 'from_now' => ':time հետո',
+ 'after' => ':time հետո',
+ 'before' => ':time առաջ',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/id.php b/vendor/nesbot/carbon/src/Carbon/Lang/id.php
new file mode 100644
index 00000000..7f7114fa
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/id.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count tahun',
+ 'y' => ':count tahun',
+ 'month' => ':count bulan',
+ 'm' => ':count bulan',
+ 'week' => ':count minggu',
+ 'w' => ':count minggu',
+ 'day' => ':count hari',
+ 'd' => ':count hari',
+ 'hour' => ':count jam',
+ 'h' => ':count jam',
+ 'minute' => ':count menit',
+ 'min' => ':count menit',
+ 'second' => ':count detik',
+ 's' => ':count detik',
+ 'ago' => ':time yang lalu',
+ 'from_now' => ':time dari sekarang',
+ 'after' => ':time setelah',
+ 'before' => ':time sebelum',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/it.php b/vendor/nesbot/carbon/src/Carbon/Lang/it.php
new file mode 100644
index 00000000..19eedafa
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/it.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 anno|:count anni',
+ 'y' => '1 anno|:count anni',
+ 'month' => '1 mese|:count mesi',
+ 'm' => '1 mese|:count mesi',
+ 'week' => '1 settimana|:count settimane',
+ 'w' => '1 settimana|:count settimane',
+ 'day' => '1 giorno|:count giorni',
+ 'd' => '1 giorno|:count giorni',
+ 'hour' => '1 ora|:count ore',
+ 'h' => '1 ora|:count ore',
+ 'minute' => '1 minuto|:count minuti',
+ 'min' => '1 minuto|:count minuti',
+ 'second' => '1 secondo|:count secondi',
+ 's' => '1 secondo|:count secondi',
+ 'ago' => ':time fa',
+ 'from_now' => ':time da adesso',
+ 'after' => ':time dopo',
+ 'before' => ':time prima',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ja.php b/vendor/nesbot/carbon/src/Carbon/Lang/ja.php
new file mode 100644
index 00000000..c12c1994
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/ja.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count 年',
+ 'y' => ':count 年',
+ 'month' => ':count ヶ月',
+ 'm' => ':count ヶ月',
+ 'week' => ':count 週間',
+ 'w' => ':count 週間',
+ 'day' => ':count 日',
+ 'd' => ':count 日',
+ 'hour' => ':count 時間',
+ 'h' => ':count 時間',
+ 'minute' => ':count 分',
+ 'min' => ':count 分',
+ 'second' => ':count 秒',
+ 's' => ':count 秒',
+ 'ago' => ':time 前',
+ 'from_now' => '今から :time',
+ 'after' => ':time 後',
+ 'before' => ':time 前',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ka.php b/vendor/nesbot/carbon/src/Carbon/Lang/ka.php
new file mode 100644
index 00000000..a8dde7eb
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/ka.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count წლის',
+ 'y' => ':count წლის',
+ 'month' => ':count თვის',
+ 'm' => ':count თვის',
+ 'week' => ':count კვირის',
+ 'w' => ':count კვირის',
+ 'day' => ':count დღის',
+ 'd' => ':count დღის',
+ 'hour' => ':count საათის',
+ 'h' => ':count საათის',
+ 'minute' => ':count წუთის',
+ 'min' => ':count წუთის',
+ 'second' => ':count წამის',
+ 's' => ':count წამის',
+ 'ago' => ':time უკან',
+ 'from_now' => ':time შემდეგ',
+ 'after' => ':time შემდეგ',
+ 'before' => ':time უკან',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/km.php b/vendor/nesbot/carbon/src/Carbon/Lang/km.php
new file mode 100644
index 00000000..a104e06e
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/km.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count ឆ្នាំ',
+ 'y' => ':count ឆ្នាំ',
+ 'month' => ':count ខែ',
+ 'm' => ':count ខែ',
+ 'week' => ':count សប្ដាហ៍',
+ 'w' => ':count សប្ដាហ៍',
+ 'day' => ':count ថ្ងៃ',
+ 'd' => ':count ថ្ងៃ',
+ 'hour' => ':count ម៉ោង',
+ 'h' => ':count ម៉ោង',
+ 'minute' => ':count នាទី',
+ 'min' => ':count នាទី',
+ 'second' => ':count វិនាទី',
+ 's' => ':count វិនាទី',
+ 'ago' => ':timeមុន',
+ 'from_now' => ':timeពីឥឡូវ',
+ 'after' => 'នៅក្រោយ :time',
+ 'before' => 'នៅមុន :time',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ko.php b/vendor/nesbot/carbon/src/Carbon/Lang/ko.php
new file mode 100644
index 00000000..9eac8c9f
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/ko.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count 년',
+ 'y' => ':count 년',
+ 'month' => ':count 개월',
+ 'm' => ':count 개월',
+ 'week' => ':count 주일',
+ 'w' => ':count 주일',
+ 'day' => ':count 일',
+ 'd' => ':count 일',
+ 'hour' => ':count 시간',
+ 'h' => ':count 시간',
+ 'minute' => ':count 분',
+ 'min' => ':count 분',
+ 'second' => ':count 초',
+ 's' => ':count 초',
+ 'ago' => ':time 전',
+ 'from_now' => ':time 후',
+ 'after' => ':time 뒤',
+ 'before' => ':time 앞',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/lt.php b/vendor/nesbot/carbon/src/Carbon/Lang/lt.php
new file mode 100644
index 00000000..3f2fd1ec
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/lt.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count metus|:count metus|:count metų',
+ 'y' => ':count metus|:count metus|:count metų',
+ 'month' => ':count mėnesį|:count mėnesius|:count mėnesių',
+ 'm' => ':count mėnesį|:count mėnesius|:count mėnesių',
+ 'week' => ':count savaitę|:count savaites|:count savaičių',
+ 'w' => ':count savaitę|:count savaites|:count savaičių',
+ 'day' => ':count dieną|:count dienas|:count dienų',
+ 'd' => ':count dieną|:count dienas|:count dienų',
+ 'hour' => ':count valandą|:count valandas|:count valandų',
+ 'h' => ':count valandą|:count valandas|:count valandų',
+ 'minute' => ':count minutę|:count minutes|:count minučių',
+ 'min' => ':count minutę|:count minutes|:count minučių',
+ 'second' => ':count sekundę|:count sekundes|:count sekundžių',
+ 's' => ':count sekundę|:count sekundes|:count sekundžių',
+ 'second_from_now' => ':count sekundės|:count sekundžių|:count sekundžių',
+ 'minute_from_now' => ':count minutės|:count minučių|:count minučių',
+ 'hour_from_now' => ':count valandos|:count valandų|:count valandų',
+ 'day_from_now' => ':count dienos|:count dienų|:count dienų',
+ 'week_from_now' => ':count savaitės|:count savaičių|:count savaičių',
+ 'month_from_now' => ':count mėnesio|:count mėnesių|:count mėnesių',
+ 'year_from_now' => ':count metų',
+ 'ago' => 'prieš :time',
+ 'from_now' => 'už :time',
+ 'after' => 'po :time',
+ 'before' => ':time nuo dabar',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/lv.php b/vendor/nesbot/carbon/src/Carbon/Lang/lv.php
new file mode 100644
index 00000000..363193db
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/lv.php
@@ -0,0 +1,47 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '0 gadiem|:count gada|:count gadiem',
+ 'y' => '0 gadiem|:count gada|:count gadiem',
+ 'month' => '0 mēnešiem|:count mēneša|:count mēnešiem',
+ 'm' => '0 mēnešiem|:count mēneša|:count mēnešiem',
+ 'week' => '0 nedēļām|:count nedēļas|:count nedēļām',
+ 'w' => '0 nedēļām|:count nedēļas|:count nedēļām',
+ 'day' => '0 dienām|:count dienas|:count dienām',
+ 'd' => '0 dienām|:count dienas|:count dienām',
+ 'hour' => '0 stundām|:count stundas|:count stundām',
+ 'h' => '0 stundām|:count stundas|:count stundām',
+ 'minute' => '0 minūtēm|:count minūtes|:count minūtēm',
+ 'min' => '0 minūtēm|:count minūtes|:count minūtēm',
+ 'second' => '0 sekundēm|:count sekundes|:count sekundēm',
+ 's' => '0 sekundēm|:count sekundes|:count sekundēm',
+ 'ago' => 'pirms :time',
+ 'from_now' => 'pēc :time',
+ 'after' => ':time vēlāk',
+ 'before' => ':time pirms',
+
+ 'year_after' => '0 gadus|:count gadu|:count gadus',
+ 'month_after' => '0 mēnešus|:count mēnesi|:count mēnešus',
+ 'week_after' => '0 nedēļas|:count nedēļu|:count nedēļas',
+ 'day_after' => '0 dienas|:count dienu|:count dienas',
+ 'hour_after' => '0 stundas|:count stundu|:count stundas',
+ 'minute_after' => '0 minūtes|:count minūti|:count minūtes',
+ 'second_after' => '0 sekundes|:count sekundi|:count sekundes',
+
+ 'year_before' => '0 gadus|:count gadu|:count gadus',
+ 'month_before' => '0 mēnešus|:count mēnesi|:count mēnešus',
+ 'week_before' => '0 nedēļas|:count nedēļu|:count nedēļas',
+ 'day_before' => '0 dienas|:count dienu|:count dienas',
+ 'hour_before' => '0 stundas|:count stundu|:count stundas',
+ 'minute_before' => '0 minūtes|:count minūti|:count minūtes',
+ 'second_before' => '0 sekundes|:count sekundi|:count sekundes',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/mk.php b/vendor/nesbot/carbon/src/Carbon/Lang/mk.php
new file mode 100644
index 00000000..51e661d6
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/mk.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 година|:count години',
+ 'month' => '1 месец|:count месеци',
+ 'week' => '1 седмица|:count седмици',
+ 'day' => '1 ден|:count дена',
+ 'hour' => '1 час|:count часа',
+ 'minute' => '1 минута|:count минути',
+ 'second' => '1 секунда|:count секунди',
+ 'ago' => 'пред :time',
+ 'from_now' => ':time од сега',
+ 'after' => 'по :time',
+ 'before' => 'пред :time',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ms.php b/vendor/nesbot/carbon/src/Carbon/Lang/ms.php
new file mode 100644
index 00000000..ef574228
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/ms.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count tahun',
+ 'y' => ':count tahun',
+ 'month' => ':count bulan',
+ 'm' => ':count bulan',
+ 'week' => ':count minggu',
+ 'w' => ':count minggu',
+ 'day' => ':count hari',
+ 'd' => ':count hari',
+ 'hour' => ':count jam',
+ 'h' => ':count jam',
+ 'minute' => ':count minit',
+ 'min' => ':count minit',
+ 'second' => ':count saat',
+ 's' => ':count saat',
+ 'ago' => ':time yang lalu',
+ 'from_now' => ':time dari sekarang',
+ 'after' => ':time selepas',
+ 'before' => ':time sebelum',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/nl.php b/vendor/nesbot/carbon/src/Carbon/Lang/nl.php
new file mode 100644
index 00000000..a398ca9d
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/nl.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count jaar',
+ 'y' => ':count jaar',
+ 'month' => '1 maand|:count maanden',
+ 'm' => '1 maand|:count maanden',
+ 'week' => '1 week|:count weken',
+ 'w' => '1 week|:count weken',
+ 'day' => '1 dag|:count dagen',
+ 'd' => '1 dag|:count dagen',
+ 'hour' => ':count uur',
+ 'h' => ':count uur',
+ 'minute' => '1 minuut|:count minuten',
+ 'min' => '1 minuut|:count minuten',
+ 'second' => '1 seconde|:count seconden',
+ 's' => '1 seconde|:count seconden',
+ 'ago' => ':time geleden',
+ 'from_now' => 'over :time',
+ 'after' => ':time later',
+ 'before' => ':time eerder',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/no.php b/vendor/nesbot/carbon/src/Carbon/Lang/no.php
new file mode 100644
index 00000000..178fbdcd
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/no.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 år|:count år',
+ 'y' => '1 år|:count år',
+ 'month' => '1 måned|:count måneder',
+ 'm' => '1 måned|:count måneder',
+ 'week' => '1 uke|:count uker',
+ 'w' => '1 uke|:count uker',
+ 'day' => '1 dag|:count dager',
+ 'd' => '1 dag|:count dager',
+ 'hour' => '1 time|:count timer',
+ 'h' => '1 time|:count timer',
+ 'minute' => '1 minutt|:count minutter',
+ 'min' => '1 minutt|:count minutter',
+ 'second' => '1 sekund|:count sekunder',
+ 's' => '1 sekund|:count sekunder',
+ 'ago' => ':time siden',
+ 'from_now' => 'om :time',
+ 'after' => ':time etter',
+ 'before' => ':time før',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/pl.php b/vendor/nesbot/carbon/src/Carbon/Lang/pl.php
new file mode 100644
index 00000000..bca2d7fb
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/pl.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 rok|:count lata|:count lat',
+ 'y' => '1 rok|:count lata|:count lat',
+ 'month' => '1 miesiąc|:count miesiące|:count miesięcy',
+ 'm' => '1 miesiąc|:count miesiące|:count miesięcy',
+ 'week' => '1 tydzień|:count tygodnie|:count tygodni',
+ 'w' => '1 tydzień|:count tygodnie|:count tygodni',
+ 'day' => '1 dzień|:count dni|:count dni',
+ 'd' => '1 dzień|:count dni|:count dni',
+ 'hour' => '1 godzina|:count godziny|:count godzin',
+ 'h' => '1 godzina|:count godziny|:count godzin',
+ 'minute' => '1 minuta|:count minuty|:count minut',
+ 'min' => '1 minuta|:count minuty|:count minut',
+ 'second' => '1 sekunda|:count sekundy|:count sekund',
+ 's' => '1 sekunda|:count sekundy|:count sekund',
+ 'ago' => ':time temu',
+ 'from_now' => ':time od teraz',
+ 'after' => ':time przed',
+ 'before' => ':time po',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/pt.php b/vendor/nesbot/carbon/src/Carbon/Lang/pt.php
new file mode 100644
index 00000000..f1706487
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/pt.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 ano|:count anos',
+ 'y' => '1 ano|:count anos',
+ 'month' => '1 mês|:count meses',
+ 'm' => '1 mês|:count meses',
+ 'week' => '1 semana|:count semanas',
+ 'w' => '1 semana|:count semanas',
+ 'day' => '1 dia|:count dias',
+ 'd' => '1 dia|:count dias',
+ 'hour' => '1 hora|:count horas',
+ 'h' => '1 hora|:count horas',
+ 'minute' => '1 minuto|:count minutos',
+ 'min' => '1 minuto|:count minutos',
+ 'second' => '1 segundo|:count segundos',
+ 's' => '1 segundo|:count segundos',
+ 'ago' => ':time atrás',
+ 'from_now' => 'em :time',
+ 'after' => ':time depois',
+ 'before' => ':time antes',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/pt_BR.php b/vendor/nesbot/carbon/src/Carbon/Lang/pt_BR.php
new file mode 100644
index 00000000..f9cbdc7a
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/pt_BR.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 ano|:count anos',
+ 'y' => '1 ano|:count anos',
+ 'month' => '1 mês|:count meses',
+ 'm' => '1 mês|:count meses',
+ 'week' => '1 semana|:count semanas',
+ 'w' => '1 semana|:count semanas',
+ 'day' => '1 dia|:count dias',
+ 'd' => '1 dia|:count dias',
+ 'hour' => '1 hora|:count horas',
+ 'h' => '1 hora|:count horas',
+ 'minute' => '1 minuto|:count minutos',
+ 'min' => '1 minuto|:count minutos',
+ 'second' => '1 segundo|:count segundos',
+ 's' => '1 segundo|:count segundos',
+ 'ago' => 'há :time',
+ 'from_now' => 'em :time',
+ 'after' => 'após :time',
+ 'before' => ':time atrás',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ro.php b/vendor/nesbot/carbon/src/Carbon/Lang/ro.php
new file mode 100644
index 00000000..cc167240
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/ro.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => 'un an|:count ani|:count ani',
+ 'y' => 'un an|:count ani|:count ani',
+ 'month' => 'o lună|:count luni|:count luni',
+ 'm' => 'o lună|:count luni|:count luni',
+ 'week' => 'o săptămână|:count săptămâni|:count săptămâni',
+ 'w' => 'o săptămână|:count săptămâni|:count săptămâni',
+ 'day' => 'o zi|:count zile|:count zile',
+ 'd' => 'o zi|:count zile|:count zile',
+ 'hour' => 'o oră|:count ore|:count ore',
+ 'h' => 'o oră|:count ore|:count ore',
+ 'minute' => 'un minut|:count minute|:count minute',
+ 'min' => 'un minut|:count minute|:count minute',
+ 'second' => 'o secundă|:count secunde|:count secunde',
+ 's' => 'o secundă|:count secunde|:count secunde',
+ 'ago' => 'acum :time',
+ 'from_now' => ':time de acum',
+ 'after' => 'peste :time',
+ 'before' => 'acum :time',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ru.php b/vendor/nesbot/carbon/src/Carbon/Lang/ru.php
new file mode 100644
index 00000000..680cbdcb
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/ru.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count год|:count года|:count лет',
+ 'y' => ':count год|:count года|:count лет',
+ 'month' => ':count месяц|:count месяца|:count месяцев',
+ 'm' => ':count месяц|:count месяца|:count месяцев',
+ 'week' => ':count неделю|:count недели|:count недель',
+ 'w' => ':count неделю|:count недели|:count недель',
+ 'day' => ':count день|:count дня|:count дней',
+ 'd' => ':count день|:count дня|:count дней',
+ 'hour' => ':count час|:count часа|:count часов',
+ 'h' => ':count час|:count часа|:count часов',
+ 'minute' => ':count минуту|:count минуты|:count минут',
+ 'min' => ':count минуту|:count минуты|:count минут',
+ 'second' => ':count секунду|:count секунды|:count секунд',
+ 's' => ':count секунду|:count секунды|:count секунд',
+ 'ago' => ':time назад',
+ 'from_now' => 'через :time',
+ 'after' => ':time после',
+ 'before' => ':time до',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sk.php b/vendor/nesbot/carbon/src/Carbon/Lang/sk.php
new file mode 100644
index 00000000..45c8f76d
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/sk.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => 'rok|:count roky|:count rokov',
+ 'y' => 'rok|:count roky|:count rokov',
+ 'month' => 'mesiac|:count mesiace|:count mesiacov',
+ 'm' => 'mesiac|:count mesiace|:count mesiacov',
+ 'week' => 'týždeň|:count týždne|:count týždňov',
+ 'w' => 'týždeň|:count týždne|:count týždňov',
+ 'day' => 'deň|:count dni|:count dní',
+ 'd' => 'deň|:count dni|:count dní',
+ 'hour' => 'hodinu|:count hodiny|:count hodín',
+ 'h' => 'hodinu|:count hodiny|:count hodín',
+ 'minute' => 'minútu|:count minúty|:count minút',
+ 'min' => 'minútu|:count minúty|:count minút',
+ 'second' => 'sekundu|:count sekundy|:count sekúnd',
+ 's' => 'sekundu|:count sekundy|:count sekúnd',
+ 'ago' => 'pred :time',
+ 'from_now' => 'za :time',
+ 'after' => ':time neskôr',
+ 'before' => ':time predtým',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sl.php b/vendor/nesbot/carbon/src/Carbon/Lang/sl.php
new file mode 100644
index 00000000..fcef085e
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/sl.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count leto|:count leti|:count leta|:count let',
+ 'y' => ':count leto|:count leti|:count leta|:count let',
+ 'month' => ':count mesec|:count meseca|:count mesece|:count mesecev',
+ 'm' => ':count mesec|:count meseca|:count mesece|:count mesecev',
+ 'week' => ':count teden|:count tedna|:count tedne|:count tednov',
+ 'w' => ':count teden|:count tedna|:count tedne|:count tednov',
+ 'day' => ':count dan|:count dni|:count dni|:count dni',
+ 'd' => ':count dan|:count dni|:count dni|:count dni',
+ 'hour' => ':count uro|:count uri|:count ure|:count ur',
+ 'h' => ':count uro|:count uri|:count ure|:count ur',
+ 'minute' => ':count minuto|:count minuti|:count minute|:count minut',
+ 'min' => ':count minuto|:count minuti|:count minute|:count minut',
+ 'second' => ':count sekundo|:count sekundi|:count sekunde|:count sekund',
+ 's' => ':count sekundo|:count sekundi|:count sekunde|:count sekund',
+ 'year_ago' => ':count letom|:count leti|:count leti|:count leti',
+ 'month_ago' => ':count mesecem|:count meseci|:count meseci|:count meseci',
+ 'week_ago' => ':count tednom|:count tednoma|:count tedni|:count tedni',
+ 'day_ago' => ':count dnem|:count dnevoma|:count dnevi|:count dnevi',
+ 'hour_ago' => ':count uro|:count urama|:count urami|:count urami',
+ 'minute_ago' => ':count minuto|:count minutama|:count minutami|:count minutami',
+ 'second_ago' => ':count sekundo|:count sekundama|:count sekundami|:count sekundami',
+ 'ago' => 'pred :time',
+ 'from_now' => 'čez :time',
+ 'after' => 'čez :time',
+ 'before' => 'pred :time',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sq.php b/vendor/nesbot/carbon/src/Carbon/Lang/sq.php
new file mode 100644
index 00000000..41be2513
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/sq.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 vit|:count vjet',
+ 'y' => '1 vit|:count vjet',
+ 'month' => '1 muaj|:count muaj',
+ 'm' => '1 muaj|:count muaj',
+ 'week' => '1 javë|:count javë',
+ 'w' => '1 javë|:count javë',
+ 'day' => '1 ditë|:count ditë',
+ 'd' => '1 ditë|:count ditë',
+ 'hour' => '1 orë|:count orë',
+ 'h' => '1 orë|:count orë',
+ 'minute' => '1 minutë|:count minuta',
+ 'min' => '1 minutë|:count minuta',
+ 'second' => '1 sekondë|:count sekonda',
+ 's' => '1 sekondë|:count sekonda',
+ 'ago' => ':time më parë',
+ 'from_now' => ':time nga tani',
+ 'after' => ':time pas',
+ 'before' => ':time para',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sr.php b/vendor/nesbot/carbon/src/Carbon/Lang/sr.php
new file mode 100644
index 00000000..70915a27
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/sr.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count godina|:count godine|:count godina',
+ 'y' => ':count godina|:count godine|:count godina',
+ 'month' => ':count mesec|:count meseca|:count meseci',
+ 'm' => ':count mesec|:count meseca|:count meseci',
+ 'week' => ':count nedelja|:count nedelje|:count nedelja',
+ 'w' => ':count nedelja|:count nedelje|:count nedelja',
+ 'day' => ':count dan|:count dana|:count dana',
+ 'd' => ':count dan|:count dana|:count dana',
+ 'hour' => ':count sat|:count sata|:count sati',
+ 'h' => ':count sat|:count sata|:count sati',
+ 'minute' => ':count minut|:count minuta |:count minuta',
+ 'min' => ':count minut|:count minuta |:count minuta',
+ 'second' => ':count sekund|:count sekunde|:count sekunde',
+ 's' => ':count sekund|:count sekunde|:count sekunde',
+ 'ago' => 'pre :time',
+ 'from_now' => ':time od sada',
+ 'after' => 'nakon :time',
+ 'before' => 'pre :time',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sr_Cyrl_ME.php b/vendor/nesbot/carbon/src/Carbon/Lang/sr_Cyrl_ME.php
new file mode 100644
index 00000000..9b67838a
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/sr_Cyrl_ME.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count године|[0,Inf[ :count година',
+ 'y' => ':count г.',
+ 'month' => '{1} :count мјесец|{2,3,4}:count мјесеца|[5,Inf[ :count мјесеци',
+ 'm' => ':count мј.',
+ 'week' => '{1} :count недјеља|{2,3,4}:count недјеље|[5,Inf[ :count недјеља',
+ 'w' => ':count нед.',
+ 'day' => '{1,21,31} :count дан|[2,Inf[ :count дана',
+ 'd' => ':count д.',
+ 'hour' => '{1,21} :count сат|{2,3,4,22,23,24}:count сата|[5,Inf[ :count сати',
+ 'h' => ':count ч.',
+ 'minute' => '{1,21,31,41,51} :count минут|[2,Inf[ :count минута',
+ 'min' => ':count мин.',
+ 'second' => '{1,21,31,41,51} :count секунд|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count секунде|[5,Inf[:count секунди',
+ 's' => ':count сек.',
+ 'ago' => 'прије :time',
+ 'from_now' => 'за :time',
+ 'after' => ':time након',
+ 'before' => ':time прије',
+
+ 'year_from_now' => '{1,21,31,41,51} :count годину|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count године|[5,Inf[ :count година',
+ 'year_ago' => '{1,21,31,41,51} :count годину|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count године|[5,Inf[ :count година',
+
+ 'week_from_now' => '{1} :count недјељу|{2,3,4} :count недјеље|[5,Inf[ :count недјеља',
+ 'week_ago' => '{1} :count недјељу|{2,3,4} :count недјеље|[5,Inf[ :count недјеља',
+
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sr_Latn_ME.php b/vendor/nesbot/carbon/src/Carbon/Lang/sr_Latn_ME.php
new file mode 100644
index 00000000..d0aaee37
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/sr_Latn_ME.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count godine|[0,Inf[ :count godina',
+ 'y' => ':count g.',
+ 'month' => '{1} :count mjesec|{2,3,4}:count mjeseca|[5,Inf[ :count mjeseci',
+ 'm' => ':count mj.',
+ 'week' => '{1} :count nedjelja|{2,3,4}:count nedjelje|[5,Inf[ :count nedjelja',
+ 'w' => ':count ned.',
+ 'day' => '{1,21,31} :count dan|[2,Inf[ :count dana',
+ 'd' => ':count d.',
+ 'hour' => '{1,21} :count sat|{2,3,4,22,23,24}:count sata|[5,Inf[ :count sati',
+ 'h' => ':count č.',
+ 'minute' => '{1,21,31,41,51} :count minut|[2,Inf[ :count minuta',
+ 'min' => ':count min.',
+ 'second' => '{1,21,31,41,51} :count sekund|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count sekunde|[5,Inf[:count sekundi',
+ 's' => ':count sek.',
+ 'ago' => 'prije :time',
+ 'from_now' => 'za :time',
+ 'after' => ':time nakon',
+ 'before' => ':time prije',
+
+ 'year_from_now' => '{1,21,31,41,51} :count godinu|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count godine|[5,Inf[ :count godina',
+ 'year_ago' => '{1,21,31,41,51} :count godinu|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count godine|[5,Inf[ :count godina',
+
+ 'week_from_now' => '{1} :count nedjelju|{2,3,4} :count nedjelje|[5,Inf[ :count nedjelja',
+ 'week_ago' => '{1} :count nedjelju|{2,3,4} :count nedjelje|[5,Inf[ :count nedjelja',
+
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sr_ME.php b/vendor/nesbot/carbon/src/Carbon/Lang/sr_ME.php
new file mode 100644
index 00000000..d0aaee37
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/sr_ME.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count godine|[0,Inf[ :count godina',
+ 'y' => ':count g.',
+ 'month' => '{1} :count mjesec|{2,3,4}:count mjeseca|[5,Inf[ :count mjeseci',
+ 'm' => ':count mj.',
+ 'week' => '{1} :count nedjelja|{2,3,4}:count nedjelje|[5,Inf[ :count nedjelja',
+ 'w' => ':count ned.',
+ 'day' => '{1,21,31} :count dan|[2,Inf[ :count dana',
+ 'd' => ':count d.',
+ 'hour' => '{1,21} :count sat|{2,3,4,22,23,24}:count sata|[5,Inf[ :count sati',
+ 'h' => ':count č.',
+ 'minute' => '{1,21,31,41,51} :count minut|[2,Inf[ :count minuta',
+ 'min' => ':count min.',
+ 'second' => '{1,21,31,41,51} :count sekund|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count sekunde|[5,Inf[:count sekundi',
+ 's' => ':count sek.',
+ 'ago' => 'prije :time',
+ 'from_now' => 'za :time',
+ 'after' => ':time nakon',
+ 'before' => ':time prije',
+
+ 'year_from_now' => '{1,21,31,41,51} :count godinu|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count godine|[5,Inf[ :count godina',
+ 'year_ago' => '{1,21,31,41,51} :count godinu|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count godine|[5,Inf[ :count godina',
+
+ 'week_from_now' => '{1} :count nedjelju|{2,3,4} :count nedjelje|[5,Inf[ :count nedjelja',
+ 'week_ago' => '{1} :count nedjelju|{2,3,4} :count nedjelje|[5,Inf[ :count nedjelja',
+
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sv.php b/vendor/nesbot/carbon/src/Carbon/Lang/sv.php
new file mode 100644
index 00000000..6bebf7b8
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/sv.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 år|:count år',
+ 'y' => '1 år|:count år',
+ 'month' => '1 månad|:count månader',
+ 'm' => '1 månad|:count månader',
+ 'week' => '1 vecka|:count veckor',
+ 'w' => '1 vecka|:count veckor',
+ 'day' => '1 dag|:count dagar',
+ 'd' => '1 dag|:count dagar',
+ 'hour' => '1 timme|:count timmar',
+ 'h' => '1 timme|:count timmar',
+ 'minute' => '1 minut|:count minuter',
+ 'min' => '1 minut|:count minuter',
+ 'second' => '1 sekund|:count sekunder',
+ 's' => '1 sekund|:count sekunder',
+ 'ago' => ':time sedan',
+ 'from_now' => 'om :time',
+ 'after' => ':time efter',
+ 'before' => ':time före',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/th.php b/vendor/nesbot/carbon/src/Carbon/Lang/th.php
new file mode 100644
index 00000000..c4c402ef
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/th.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => '1 ปี|:count ปี',
+ 'y' => '1 ปี|:count ปี',
+ 'month' => '1 เดือน|:count เดือน',
+ 'm' => '1 เดือน|:count เดือน',
+ 'week' => '1 สัปดาห์|:count สัปดาห์',
+ 'w' => '1 สัปดาห์|:count สัปดาห์',
+ 'day' => '1 วัน|:count วัน',
+ 'd' => '1 วัน|:count วัน',
+ 'hour' => '1 ชั่วโมง|:count ชั่วโมง',
+ 'h' => '1 ชั่วโมง|:count ชั่วโมง',
+ 'minute' => '1 นาที|:count นาที',
+ 'min' => '1 นาที|:count นาที',
+ 'second' => '1 วินาที|:count วินาที',
+ 's' => '1 วินาที|:count วินาที',
+ 'ago' => ':time ที่แล้ว',
+ 'from_now' => ':time จากนี้',
+ 'after' => 'หลัง:time',
+ 'before' => 'ก่อน:time',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/tr.php b/vendor/nesbot/carbon/src/Carbon/Lang/tr.php
new file mode 100644
index 00000000..6a9dfed8
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/tr.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count yıl',
+ 'y' => ':count yıl',
+ 'month' => ':count ay',
+ 'm' => ':count ay',
+ 'week' => ':count hafta',
+ 'w' => ':count hafta',
+ 'day' => ':count gün',
+ 'd' => ':count gün',
+ 'hour' => ':count saat',
+ 'h' => ':count saat',
+ 'minute' => ':count dakika',
+ 'min' => ':count dakika',
+ 'second' => ':count saniye',
+ 's' => ':count saniye',
+ 'ago' => ':time önce',
+ 'from_now' => ':time sonra',
+ 'after' => ':time sonra',
+ 'before' => ':time önce',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/uk.php b/vendor/nesbot/carbon/src/Carbon/Lang/uk.php
new file mode 100644
index 00000000..aeebca3d
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/uk.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count рік|:count роки|:count років',
+ 'y' => ':count рік|:count роки|:count років',
+ 'month' => ':count місяць|:count місяці|:count місяців',
+ 'm' => ':count місяць|:count місяці|:count місяців',
+ 'week' => ':count тиждень|:count тижні|:count тижнів',
+ 'w' => ':count тиждень|:count тижні|:count тижнів',
+ 'day' => ':count день|:count дні|:count днів',
+ 'd' => ':count день|:count дні|:count днів',
+ 'hour' => ':count година|:count години|:count годин',
+ 'h' => ':count година|:count години|:count годин',
+ 'minute' => ':count хвилину|:count хвилини|:count хвилин',
+ 'min' => ':count хвилину|:count хвилини|:count хвилин',
+ 'second' => ':count секунду|:count секунди|:count секунд',
+ 's' => ':count секунду|:count секунди|:count секунд',
+ 'ago' => ':time назад',
+ 'from_now' => 'через :time',
+ 'after' => ':time після',
+ 'before' => ':time до',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ur.php b/vendor/nesbot/carbon/src/Carbon/Lang/ur.php
new file mode 100644
index 00000000..3c5f7ed9
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/ur.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count سال',
+ 'month' => ':count ماه',
+ 'week' => ':count ہفتے',
+ 'day' => ':count روز',
+ 'hour' => ':count گھنٹے',
+ 'minute' => ':count منٹ',
+ 'second' => ':count سیکنڈ',
+ 'ago' => ':time پہلے',
+ 'from_now' => ':time بعد',
+ 'after' => ':time بعد',
+ 'before' => ':time پہلے',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/uz.php b/vendor/nesbot/carbon/src/Carbon/Lang/uz.php
new file mode 100644
index 00000000..c997f29d
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/uz.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count yil|:count yil|:count yil',
+ 'y' => ':count yil|:count yil|:count yil',
+ 'month' => ':count oy|:count oy|:count oylar',
+ 'm' => ':count oy|:count oy|:count oylar',
+ 'week' => ':count hafta|:count hafta|:count hafta',
+ 'w' => ':count hafta|:count hafta|:count hafta',
+ 'day' => ':count kun|:count kun|:count kun',
+ 'd' => ':count kun|:count kun|:count kun',
+ 'hour' => ':count soat|:count soat|:count soat',
+ 'h' => ':count soat|:count soat|:count soat',
+ 'minute' => ':count minut|:count minut|:count minut',
+ 'min' => ':count minut|:count minut|:count minut',
+ 'second' => ':count sekund|:count sekund|:count sekund',
+ 's' => ':count sekund|:count sekund|:count sekund',
+ 'ago' => ':time avval',
+ 'from_now' => ':time keyin',
+ 'after' => ':time keyin',
+ 'before' => ':time oldin',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/vi.php b/vendor/nesbot/carbon/src/Carbon/Lang/vi.php
new file mode 100644
index 00000000..3f9838d6
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/vi.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count năm',
+ 'y' => ':count năm',
+ 'month' => ':count tháng',
+ 'm' => ':count tháng',
+ 'week' => ':count tuần',
+ 'w' => ':count tuần',
+ 'day' => ':count ngày',
+ 'd' => ':count ngày',
+ 'hour' => ':count giờ',
+ 'h' => ':count giờ',
+ 'minute' => ':count phút',
+ 'min' => ':count phút',
+ 'second' => ':count giây',
+ 's' => ':count giây',
+ 'ago' => ':time trước',
+ 'from_now' => ':time từ bây giờ',
+ 'after' => ':time sau',
+ 'before' => ':time trước',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/zh.php b/vendor/nesbot/carbon/src/Carbon/Lang/zh.php
new file mode 100644
index 00000000..9e1f6cad
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/zh.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count年',
+ 'y' => ':count年',
+ 'month' => ':count个月',
+ 'm' => ':count个月',
+ 'week' => ':count周',
+ 'w' => ':count周',
+ 'day' => ':count天',
+ 'd' => ':count天',
+ 'hour' => ':count小时',
+ 'h' => ':count小时',
+ 'minute' => ':count分钟',
+ 'min' => ':count分钟',
+ 'second' => ':count秒',
+ 's' => ':count秒',
+ 'ago' => ':time前',
+ 'from_now' => '距现在:time',
+ 'after' => ':time后',
+ 'before' => ':time前',
+);
diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/zh_TW.php b/vendor/nesbot/carbon/src/Carbon/Lang/zh_TW.php
new file mode 100644
index 00000000..6c1d417f
--- /dev/null
+++ b/vendor/nesbot/carbon/src/Carbon/Lang/zh_TW.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return array(
+ 'year' => ':count 年',
+ 'y' => ':count 年',
+ 'month' => ':count 月',
+ 'm' => ':count 月',
+ 'week' => ':count 周',
+ 'w' => ':count 周',
+ 'day' => ':count 天',
+ 'd' => ':count 天',
+ 'hour' => ':count 小時',
+ 'h' => ':count 小時',
+ 'minute' => ':count 分鐘',
+ 'min' => ':count 分鐘',
+ 'second' => ':count 秒',
+ 's' => ':count 秒',
+ 'ago' => ':time前',
+ 'from_now' => '距現在 :time',
+ 'after' => ':time後',
+ 'before' => ':time前',
+);
diff --git a/vendor/paragonie/random_compat/CHANGELOG.md b/vendor/paragonie/random_compat/CHANGELOG.md
new file mode 100644
index 00000000..f8f01b7f
--- /dev/null
+++ b/vendor/paragonie/random_compat/CHANGELOG.md
@@ -0,0 +1,282 @@
+### Version 1.4.2 - 2017-03-13
+
+* Backport changes from version 2:
+ * Version 2.0.9 - 2017-03-03
+ * More Psalm integration fixes.
+ * Version 2.0.8 - 2017-03-03
+ * Prevent function already declared error for `random_int()` caused by misusing
+ the library (really you should only ever include `lib/random.php` and never any
+ of the other files). See [#125](https://github.com/paragonie/random_compat/issues/125).
+ * Version 2.0.6, 2.0.7 - 2017-02-27
+ * Just updates to psalm.xml to silence false positives.
+ * Version 2.0.5 - 2017-02-27
+ * Run random_compat through the static analysis tool, [psalm](https://github.com/vimeo/psalm),
+ as part of our continuous integration process.
+ * Minor readability enhancements ([#122](https://github.com/paragonie/random_compat/issues/122)
+ and several docblock changes).
+ * Version 2.0.4 - 2016-11-07
+ * Don't unnecessarily prevent `mcrypt_create_iv()` from being used.
+ See [#111](https://github.com/paragonie/random_compat/issues/111).
+ * Version 2.0.3 - 2016-10-17
+ * Updated `lib/error_polyfill.php` [to resolve corner cases](https://github.com/paragonie/random_compat/issues/104).
+ * The README was updated to help users troubleshoot and fix insecure environments.
+ * Tags will now be signed by [the GnuPG key used by the security team at Paragon Initiative Enterprises, LLC](https://paragonie.com/static/gpg-public-key.txt).
+ * Version 2.0.2 - 2016-04-03
+ * Added a consistency check (discovered by Taylor Hornby in his
+ [PHP encryption library](https://github.com/defuse/php-encryption)). It
+ wasn't likely causing any trouble for us.
+
+### Version 1.4.1 - 2016-03-18
+
+Update comment in random.php
+
+### Version 1.4.0 - 2016-03-18
+
+Restored OpenSSL in the version 1 branch in preparation to remove
+OpenSSL in version 2.
+
+### Version 1.3.1/1.2.3 - 2016-03-18
+
+* Add more possible values to `open_baseir` check.
+
+### Version 1.3.0 - 2016-03-17
+
+* Removed `openssl_random_pseudo_bytes()` entirely. If you are using
+ random_compat in PHP on a Unix-like OS but cannot access
+ `/dev/urandom`, version 1.3+ will throw an `Exception`. If you want to
+ trust OpenSSL, feel free to write your own fallback code. e.g.
+
+ ```php
+ try {
+ $bytes = random_bytes(32);
+ } catch (Exception $ex) {
+ $strong = false;
+ $bytes = openssl_random_pseudo_bytes(32, $strong);
+ if (!$strong) {
+ throw $ex;
+ }
+ }
+ ```
+
+### Version 1.2.2 - 2016-03-11
+
+* To prevent applications from hanging, if `/dev/urandom` is not
+ accessible to PHP, skip mcrypt (which just fails before giving OpenSSL
+ a chance and was morally equivalent to not offering OpenSSL at all).
+
+### Version 1.2.1 - 2016-02-29
+
+* PHP 5.6.10 - 5.6.12 will hang when mcrypt is used on Unix-based operating
+ systems ([PHP bug 69833](https://bugs.php.net/bug.php?id=69833)). If you are
+ running one of these versions, please upgrade (or make sure `/dev/urandom` is
+ readable) otherwise you're relying on OpenSSL.
+
+### Version 1.2.0 - 2016-02-05
+
+* Whitespace and other cosmetic changes
+* Added a changelog.
+* We now ship with a command line utility to build a PHP Archive from the
+ command line.
+
+ Every time we publish a new release, we will also upload a .phar
+ to Github. Our public key is signed by our GPG key.
+
+### Version 1.1.6 - 2016-01-29
+
+* Eliminate `open_basedir` warnings by detecting this configuration setting.
+ (Thanks [@oucil](https://github.com/oucil) for reporting this.)
+* Added install instructions to the README.
+* Documentation cleanup (there is, in fact, no `MCRYPT_CREATE_IV` constant, I
+ meant to write `MCRYPT_DEV_URANDOM`)
+
+### Version 1.1.5 - 2016-01-06
+
+Prevent fatal errors on platforms with older versions of libsodium.
+
+### Version 1.1.4 - 2015-12-10
+
+Thanks [@narfbg](https://github.com/narfbg) for [critiquing the previous patch](https://github.com/paragonie/random_compat/issues/79#issuecomment-163590589)
+and suggesting a fix.
+
+### Version 1.1.3 - 2015-12-09
+
+The test for COM in disabled_classes is now case-insensitive.
+
+### Version 1.1.2 - 2015-12-09
+
+Don't instantiate COM if it's a disabled class. Removes the E_WARNING on Windows.
+
+### Version 1.1.1 - 2015-11-30
+
+Fix a performance issue with `/dev/urandom` buffering.
+
+### Version 1.1.0 - 2015-11-09
+
+Fix performance issues with ancient versions of PHP on Windows, but dropped
+support for PHP < 5.4.1 without mcrypt on Windows 7+ in the process. Since this
+ is a BC break, semver dictates a minor version bump.
+
+### Version 1.0.10 - 2015-10-23
+
+* Avoid a performance killer with OpenSSL on Windows PHP 5.3.0 - 5.3.3 that was
+ affecting [WordPress users](https://core.trac.wordpress.org/ticket/34409).
+* Use `$var = null` instead of `unset($var)` to avoid triggering the garbage
+ collector and slowing things down.
+
+### Version 1.0.9 - 2015-10-20
+
+There is an outstanding issue `mcrypt_create_iv()` and PHP 7's `random_bytes()`
+on Windows reported by [@nicolas-grekas](https://github.com/nicolas-grekas) caused by `proc_open()` and environment
+variable handling (discovered by Appveyor when developing Symfony).
+
+Since the break is consistent, it's not our responsibility to fix it, but we
+should fail the same way PHP 7 will (i.e. throw an `Exception` rather than raise
+an error and then throw an `Exception`).
+
+### Version 1.0.8 - 2015-10-18
+
+* Fix usability issues with Windows (`new COM('CAPICOM.Utilities.1')` is not
+ always available).
+* You can now test all the possible drivers by running `phpunit.sh each` in the
+ `tests` directory.
+
+### Version 1.0.7 - 2015-10-16
+
+Several large integer handling bugfixes were contributed by [@oittaa](https://github.com/oittaa).
+
+### Version 1.0.6 - 2015-10-15
+
+Don't let the version number fool you, this was a pretty significant change.
+
+1. Added support for ext-libsodium, if it exists on the system. This is morally
+ equivalent to adding `getrandom(2)` support without having to expose the
+ syscall interface in PHP-land.
+2. Relaxed open_basedir restrictions. In previous versions, if open_basedir was
+ set, PHP wouldn't even try to read from `/dev/urandom`. Now it will still do
+ so if you can.
+3. Fixed integer casting inconsistencies between random_compat and PHP 7.
+4. Handle edge cases where an integer overflow turns one of the parameters into
+ a float.
+
+One change that we discussed was making `random_bytes()` and `random_int()`
+strict typed; meaning you could *only* pass integers to either function. While
+most veteran programmers are probably only doing this already (we strongly
+encourage it), it wouldn't be consistent with how these functions behave in PHP
+7. Please use these functions responsibly.
+
+We've had even more of the PHP community involved in this release; the
+contributors list has been updated. If I forgot anybody, I promise you it's not
+because your contributions (either code or ideas) aren't valued, it's because
+I'm a bit overloaded with information at the moment. Please let me know
+immediately and I will correct my oversight.
+
+Thanks everyone for helping make random_compat better.
+
+### Version 1.0.5 - 2015-10-08
+
+Got rid of the methods in the `Throwable` interface, which was causing problems
+on PHP 5.2. While we would normally not care about 5.2 (since [5.4 and earlier are EOL'd](https://secure.php.net/supported-versions.php)),
+we do want to encourage widespread adoption (e.g. [Wordpress](https://core.trac.wordpress.org/ticket/28633)).
+
+### Version 1.0.4 - 2015-10-02
+
+Removed redundant `if()` checks, since `lib/random.php` is the entrypoint people
+should use.
+
+### Version 1.0.3 - 2015-10-02
+
+This release contains bug fixes contributed by the community.
+
+* Avoid a PHP Notice when PHP is running without the mbstring extension
+* Use a compatible version of PHPUnit for testing on older versions of PHP
+
+Although none of these bugs were outright security-affecting, updating ASAP is
+still strongly encouraged.
+
+### Version 1.0.2 - 2015-09-23
+
+Less strict input validation on `random_int()` parameters. PHP 7's `random_int()`
+accepts strings and floats that look like numbers, so we should too.
+
+Thanks [@dd32](https://github.com/@dd32) for correcting this oversight.
+
+### Version 1.0.1 - 2015-09-10
+
+Instead of throwing an Exception immediately on insecure platforms, only do so
+when `random_bytes()` is invoked.
+
+### Version 1.0.0 - 2015-09-07
+
+Our API is now stable and forward-compatible with the CSPRNG features in PHP 7
+(as of 7.0.0 RC3).
+
+A lot of great people have contributed their time and expertise to make this
+compatibility library possible. That this library has reached a stable release
+is more a reflection on the community than it is on PIE.
+
+We are confident that random_compat will serve as the simplest and most secure
+CSPRNG interface available for PHP5 projects.
+
+### Version 0.9.7 (pre-release) - 2015-09-01
+
+An attempt to achieve compatibility with Error/TypeError in the RFC.
+
+This should be identical to 1.0.0 sans any last-minute changes or performance enhancements.
+
+### Version 0.9.6 (pre-release) - 2015-08-06
+
+* Split the implementations into their own file (for ease of auditing)
+* Corrected the file type check after `/dev/urandom` has been opened (thanks
+ [@narfbg](https://github.com/narfbg) and [@jedisct1](https://github.com/jedisct1))
+
+### Version 0.9.5 (pre-release) - 2015-07-31
+
+* Validate that `/dev/urandom` is a character device
+ * Reported by [@lokdnet](https://twitter.com/lokdnet)
+ * Investigated by [@narfbg](https://github.com/narfbg) and [frymaster](http://stackoverflow.com/users/1226810/frymaster) on [StackOverflow](http://stackoverflow.com/q/31631066/2224584)
+* Remove support for `/dev/arandom` which is an old OpenBSD feature, thanks [@jedisct1](https://github.com/jedisct1)
+* Prevent race conditions on the `filetype()` check, thanks [@jedisct1](https://github.com/jedisct1)
+* Buffer file reads to 8 bytes (performance optimization; PHP defaults to 8192 bytes)
+
+### Version 0.9.4 (pre-release) - 2015-07-27
+
+* Add logic to verify that `/dev/arandom` and `/dev/urandom` are actually devices.
+* Some clean-up in the comments
+
+### Version 0.9.3 (pre-release) - 2015-07-22
+
+Unless the Exceptions change to PHP 7 fails, this should be the last pre-release
+version. If need be, we'll make one more pre-release version with compatible
+behavior.
+
+Changes since 0.9.2:
+
+* Prioritize `/dev/arandom` and `/dev/urandom` over mcrypt.
+[@oittaa](https://github.com/oittaa) removed the -1 and +1 juggling on `$range` calculations for `random_int()`
+* Whitespace and comment clean-up, plus better variable names
+* Actually put a description in the composer.json file...
+
+### Version 0.9.2 (pre-release) - 2015-07-16
+
+* Consolidated `$range > PHP_INT_MAX` logic with `$range <= PHP_INT_MAX` (thanks
+ [@oittaa](https://github.com/oittaa) and [@CodesInChaos](https://github.com/CodesInChaos))
+* `tests/phpunit.sh` now also runs the tests with `mbstring.func_overload` and
+ `open_basedir`
+* Style consistency, whitespace cleanup, more meaningful variable names
+
+### Version 0.9.1 (pre-release) - 2015-07-09
+
+* Return random values on integer ranges > `PHP_INT_MAX` (thanks [@CodesInChaos](https://github.com/CodesInChaos))
+* Determined CSPRNG preference:
+ 1. `mcrypt_create_iv()` with `MCRYPT_DEV_URANDOM`
+ 2. `/dev/arandom`
+ 3. `/dev/urandom`
+ 4. `openssl_random_pseudo_bytes()`
+* Optimized backend selection (thanks [@lt](https://github.com/lt))
+* Fix #3 (thanks [@scottchiefbaker](https://github.com/scottchiefbaker))
+
+### Version 0.9.0 (pre-release) - 2015-07-07
+
+This should be a sane polyfill for PHP 7's `random_bytes()` and `random_int()`.
+We hesitate to call it production ready until it has received sufficient third
+party review.
\ No newline at end of file
diff --git a/vendor/paragonie/random_compat/LICENSE b/vendor/paragonie/random_compat/LICENSE
new file mode 100644
index 00000000..45c7017d
--- /dev/null
+++ b/vendor/paragonie/random_compat/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Paragon Initiative Enterprises
+
+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/paragonie/random_compat/RATIONALE.md b/vendor/paragonie/random_compat/RATIONALE.md
new file mode 100644
index 00000000..a6e73072
--- /dev/null
+++ b/vendor/paragonie/random_compat/RATIONALE.md
@@ -0,0 +1,42 @@
+## Rationale (Design Decisions)
+
+### Reasoning Behind the Order of Preferred Random Data Sources
+
+The order is:
+
+ 1. `libsodium if available`
+ 2. `fread() /dev/urandom if available`
+ 3. `mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)`
+ 4. `COM('CAPICOM.Utilities.1')->GetRandom()`
+ 5. `openssl_random_pseudo_bytes()`
+
+If libsodium is available, we get random data from it. This is the preferred
+method on all OSes, but libsodium is not very widely installed, so other
+fallbacks are available.
+
+Next, we read `/dev/urandom` (if it exists). This is the preferred file to read
+for random data for cryptographic purposes for BSD and Linux. This step
+is skipped on Windows, because someone could create a `C:\dev\urandom`
+file and PHP would helpfully (but insecurely) return bytes from it.
+
+Despite [strongly urging people not to use mcrypt in their projects](https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-re-doing-it-wrong)
+(because libmcrypt is abandonware and the API puts too much responsibility on the
+implementor) we prioritize `mcrypt_create_iv()` with `MCRYPT_DEV_URANDOM` above
+the remaining implementations.
+
+The reason is simple: `mcrypt_create_iv()` is part of PHP's `ext/mcrypt` code,
+and is not part `libmcrypt`. It actually does the right thing:
+
+ * On Unix-based operating systems, it reads from `/dev/urandom` which
+ (unlike `/dev/random`) is the sane and correct thing to do.
+ * On Windows, it reads from `CryptGenRandom`, which is an exclusively Windows
+ way to get random bytes.
+
+If we're on Windows and don't have access to `mcrypt`, we use `CAPICOM.Utilities.1`.
+
+Finally, we use `openssl_random_pseudo_bytes()` **as a last resort**, due to
+[PHP bug #70014](https://bugs.php.net/bug.php?id=70014). Internally, this
+function calls `RAND_pseudo_bytes()`, which has been [deprecated](https://github.com/paragonie/random_compat/issues/5)
+by the OpenSSL team. Furthermore, [it might silently return weak random data](https://github.com/paragonie/random_compat/issues/6#issuecomment-119564973)
+if it is called before OpenSSL's **userspace** CSPRNG is seeded. Also,
+[you want the OS CSPRNG, not a userspace CSPRNG](http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/).
diff --git a/vendor/paragonie/random_compat/README.md b/vendor/paragonie/random_compat/README.md
new file mode 100644
index 00000000..63c6d715
--- /dev/null
+++ b/vendor/paragonie/random_compat/README.md
@@ -0,0 +1,176 @@
+# random_compat
+
+[](https://travis-ci.org/paragonie/random_compat)
+[](https://scrutinizer-ci.com/g/paragonie/random_compat)
+
+PHP 5.x polyfill for `random_bytes()` and `random_int()` created and maintained
+by [Paragon Initiative Enterprises](https://paragonie.com).
+
+Although this library *should* function in earlier versions of PHP, we will only
+consider issues relevant to [supported PHP versions](https://secure.php.net/supported-versions.php).
+**If you are using an unsupported version of PHP, please upgrade as soon as possible.**
+
+## Important
+
+Although this library has been examined by some security experts in the PHP
+community, there will always be a chance that we overlooked something. Please
+ask your favorite trusted hackers to hammer it for implementation errors and
+bugs before even thinking about deploying it in production.
+
+**Do not use the master branch, use a [stable release](https://github.com/paragonie/random_compat/releases/latest).**
+
+For the background of this library, please refer to our blog post on
+[Generating Random Integers and Strings in PHP](https://paragonie.com/blog/2015/07/how-safely-generate-random-strings-and-integers-in-php).
+
+### Usability Notice
+
+If PHP cannot safely generate random data, this library will throw an `Exception`.
+It will never fall back to insecure random data. If this keeps happening, upgrade
+to a newer version of PHP immediately.
+
+## Installing
+
+**With [Composer](https://getcomposer.org):**
+
+ composer require paragonie/random_compat
+
+**Signed PHP Archive:**
+
+As of version 1.2.0, we also ship an ECDSA-signed PHP Archive with each stable
+release on Github.
+
+1. Download [the `.phar`, `.phar.pubkey`, and `.phar.pubkey.asc`](https://github.com/paragonie/random_compat/releases/latest) files.
+2. (**Recommended** but not required) Verify the PGP signature of `.phar.pubkey`
+ (contained within the `.asc` file) using the [PGP public key for Paragon Initiative Enterprises](https://paragonie.com/static/gpg-public-key.txt).
+3. Extract both `.phar` and `.phar.pubkey` files to the same directory.
+4. `require_once "/path/to/random_compat.phar";`
+5. When a new version is released, you only need to replace the `.phar` file;
+ the `.pubkey` will not change (unless our signing key is ever compromised).
+
+**Manual Installation:**
+
+1. Download [a stable release](https://github.com/paragonie/random_compat/releases/latest).
+2. Extract the files into your project.
+3. `require_once "/path/to/random_compat/lib/random.php";`
+
+## Usage
+
+This library exposes the [CSPRNG functions added in PHP 7](https://secure.php.net/manual/en/ref.csprng.php)
+for use in PHP 5 projects. Their behavior should be identical.
+
+### Generate a string of random bytes
+
+```php
+try {
+ $string = random_bytes(32);
+} catch (TypeError $e) {
+ // Well, it's an integer, so this IS unexpected.
+ die("An unexpected error has occurred");
+} catch (Error $e) {
+ // This is also unexpected because 32 is a reasonable integer.
+ die("An unexpected error has occurred");
+} catch (Exception $e) {
+ // If you get this message, the CSPRNG failed hard.
+ die("Could not generate a random string. Is our OS secure?");
+}
+
+var_dump(bin2hex($string));
+// string(64) "5787c41ae124b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2eeac6f"
+```
+
+### Generate a random integer between two given integers (inclusive)
+
+```php
+try {
+ $int = random_int(0,255);
+
+} catch (TypeError $e) {
+ // Well, it's an integer, so this IS unexpected.
+ die("An unexpected error has occurred");
+} catch (Error $e) {
+ // This is also unexpected because 0 and 255 are both reasonable integers.
+ die("An unexpected error has occurred");
+} catch (Exception $e) {
+ // If you get this message, the CSPRNG failed hard.
+ die("Could not generate a random string. Is our OS secure?");
+}
+
+var_dump($int);
+// int(47)
+```
+
+### Exception handling
+
+When handling exceptions and errors you must account for differences between
+PHP 5 and PHP7.
+
+The differences:
+
+* Catching `Error` works, so long as it is caught before `Exception`.
+* Catching `Exception` has different behavior, without previously catching `Error`.
+* There is *no* portable way to catch all errors/exceptions.
+
+#### Our recommendation
+
+**Always** catch `Error` before `Exception`.
+
+#### Example
+
+```php
+try {
+ return random_int(1, $userInput);
+} catch (TypeError $e) {
+ // This is okay, so long as `Error` is caught before `Exception`.
+ throw new Exception('Please enter a number!');
+} catch (Error $e) {
+ // This is required, if you do not need to do anything just rethrow.
+ throw $e;
+} catch (Exception $e) {
+ // This is optional and maybe omitted if you do not want to handle errors
+ // during generation.
+ throw new InternalServerErrorException(
+ 'Oops, our server is bust and cannot generate any random data.',
+ 500,
+ $e
+ );
+}
+```
+
+## Contributors
+
+This project would not be anywhere near as excellent as it is today if it
+weren't for the contributions of the following individuals:
+
+* [@AndrewCarterUK (Andrew Carter)](https://github.com/AndrewCarterUK)
+* [@asgrim (James Titcumb)](https://github.com/asgrim)
+* [@bcremer (Benjamin Cremer)](https://github.com/bcremer)
+* [@CodesInChaos (Christian Winnerlein)](https://github.com/CodesInChaos)
+* [@chriscct7 (Chris Christoff)](https://github.com/chriscct7)
+* [@cs278 (Chris Smith)](https://github.com/cs278)
+* [@cweagans (Cameron Eagans)](https://github.com/cweagans)
+* [@dd32 (Dion Hulse)](https://github.com/dd32)
+* [@geggleto (Glenn Eggleton)](https://github.com/geggleto)
+* [@ircmaxell (Anthony Ferrara)](https://github.com/ircmaxell)
+* [@jedisct1 (Frank Denis)](https://github.com/jedisct1)
+* [@juliangut (Julián Gutiérrez)](https://github.com/juliangut)
+* [@kelunik (Niklas Keller)](https://github.com/kelunik)
+* [@lt (Leigh)](https://github.com/lt)
+* [@MasonM (Mason Malone)](https://github.com/MasonM)
+* [@mmeyer2k (Michael M)](https://github.com/mmeyer2k)
+* [@narfbg (Andrey Andreev)](https://github.com/narfbg)
+* [@nicolas-grekas (Nicolas Grekas)](https://github.com/nicolas-grekas)
+* [@oittaa](https://github.com/oittaa)
+* [@oucil (Kevin Farley)](https://github.com/oucil)
+* [@redragonx (Stephen Chavez)](https://github.com/redragonx)
+* [@rchouinard (Ryan Chouinard)](https://github.com/rchouinard)
+* [@SammyK (Sammy Kaye Powers)](https://github.com/SammyK)
+* [@scottchiefbaker (Scott Baker)](https://github.com/scottchiefbaker)
+* [@skyosev (Stoyan Kyosev)](https://github.com/skyosev)
+* [@stof (Christophe Coevoet)](https://github.com/stof)
+* [@teohhanhui (Teoh Han Hui)](https://github.com/teohhanhui)
+* [@tom-- (Tom Worster)](https://github.com/tom--)
+* [@tsyr2ko](https://github.com/tsyr2ko)
+* [@trowski (Aaron Piotrowski)](https://github.com/trowski)
+* [@twistor (Chris Lepannen)](https://github.com/twistor)
+* [@voku (Lars Moelleken)](https://github.com/voku)
+* [@xabbuh (Christian Flothmann)](https://github.com/xabbuh)
diff --git a/vendor/paragonie/random_compat/SECURITY.md b/vendor/paragonie/random_compat/SECURITY.md
new file mode 100644
index 00000000..8f731b38
--- /dev/null
+++ b/vendor/paragonie/random_compat/SECURITY.md
@@ -0,0 +1,108 @@
+# An Invitation to Security Researchers
+
+Every company says they take security "very seriously." Rather than bore anyone
+with banal boilerplate, here are some quick answers followed by detailed
+elaboration. If you have any questions about our policies, please email them to
+`scott@paragonie.com`.
+
+## Quick Answers
+
+* There is no compulsion to disclose vulnerabilities privately, but we
+ appreciate a head's up.
+* `security@paragonie.com` will get your reports to the right person. Our GPG
+ fingerprint, should you decide to encrypt your report, is
+ `7F52 D5C6 1D12 55C7 3136 2E82 6B97 A1C2 8264 04DA`.
+
+* **YES**, we will reward security researchers who disclose vulnerabilities in
+ our software.
+* In most cases, **No Proof-of-Concept Required.**
+
+## How to Report a Security Bug to Paragon Initiative Enterprises
+
+### There is no compulsion to disclose privately.
+
+We believe vulnerability disclosure style is a personal choice and enjoy working
+with a diverse community. We understand and appreciate the importance of Full
+Disclosure in the history and practice of security research.
+
+We would *like* to know about high-severity bugs before they become public
+knowledge, so we can fix them in a timely manner, but **we do not believe in
+threatening researchers or trying to enforce vulnerability embargoes**.
+
+Ultimately, if you discover a security-affecting vulnerability, what you do with
+it is your choice. We would like to work with people, and to celebrate and
+reward their skill, experience, and dedication. We appreciate being informed of
+our mistakes so we can learn from them and build a better product. Our goal is
+to empower the community.
+
+### Where to Send Security Vulnerabilities
+
+Our security email address is `security@paragonie.com`. Also feel free to open a
+new issue on Github if you want to disclose publicly.
+
+```
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG
+
+mQENBFUgwRUBCADcIpqNwyYc5UmY/tpx1sF/rQ3knR1YNXYZThzFV+Gmqhp1fDH5
+qBs9foh1xwI6O7knWmQngnf/nBumI3x6xj7PuOdEZUh2FwCG/VWnglW8rKmoHzHA
+ivjiu9SLnPIPAgHSHeh2XD7q3Ndm3nenbjAiRFNl2iXcwA2cTQp9Mmfw9vVcw0G0
+z1o0G3s8cC8ZS6flFySIervvfSRWj7A1acI5eE3+AH/qXJRdEJ+9J8OB65p1JMfk
+6+fWgOB1XZxMpz70S0rW6IX38WDSRhEK2fXyZJAJjyt+YGuzjZySNSoQR/V6vNYn
+syrNPCJ2i5CgZQxAkyBBcr7koV9RIhPRzct/ABEBAAG0IVNlY3VyaXR5IDxzZWN1
+cml0eUBwYXJhZ29uaWUuY29tPokBOQQTAQIAIwUCVSDBFQIbAwcLCQgHAwIBBhUI
+AgkKCwQWAgMBAh4BAheAAAoJEGuXocKCZATat2YIAIoejNFEQ2c1iaOEtSuB7Pn/
+WLbsDsHNLDKOV+UnfaCjv/vL7D+5NMChFCi2frde/NQb2TsjqmIH+V+XbnJtlrXD
+Vj7yvMVal+Jqjwj7v4eOEWcKVcFZk+9cfUgh7t92T2BMX58RpgZF0IQZ6Z1R3FfC
+9Ub4X6ykW+te1q0/4CoRycniwmlQi6iGSr99LQ5pfJq2Qlmz/luTZ0UX0h575T7d
+cp2T1sX/zFRk/fHeANWSksipdDBjAXR7NMnYZgw2HghEdFk/xRDY7K1NRWNZBf05
+WrMHmh6AIVJiWZvI175URxEe268hh+wThBhXQHMhFNJM1qPIuzb4WogxM3UUD7m5
+AQ0EVSDBFQEIALNkpzSuJsHAHh79sc0AYWztdUe2MzyofQbbOnOCpWZebYsC3EXU
+335fIg59k0m6f+O7GmEZzzIv5v0i99GS1R8CJm6FvhGqtH8ZqmOGbc71WdJSiNVE
+0kpQoJlVzRbig6ZyyjzrggbM1eh5OXOk5pw4+23FFEdw7JWU0HJS2o71r1hwp05Z
+vy21kcUEobz/WWQQyGS0Neo7PJn+9KS6wOxXul/UE0jct/5f7KLMdWMJ1VgniQmm
+hjvkHLPSICteqCI04RfcmMseW9gueHQXeUu1SNIvsWa2MhxjeBej3pDnrZWszKwy
+gF45GO9/v4tkIXNMy5J1AtOyRgQ3IUMqp8EAEQEAAYkBHwQYAQIACQUCVSDBFQIb
+DAAKCRBrl6HCgmQE2jnIB/4/xFz8InpM7eybnBOAir3uGcYfs3DOmaKn7qWVtGzv
+rKpQPYnVtlU2i6Z5UO4c4jDLT/8Xm1UDz3Lxvqt4xCaDwJvBZexU5BMK8l5DvOzH
+6o6P2L1UDu6BvmPXpVZz7/qUhOnyf8VQg/dAtYF4/ax19giNUpI5j5o5mX5w80Rx
+qSXV9NdSL4fdjeG1g/xXv2luhoV53T1bsycI3wjk/x5tV+M2KVhZBvvuOm/zhJje
+oLWp0saaESkGXIXqurj6gZoujJvSvzl0n9F9VwqMEizDUfrXgtD1siQGhP0sVC6q
+ha+F/SAEJ0jEquM4TfKWWU2S5V5vgPPpIQSYRnhQW4b1
+=xJPW
+-----END PGP PUBLIC KEY BLOCK-----
+```
+
+### We Will Reward Security Researchers
+
+**This process has not been formalized; nor have dollar amounts been
+discussed.**
+
+However, if you report a valid security-affecting bug, we will compensate you
+for the time spent finding the vulnerability and reward you for being a good
+neighbor.
+
+#### What does a "valid" bug mean?
+
+There are two sides to this:
+
+1. Some have spammed projects with invalid bug reports hoping to collect
+ bounties for pressing a button and running an automated analysis tool. This
+ is not cool.
+2. There is a potential for the developers of a project to declare all security
+ bug reports as invalid to save money.
+
+Our team members have an established history of reporting vulnerabilities to
+large open source projects. **We aren't in the business of ripping people off.**
+When in doubt, our policy is to err on the side of generosity.
+
+### No Proof-of-Concept Required
+
+We might ask for one if we feel we do not understand some of the details
+pertaining to a specific vulnerability. We certainly appreciate them if you
+include them in your report, but we believe **the burden lies with the developer
+to prove their software *is* secure** rather than with the researcher to prove
+that it isn't.
+
+In our experience, most bugs are simpler to fix than they are to exploit.
+
diff --git a/vendor/paragonie/random_compat/build-phar.sh b/vendor/paragonie/random_compat/build-phar.sh
new file mode 100644
index 00000000..b4a5ba31
--- /dev/null
+++ b/vendor/paragonie/random_compat/build-phar.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) )
+
+php -dphar.readonly=0 "$basedir/other/build_phar.php" $*
\ No newline at end of file
diff --git a/vendor/paragonie/random_compat/composer.json b/vendor/paragonie/random_compat/composer.json
new file mode 100644
index 00000000..d363f4c8
--- /dev/null
+++ b/vendor/paragonie/random_compat/composer.json
@@ -0,0 +1,35 @@
+{
+ "name": "paragonie/random_compat",
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "random",
+ "pseudorandom"
+ ],
+ "license": "MIT",
+ "type": "library",
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/paragonie/random_compat/issues",
+ "email": "info@paragonie.com",
+ "source": "https://github.com/paragonie/random_compat"
+ },
+ "require": {
+ "php": ">=5.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "autoload": {
+ "files": ["lib/random.php"]
+ }
+}
diff --git a/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey
new file mode 100644
index 00000000..eb50ebfc
--- /dev/null
+++ b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey
@@ -0,0 +1,5 @@
+-----BEGIN PUBLIC KEY-----
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm
+pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p
++h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc
+-----END PUBLIC KEY-----
diff --git a/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc
new file mode 100644
index 00000000..6a1d7f30
--- /dev/null
+++ b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.0.22 (MingW32)
+
+iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip
+QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg
+1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW
+NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA
+NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV
+JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74=
+=B6+8
+-----END PGP SIGNATURE-----
diff --git a/vendor/paragonie/random_compat/lib/byte_safe_strings.php b/vendor/paragonie/random_compat/lib/byte_safe_strings.php
new file mode 100644
index 00000000..6de294f8
--- /dev/null
+++ b/vendor/paragonie/random_compat/lib/byte_safe_strings.php
@@ -0,0 +1,181 @@
+ RandomCompat_strlen($binary_string)) {
+ return '';
+ }
+
+ return (string) mb_substr($binary_string, $start, $length, '8bit');
+ }
+
+ } else {
+
+ /**
+ * substr() implementation that isn't brittle to mbstring.func_overload
+ *
+ * This version just uses the default substr()
+ *
+ * @param string $binary_string
+ * @param int $start
+ * @param int $length (optional)
+ *
+ * @throws TypeError
+ *
+ * @return string
+ */
+ function RandomCompat_substr($binary_string, $start, $length = null)
+ {
+ if (!is_string($binary_string)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): First argument should be a string'
+ );
+ }
+
+ if (!is_int($start)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): Second argument should be an integer'
+ );
+ }
+
+ if ($length !== null) {
+ if (!is_int($length)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): Third argument should be an integer, or omitted'
+ );
+ }
+
+ return (string) substr($binary_string, $start, $length);
+ }
+
+ return (string) substr($binary_string, $start);
+ }
+ }
+}
diff --git a/vendor/paragonie/random_compat/lib/cast_to_int.php b/vendor/paragonie/random_compat/lib/cast_to_int.php
new file mode 100644
index 00000000..dc4048c9
--- /dev/null
+++ b/vendor/paragonie/random_compat/lib/cast_to_int.php
@@ -0,0 +1,74 @@
+ operators might accidentally let a float
+ * through.
+ *
+ * @param int|float $number The number we want to convert to an int
+ * @param boolean $fail_open Set to true to not throw an exception
+ *
+ * @return float|int
+ *
+ * @throws TypeError
+ */
+ function RandomCompat_intval($number, $fail_open = false)
+ {
+ if (is_int($number) || is_float($number)) {
+ $number += 0;
+ } elseif (is_numeric($number)) {
+ $number += 0;
+ }
+
+ if (
+ is_float($number)
+ &&
+ $number > ~PHP_INT_MAX
+ &&
+ $number < PHP_INT_MAX
+ ) {
+ $number = (int) $number;
+ }
+
+ if (is_int($number)) {
+ return (int) $number;
+ } elseif (!$fail_open) {
+ throw new TypeError(
+ 'Expected an integer.'
+ );
+ }
+ return $number;
+ }
+}
diff --git a/vendor/paragonie/random_compat/lib/error_polyfill.php b/vendor/paragonie/random_compat/lib/error_polyfill.php
new file mode 100644
index 00000000..17ece7b2
--- /dev/null
+++ b/vendor/paragonie/random_compat/lib/error_polyfill.php
@@ -0,0 +1,49 @@
+= 70000) {
+ return;
+}
+
+if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
+ define('RANDOM_COMPAT_READ_BUFFER', 8);
+}
+
+$RandomCompatDIR = dirname(__FILE__);
+
+require_once $RandomCompatDIR . '/byte_safe_strings.php';
+require_once $RandomCompatDIR . '/cast_to_int.php';
+require_once $RandomCompatDIR . '/error_polyfill.php';
+
+if (!is_callable('random_bytes')) {
+ /**
+ * PHP 5.2.0 - 5.6.x way to implement random_bytes()
+ *
+ * We use conditional statements here to define the function in accordance
+ * to the operating environment. It's a micro-optimization.
+ *
+ * In order of preference:
+ * 1. Use libsodium if available.
+ * 2. fread() /dev/urandom if available (never on Windows)
+ * 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
+ * 4. COM('CAPICOM.Utilities.1')->GetRandom()
+ *
+ * See RATIONALE.md for our reasoning behind this particular order
+ */
+ if (extension_loaded('libsodium')) {
+ // See random_bytes_libsodium.php
+ if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
+ require_once $RandomCompatDIR . '/random_bytes_libsodium.php';
+ } elseif (method_exists('Sodium', 'randombytes_buf')) {
+ require_once $RandomCompatDIR . '/random_bytes_libsodium_legacy.php';
+ }
+ }
+
+ /**
+ * Reading directly from /dev/urandom:
+ */
+ if (DIRECTORY_SEPARATOR === '/') {
+ // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
+ // way to exclude Windows.
+ $RandomCompatUrandom = true;
+ $RandomCompat_basedir = ini_get('open_basedir');
+
+ if (!empty($RandomCompat_basedir)) {
+ $RandomCompat_open_basedir = explode(
+ PATH_SEPARATOR,
+ strtolower($RandomCompat_basedir)
+ );
+ $RandomCompatUrandom = (array() !== array_intersect(
+ array('/dev', '/dev/', '/dev/urandom'),
+ $RandomCompat_open_basedir
+ ));
+ $RandomCompat_open_basedir = null;
+ }
+
+ if (
+ !is_callable('random_bytes')
+ &&
+ $RandomCompatUrandom
+ &&
+ @is_readable('/dev/urandom')
+ ) {
+ // Error suppression on is_readable() in case of an open_basedir
+ // or safe_mode failure. All we care about is whether or not we
+ // can read it at this point. If the PHP environment is going to
+ // panic over trying to see if the file can be read in the first
+ // place, that is not helpful to us here.
+
+ // See random_bytes_dev_urandom.php
+ require_once $RandomCompatDIR . '/random_bytes_dev_urandom.php';
+ }
+ // Unset variables after use
+ $RandomCompat_basedir = null;
+ } else {
+ $RandomCompatUrandom = false;
+ }
+
+ /**
+ * mcrypt_create_iv()
+ *
+ * We only want to use mcypt_create_iv() if:
+ *
+ * - random_bytes() hasn't already been defined
+ * - the mcrypt extensions is loaded
+ * - One of these two conditions is true:
+ * - We're on Windows (DIRECTORY_SEPARATOR !== '/')
+ * - We're not on Windows and /dev/urandom is readabale
+ * (i.e. we're not in a chroot jail)
+ * - Special case:
+ * - If we're not on Windows, but the PHP version is between
+ * 5.6.10 and 5.6.12, we don't want to use mcrypt. It will
+ * hang indefinitely. This is bad.
+ * - If we're on Windows, we want to use PHP >= 5.3.7 or else
+ * we get insufficient entropy errors.
+ */
+ if (
+ !is_callable('random_bytes')
+ &&
+ // Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be.
+ (DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307)
+ &&
+ // Prevent this code from hanging indefinitely on non-Windows;
+ // see https://bugs.php.net/bug.php?id=69833
+ (
+ DIRECTORY_SEPARATOR !== '/' ||
+ (PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
+ )
+ &&
+ extension_loaded('mcrypt')
+ ) {
+ // See random_bytes_mcrypt.php
+ require_once $RandomCompatDIR . '/random_bytes_mcrypt.php';
+ }
+ $RandomCompatUrandom = null;
+
+ /**
+ * This is a Windows-specific fallback, for when the mcrypt extension
+ * isn't loaded.
+ */
+ if (
+ !is_callable('random_bytes')
+ &&
+ extension_loaded('com_dotnet')
+ &&
+ class_exists('COM')
+ ) {
+ $RandomCompat_disabled_classes = preg_split(
+ '#\s*,\s*#',
+ strtolower(ini_get('disable_classes'))
+ );
+
+ if (!in_array('com', $RandomCompat_disabled_classes)) {
+ try {
+ $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
+ if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
+ // See random_bytes_com_dotnet.php
+ require_once $RandomCompatDIR . '/random_bytes_com_dotnet.php';
+ }
+ } catch (com_exception $e) {
+ // Don't try to use it.
+ }
+ }
+ $RandomCompat_disabled_classes = null;
+ $RandomCompatCOMtest = null;
+ }
+
+ /**
+ * openssl_random_pseudo_bytes()
+ */
+ if (
+ (
+ // Unix-like with PHP >= 5.3.0 or
+ (
+ DIRECTORY_SEPARATOR === '/'
+ &&
+ PHP_VERSION_ID >= 50300
+ )
+ ||
+ // Windows with PHP >= 5.4.1
+ PHP_VERSION_ID >= 50401
+ )
+ &&
+ !function_exists('random_bytes')
+ &&
+ extension_loaded('openssl')
+ ) {
+ // See random_bytes_openssl.php
+ require_once $RandomCompatDIR . '/random_bytes_openssl.php';
+ }
+
+ /**
+ * throw new Exception
+ */
+ if (!is_callable('random_bytes')) {
+ /**
+ * We don't have any more options, so let's throw an exception right now
+ * and hope the developer won't let it fail silently.
+ *
+ * @param mixed $length
+ * @return void
+ * @throws Exception
+ */
+ function random_bytes($length)
+ {
+ unset($length); // Suppress "variable not used" warnings.
+ throw new Exception(
+ 'There is no suitable CSPRNG installed on your system'
+ );
+ }
+ }
+}
+
+if (!is_callable('random_int')) {
+ require_once $RandomCompatDIR . '/random_int.php';
+}
+
+$RandomCompatDIR = null;
diff --git a/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php b/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php
new file mode 100644
index 00000000..28cc56ac
--- /dev/null
+++ b/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php
@@ -0,0 +1,88 @@
+GetRandom($bytes, 0));
+ if (RandomCompat_strlen($buf) >= $bytes) {
+ /**
+ * Return our random entropy buffer here:
+ */
+ return RandomCompat_substr($buf, 0, $bytes);
+ }
+ ++$execCount;
+ } while ($execCount < $bytes);
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+}
diff --git a/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php b/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php
new file mode 100644
index 00000000..8bf70341
--- /dev/null
+++ b/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php
@@ -0,0 +1,150 @@
+ 0);
+
+ /**
+ * Is our result valid?
+ */
+ if ($buf !== false) {
+ if (RandomCompat_strlen($buf) === $bytes) {
+ /**
+ * Return our random entropy buffer here:
+ */
+ return $buf;
+ }
+ }
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Error reading from source device'
+ );
+ }
+}
diff --git a/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php b/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php
new file mode 100644
index 00000000..7d32b21f
--- /dev/null
+++ b/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php
@@ -0,0 +1,88 @@
+ 2147483647) {
+ $buf = '';
+ for ($i = 0; $i < $bytes; $i += 1073741824) {
+ $n = ($bytes - $i) > 1073741824
+ ? 1073741824
+ : $bytes - $i;
+ $buf .= \Sodium\randombytes_buf($n);
+ }
+ } else {
+ $buf = \Sodium\randombytes_buf($bytes);
+ }
+
+ if ($buf !== false) {
+ if (RandomCompat_strlen($buf) === $bytes) {
+ return $buf;
+ }
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+}
diff --git a/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php b/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php
new file mode 100644
index 00000000..ba93c403
--- /dev/null
+++ b/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php
@@ -0,0 +1,92 @@
+ 2147483647) {
+ for ($i = 0; $i < $bytes; $i += 1073741824) {
+ $n = ($bytes - $i) > 1073741824
+ ? 1073741824
+ : $bytes - $i;
+ $buf .= Sodium::randombytes_buf($n);
+ }
+ } else {
+ $buf .= Sodium::randombytes_buf($bytes);
+ }
+
+ if (is_string($buf)) {
+ if (RandomCompat_strlen($buf) === $bytes) {
+ return $buf;
+ }
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+}
diff --git a/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php b/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php
new file mode 100644
index 00000000..3bce91a5
--- /dev/null
+++ b/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php
@@ -0,0 +1,77 @@
+ operators might accidentally let a float
+ * through.
+ */
+
+ try {
+ $min = RandomCompat_intval($min);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_int(): $min must be an integer'
+ );
+ }
+
+ try {
+ $max = RandomCompat_intval($max);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_int(): $max must be an integer'
+ );
+ }
+
+ /**
+ * Now that we've verified our weak typing system has given us an integer,
+ * let's validate the logic then we can move forward with generating random
+ * integers along a given range.
+ */
+ if ($min > $max) {
+ throw new Error(
+ 'Minimum value must be less than or equal to the maximum value'
+ );
+ }
+
+ if ($max === $min) {
+ return $min;
+ }
+
+ /**
+ * Initialize variables to 0
+ *
+ * We want to store:
+ * $bytes => the number of random bytes we need
+ * $mask => an integer bitmask (for use with the &) operator
+ * so we can minimize the number of discards
+ */
+ $attempts = $bits = $bytes = $mask = $valueShift = 0;
+
+ /**
+ * At this point, $range is a positive number greater than 0. It might
+ * overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to
+ * a float and we will lose some precision.
+ */
+ $range = $max - $min;
+
+ /**
+ * Test for integer overflow:
+ */
+ if (!is_int($range)) {
+
+ /**
+ * Still safely calculate wider ranges.
+ * Provided by @CodesInChaos, @oittaa
+ *
+ * @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435
+ *
+ * We use ~0 as a mask in this case because it generates all 1s
+ *
+ * @ref https://eval.in/400356 (32-bit)
+ * @ref http://3v4l.org/XX9r5 (64-bit)
+ */
+ $bytes = PHP_INT_SIZE;
+ $mask = ~0;
+
+ } else {
+
+ /**
+ * $bits is effectively ceil(log($range, 2)) without dealing with
+ * type juggling
+ */
+ while ($range > 0) {
+ if ($bits % 8 === 0) {
+ ++$bytes;
+ }
+ ++$bits;
+ $range >>= 1;
+ $mask = $mask << 1 | 1;
+ }
+ $valueShift = $min;
+ }
+
+ $val = 0;
+ /**
+ * Now that we have our parameters set up, let's begin generating
+ * random integers until one falls between $min and $max
+ */
+ do {
+ /**
+ * The rejection probability is at most 0.5, so this corresponds
+ * to a failure probability of 2^-128 for a working RNG
+ */
+ if ($attempts > 128) {
+ throw new Exception(
+ 'random_int: RNG is broken - too many rejections'
+ );
+ }
+
+ /**
+ * Let's grab the necessary number of random bytes
+ */
+ $randomByteString = random_bytes($bytes);
+
+ /**
+ * Let's turn $randomByteString into an integer
+ *
+ * This uses bitwise operators (<< and |) to build an integer
+ * out of the values extracted from ord()
+ *
+ * Example: [9F] | [6D] | [32] | [0C] =>
+ * 159 + 27904 + 3276800 + 201326592 =>
+ * 204631455
+ */
+ $val &= 0;
+ for ($i = 0; $i < $bytes; ++$i) {
+ $val |= ord($randomByteString[$i]) << ($i * 8);
+ }
+
+ /**
+ * Apply mask
+ */
+ $val &= $mask;
+ $val += $valueShift;
+
+ ++$attempts;
+ /**
+ * If $val overflows to a floating point number,
+ * ... or is larger than $max,
+ * ... or smaller than $min,
+ * then try again.
+ */
+ } while (!is_int($val) || $val > $max || $val < $min);
+
+ return (int)$val;
+ }
+}
diff --git a/vendor/paragonie/random_compat/other/build_phar.php b/vendor/paragonie/random_compat/other/build_phar.php
new file mode 100644
index 00000000..70ef4b2e
--- /dev/null
+++ b/vendor/paragonie/random_compat/other/build_phar.php
@@ -0,0 +1,57 @@
+buildFromDirectory(dirname(__DIR__).'/lib');
+rename(
+ dirname(__DIR__).'/lib/index.php',
+ dirname(__DIR__).'/lib/random.php'
+);
+
+/**
+ * If we pass an (optional) path to a private key as a second argument, we will
+ * sign the Phar with OpenSSL.
+ *
+ * If you leave this out, it will produce an unsigned .phar!
+ */
+if ($argc > 1) {
+ if (!@is_readable($argv[1])) {
+ echo 'Could not read the private key file:', $argv[1], "\n";
+ exit(255);
+ }
+ $pkeyFile = file_get_contents($argv[1]);
+
+ $private = openssl_get_privatekey($pkeyFile);
+ if ($private !== false) {
+ $pkey = '';
+ openssl_pkey_export($private, $pkey);
+ $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey);
+
+ /**
+ * Save the corresponding public key to the file
+ */
+ if (!@is_readable($dist.'/random_compat.phar.pubkey')) {
+ $details = openssl_pkey_get_details($private);
+ file_put_contents(
+ $dist.'/random_compat.phar.pubkey',
+ $details['key']
+ );
+ }
+ } else {
+ echo 'An error occurred reading the private key from OpenSSL.', "\n";
+ exit(255);
+ }
+}
diff --git a/vendor/paragonie/random_compat/other/ide_stubs/COM.php b/vendor/paragonie/random_compat/other/ide_stubs/COM.php
new file mode 100644
index 00000000..4ba4bb31
--- /dev/null
+++ b/vendor/paragonie/random_compat/other/ide_stubs/COM.php
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
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..196f7fc1
--- /dev/null
+++ b/vendor/pimple/pimple/.travis.yml
@@ -0,0 +1,40 @@
+language: php
+
+env:
+ matrix:
+ - PIMPLE_EXT=no
+ - PIMPLE_EXT=yes
+ global:
+ - REPORT_EXIT_STATUS=1
+
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.1
+
+before_script:
+ - composer self-update
+ - COMPOSER_ROOT_VERSION=dev-master composer install
+ - 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
+ - if [ "$PIMPLE_EXT" == "yes" ]; then export SYMFONY_DEPRECATIONS_HELPER=weak; fi
+ - cd ../..
+ - ./vendor/bin/simple-phpunit
+
+matrix:
+ include:
+ - php: hhvm
+ dist: trusty
+ env: PIMPLE_EXT=no
+ exclude:
+ - php: 7.0
+ env: PIMPLE_EXT=yes
+ - php: 7.1
+ env: PIMPLE_EXT=yes
diff --git a/vendor/pimple/pimple/CHANGELOG b/vendor/pimple/pimple/CHANGELOG
new file mode 100644
index 00000000..0534f923
--- /dev/null
+++ b/vendor/pimple/pimple/CHANGELOG
@@ -0,0 +1,40 @@
+* 3.1.0 (2017-07-03)
+
+ * deprecated the C extension
+ * added support for PSR-11 exceptions
+
+* 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..e02dc5a7
--- /dev/null
+++ b/vendor/pimple/pimple/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2009-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/pimple/pimple/README.rst b/vendor/pimple/pimple/README.rst
new file mode 100644
index 00000000..2af62d9c
--- /dev/null
+++ b/vendor/pimple/pimple/README.rst
@@ -0,0 +1,190 @@
+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"
+
+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..d863ca84
--- /dev/null
+++ b/vendor/pimple/pimple/composer.json
@@ -0,0 +1,29 @@
+{
+ "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",
+ "psr/container": "^1.0"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^3.2"
+ },
+ "autoload": {
+ "psr-0": { "Pimple": "src/" }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.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..3a6e9aae
--- /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..3dd10a7c
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/php_pimple.h
@@ -0,0 +1,137 @@
+
+/*
+ * 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.1.0-DEV"
+
+#define PIMPLE_NS "Pimple"
+#define PSR_CONTAINER_NS "Psr\\Container"
+#define PIMPLE_EXCEPTION_NS "Pimple\\Exception"
+
+#define PIMPLE_DEFAULT_ZVAL_CACHE_NUM 5
+#define PIMPLE_DEFAULT_ZVAL_VALUES_NUM 10
+
+#define PIMPLE_DEPRECATE do { \
+ int er = EG(error_reporting); \
+ EG(error_reporting) = 0;\
+ php_error(E_DEPRECATED, "The Pimple C extension is deprecated since version 3.1 and will be removed in 4.0."); \
+ EG(error_reporting) = er; \
+} while (0);
+
+zend_module_entry *get_module(void);
+
+PHP_MINIT_FUNCTION(pimple);
+PHP_MINFO_FUNCTION(pimple);
+
+PHP_METHOD(FrozenServiceException, __construct);
+PHP_METHOD(InvalidServiceIdentifierException, __construct);
+PHP_METHOD(UnknownIdentifierException, __construct);
+
+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 void pimple_exception_call_parent_constructor(zval *this_ptr, const char *format, const char *arg1 TSRMLS_DC);
+
+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..285e3dd5
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/pimple.c
@@ -0,0 +1,1101 @@
+
+/*
+ * 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_PsrContainerInterface;
+static zend_class_entry *pimple_ce_PsrContainerExceptionInterface;
+static zend_class_entry *pimple_ce_PsrNotFoundExceptionInterface;
+
+static zend_class_entry *pimple_ce_ExpectedInvokableException;
+static zend_class_entry *pimple_ce_FrozenServiceException;
+static zend_class_entry *pimple_ce_InvalidServiceIdentifierException;
+static zend_class_entry *pimple_ce_UnknownIdentifierException;
+
+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);
+
+
+/* Psr\Container\ContainerInterface */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_pimple_PsrContainerInterface_get, 0, 0, 1)
+ZEND_ARG_INFO(0, id)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_pimple_PsrContainerInterface_has, 0, 0, 1)
+ZEND_ARG_INFO(0, id)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry pimple_ce_PsrContainerInterface_functions[] = {
+ PHP_ABSTRACT_ME(ContainerInterface, get, arginfo_pimple_PsrContainerInterface_get)
+ PHP_ABSTRACT_ME(ContainerInterface, has, arginfo_pimple_PsrContainerInterface_has)
+ PHP_FE_END
+};
+
+/* Psr\Container\ContainerExceptionInterface */
+static const zend_function_entry pimple_ce_PsrContainerExceptionInterface_functions[] = {
+ PHP_FE_END
+};
+
+/* Psr\Container\NotFoundExceptionInterface */
+static const zend_function_entry pimple_ce_PsrNotFoundExceptionInterface_functions[] = {
+ PHP_FE_END
+};
+
+/* Pimple\Exception\FrozenServiceException */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_FrozenServiceException___construct, 0, 0, 1)
+ZEND_ARG_INFO(0, id)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry pimple_ce_FrozenServiceException_functions[] = {
+ PHP_ME(FrozenServiceException, __construct, arginfo_FrozenServiceException___construct, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+/* Pimple\Exception\InvalidServiceIdentifierException */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_InvalidServiceIdentifierException___construct, 0, 0, 1)
+ZEND_ARG_INFO(0, id)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry pimple_ce_InvalidServiceIdentifierException_functions[] = {
+ PHP_ME(InvalidServiceIdentifierException, __construct, arginfo_InvalidServiceIdentifierException___construct, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+/* Pimple\Exception\UnknownIdentifierException */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_UnknownIdentifierException___construct, 0, 0, 1)
+ZEND_ARG_INFO(0, id)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry pimple_ce_UnknownIdentifierException_functions[] = {
+ PHP_ME(UnknownIdentifierException, __construct, arginfo_UnknownIdentifierException___construct, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+/* Pimple\Container */
+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()
+
+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
+};
+
+/* Pimple\ServiceProviderInterface */
+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_serviceprovider_iface_ce_functions[] = {
+ PHP_ABSTRACT_ME(ServiceProviderInterface, register, arginfo_serviceprovider_register)
+ PHP_FE_END
+};
+
+/* parent::__construct(sprintf("Something with %s", $arg1)) */
+static void pimple_exception_call_parent_constructor(zval *this_ptr, const char *format, const char *arg1 TSRMLS_DC)
+{
+ zend_class_entry *ce = Z_OBJCE_P(this_ptr);
+ char *message = NULL;
+ int message_len;
+ zval *constructor_arg;
+
+ message_len = spprintf(&message, 0, format, arg1);
+ ALLOC_INIT_ZVAL(constructor_arg);
+ ZVAL_STRINGL(constructor_arg, message, message_len, 1);
+
+ zend_call_method_with_1_params(&this_ptr, ce, &ce->parent->constructor, "__construct", NULL, constructor_arg);
+
+ efree(message);
+ zval_ptr_dtor(&constructor_arg);
+}
+
+/**
+ * Pass a single string parameter to exception constructor and throw
+ */
+static void pimple_throw_exception_string(zend_class_entry *ce, const char *message, zend_uint message_len TSRMLS_DC)
+{
+ zval *exception, *param;
+
+ ALLOC_INIT_ZVAL(exception);
+ object_init_ex(exception, ce);
+
+ ALLOC_INIT_ZVAL(param);
+ ZVAL_STRINGL(param, message, message_len, 1);
+
+ zend_call_method_with_1_params(&exception, ce, &ce->constructor, "__construct", NULL, param);
+
+ zend_throw_exception_object(exception TSRMLS_CC);
+
+ zval_ptr_dtor(¶m);
+}
+
+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);
+ pimple_throw_exception_string(pimple_ce_FrozenServiceException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
+ 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);
+ convert_to_string(offset);
+ pimple_throw_exception_string(pimple_ce_FrozenServiceException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
+ 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) {
+ pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
+
+ 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 every time 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(FrozenServiceException, __construct)
+{
+ char *id = NULL;
+ int id_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) {
+ return;
+ }
+ pimple_exception_call_parent_constructor(getThis(), "Cannot override frozen service \"%s\".", id TSRMLS_CC);
+}
+
+PHP_METHOD(InvalidServiceIdentifierException, __construct)
+{
+ char *id = NULL;
+ int id_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) {
+ return;
+ }
+ pimple_exception_call_parent_constructor(getThis(), "Identifier \"%s\" does not contain an object definition.", id TSRMLS_CC);
+}
+
+PHP_METHOD(UnknownIdentifierException, __construct)
+{
+ char *id = NULL;
+ int id_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) {
+ return;
+ }
+ pimple_exception_call_parent_constructor(getThis(), "Identifier \"%s\" is not defined.", id TSRMLS_CC);
+}
+
+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(pimple_ce_ExpectedInvokableException, "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) {
+ pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
+ 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) {
+ pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
+ RETURN_NULL();
+ }
+ if (value->type != PIMPLE_IS_SERVICE) {
+ pimple_throw_exception_string(pimple_ce_InvalidServiceIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
+ 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) {
+ convert_to_string(offset);
+ pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
+ RETURN_NULL();
+ }
+ if (value->type != PIMPLE_IS_SERVICE) {
+ convert_to_string(offset);
+ pimple_throw_exception_string(pimple_ce_InvalidServiceIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
+ 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(pimple_ce_ExpectedInvokableException, "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(pimple_ce_ExpectedInvokableException, "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) {
+ return;
+ }
+
+ PIMPLE_DEPRECATE
+
+ if (!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_ce_PsrContainerInterface, tmp_ce_PsrContainerExceptionInterface, tmp_ce_PsrNotFoundExceptionInterface;
+ zend_class_entry tmp_ce_ExpectedInvokableException, tmp_ce_FrozenServiceException, tmp_ce_InvalidServiceIdentifierException, tmp_ce_UnknownIdentifierException;
+ zend_class_entry tmp_pimple_ce, tmp_pimple_closure_ce, tmp_pimple_serviceprovider_iface_ce;
+
+ /* Psr\Container namespace */
+ INIT_NS_CLASS_ENTRY(tmp_ce_PsrContainerInterface, PSR_CONTAINER_NS, "ContainerInterface", pimple_ce_PsrContainerInterface_functions);
+ INIT_NS_CLASS_ENTRY(tmp_ce_PsrContainerExceptionInterface, PSR_CONTAINER_NS, "ContainerExceptionInterface", pimple_ce_PsrContainerExceptionInterface_functions);
+ INIT_NS_CLASS_ENTRY(tmp_ce_PsrNotFoundExceptionInterface, PSR_CONTAINER_NS, "NotFoundExceptionInterface", pimple_ce_PsrNotFoundExceptionInterface_functions);
+
+ pimple_ce_PsrContainerInterface = zend_register_internal_interface(&tmp_ce_PsrContainerInterface TSRMLS_CC);
+ pimple_ce_PsrContainerExceptionInterface = zend_register_internal_interface(&tmp_ce_PsrContainerExceptionInterface TSRMLS_CC);
+ pimple_ce_PsrNotFoundExceptionInterface = zend_register_internal_interface(&tmp_ce_PsrNotFoundExceptionInterface TSRMLS_CC);
+
+ zend_class_implements(pimple_ce_PsrNotFoundExceptionInterface TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
+
+ /* Pimple\Exception namespace */
+ INIT_NS_CLASS_ENTRY(tmp_ce_ExpectedInvokableException, PIMPLE_EXCEPTION_NS, "ExpectedInvokableException", NULL);
+ INIT_NS_CLASS_ENTRY(tmp_ce_FrozenServiceException, PIMPLE_EXCEPTION_NS, "FrozenServiceException", pimple_ce_FrozenServiceException_functions);
+ INIT_NS_CLASS_ENTRY(tmp_ce_InvalidServiceIdentifierException, PIMPLE_EXCEPTION_NS, "InvalidServiceIdentifierException", pimple_ce_InvalidServiceIdentifierException_functions);
+ INIT_NS_CLASS_ENTRY(tmp_ce_UnknownIdentifierException, PIMPLE_EXCEPTION_NS, "UnknownIdentifierException", pimple_ce_UnknownIdentifierException_functions);
+
+ pimple_ce_ExpectedInvokableException = zend_register_internal_class_ex(&tmp_ce_ExpectedInvokableException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
+ pimple_ce_FrozenServiceException = zend_register_internal_class_ex(&tmp_ce_FrozenServiceException, spl_ce_RuntimeException, NULL TSRMLS_CC);
+ pimple_ce_InvalidServiceIdentifierException = zend_register_internal_class_ex(&tmp_ce_InvalidServiceIdentifierException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
+ pimple_ce_UnknownIdentifierException = zend_register_internal_class_ex(&tmp_ce_UnknownIdentifierException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
+
+ zend_class_implements(pimple_ce_ExpectedInvokableException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
+ zend_class_implements(pimple_ce_FrozenServiceException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
+ zend_class_implements(pimple_ce_InvalidServiceIdentifierException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
+ zend_class_implements(pimple_ce_UnknownIdentifierException TSRMLS_CC, 1, pimple_ce_PsrNotFoundExceptionInterface);
+
+ /* Pimple namespace */
+ 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..543cee95
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Container.php
@@ -0,0 +1,291 @@
+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 FrozenServiceException($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 UnknownIdentifierException($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 ExpectedInvokableException('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 ExpectedInvokableException('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 UnknownIdentifierException($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 UnknownIdentifierException($id);
+ }
+
+ if (isset($this->frozen[$id])) {
+ throw new FrozenServiceException($id);
+ }
+
+ if (!is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) {
+ throw new InvalidServiceIdentifierException($id);
+ }
+
+ if (!is_object($callable) || !method_exists($callable, '__invoke')) {
+ throw new ExpectedInvokableException('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/Exception/ExpectedInvokableException.php b/vendor/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php
new file mode 100644
index 00000000..7228421b
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php
@@ -0,0 +1,38 @@
+
+ */
+class ExpectedInvokableException extends \InvalidArgumentException implements ContainerExceptionInterface
+{
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php b/vendor/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php
new file mode 100644
index 00000000..64b02659
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php
@@ -0,0 +1,45 @@
+
+ */
+class FrozenServiceException extends \RuntimeException implements ContainerExceptionInterface
+{
+ /**
+ * @param string $id Identifier of the frozen service
+ */
+ public function __construct($id)
+ {
+ parent::__construct(sprintf('Cannot override frozen service "%s".', $id));
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php b/vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php
new file mode 100644
index 00000000..9df9c663
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php
@@ -0,0 +1,45 @@
+
+ */
+class InvalidServiceIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface
+{
+ /**
+ * @param string $id The invalid identifier
+ */
+ public function __construct($id)
+ {
+ parent::__construct(sprintf('Identifier "%s" does not contain an object definition.', $id));
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php b/vendor/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php
new file mode 100644
index 00000000..28413189
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php
@@ -0,0 +1,45 @@
+
+ */
+class UnknownIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface
+{
+ /**
+ * @param string $id The unknown identifier
+ */
+ public function __construct($id)
+ {
+ parent::__construct(sprintf('Identifier "%s" is not defined.', $id));
+ }
+}
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..6cefaa6c
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php
@@ -0,0 +1,571 @@
+
+ */
+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 \Pimple\Exception\UnknownIdentifierException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testOffsetGetValidatesKeyIsPresent()
+ {
+ $pimple = new Container();
+ echo $pimple['foo'];
+ }
+
+ /**
+ * @group legacy
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testLegacyOffsetGetValidatesKeyIsPresent()
+ {
+ $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->getMockBuilder('Pimple\ServiceProviderInterface')->getMock()));
+ }
+
+ /**
+ * @expectedException \Pimple\Exception\UnknownIdentifierException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testRawValidatesKeyIsPresent()
+ {
+ $pimple = new Container();
+ $pimple->raw('foo');
+ }
+
+ /**
+ * @group legacy
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testLegacyRawValidatesKeyIsPresent()
+ {
+ $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 \Pimple\Exception\UnknownIdentifierException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testExtendValidatesKeyIsPresent()
+ {
+ $pimple = new Container();
+ $pimple->extend('foo', function () {});
+ }
+
+ /**
+ * @group legacy
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testLegacyExtendValidatesKeyIsPresent()
+ {
+ $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 \Pimple\Exception\ExpectedInvokableException
+ * @expectedExceptionMessage Service definition is not a Closure or invokable object.
+ */
+ public function testFactoryFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple->factory($service);
+ }
+
+ /**
+ * @group legacy
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Service definition is not a Closure or invokable object.
+ */
+ public function testLegacyFactoryFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple->factory($service);
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \Pimple\Exception\ExpectedInvokableException
+ * @expectedExceptionMessage Callable is not a Closure or invokable object.
+ */
+ public function testProtectFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple->protect($service);
+ }
+
+ /**
+ * @group legacy
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Callable is not a Closure or invokable object.
+ */
+ public function testLegacyProtectFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple->protect($service);
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \Pimple\Exception\InvalidServiceIdentifierException
+ * @expectedExceptionMessage Identifier "foo" does not contain an object definition.
+ */
+ public function testExtendFailsForKeysNotContainingServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple['foo'] = $service;
+ $pimple->extend('foo', function () {});
+ }
+
+ /**
+ * @group legacy
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" does not contain an object definition.
+ */
+ public function testLegacyExtendFailsForKeysNotContainingServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple['foo'] = $service;
+ $pimple->extend('foo', function () {});
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \Pimple\Exception\ExpectedInvokableException
+ * @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);
+ }
+
+ /**
+ * @group legacy
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Extension service definition is not a Closure or invokable object.
+ */
+ public function testLegacyExtendFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {};
+ $pimple->extend('foo', $service);
+ }
+
+ /**
+ * @expectedException \Pimple\Exception\FrozenServiceException
+ * @expectedExceptionMessage Cannot override frozen service "foo".
+ */
+ public function testExtendFailsIfFrozenServiceIsNonInvokable()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return new Fixtures\NonInvokable();
+ };
+ $foo = $pimple['foo'];
+
+ $pimple->extend('foo', function () {});
+ }
+
+ /**
+ * @expectedException \Pimple\Exception\FrozenServiceException
+ * @expectedExceptionMessage Cannot override frozen service "foo".
+ */
+ public function testExtendFailsIfFrozenServiceIsInvokable()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return new Fixtures\Invokable();
+ };
+ $foo = $pimple['foo'];
+
+ $pimple->extend('foo', function () {});
+ }
+
+ /**
+ * 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 \Pimple\Exception\FrozenServiceException
+ * @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';
+ };
+ }
+
+ /**
+ * @group legacy
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessage Cannot override frozen service "foo".
+ */
+ public function testLegacyOverridingServiceAfterFreeze()
+ {
+ $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/container/.gitignore b/vendor/psr/container/.gitignore
new file mode 100644
index 00000000..b2395aa0
--- /dev/null
+++ b/vendor/psr/container/.gitignore
@@ -0,0 +1,3 @@
+composer.lock
+composer.phar
+/vendor/
diff --git a/vendor/psr/container/LICENSE b/vendor/psr/container/LICENSE
new file mode 100644
index 00000000..2877a489
--- /dev/null
+++ b/vendor/psr/container/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-2016 container-interop
+Copyright (c) 2016 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/container/README.md b/vendor/psr/container/README.md
new file mode 100644
index 00000000..084f6df5
--- /dev/null
+++ b/vendor/psr/container/README.md
@@ -0,0 +1,5 @@
+# PSR Container
+
+This repository holds all interfaces/classes/traits related to [PSR-11](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md).
+
+Note that this is not a container implementation of its own. See the specification for more details.
diff --git a/vendor/psr/container/composer.json b/vendor/psr/container/composer.json
new file mode 100644
index 00000000..b8ee0126
--- /dev/null
+++ b/vendor/psr/container/composer.json
@@ -0,0 +1,27 @@
+{
+ "name": "psr/container",
+ "type": "library",
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "keywords": ["psr", "psr-11", "container", "container-interop", "container-interface"],
+ "homepage": "https://github.com/php-fig/container",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/psr/container/src/ContainerExceptionInterface.php b/vendor/psr/container/src/ContainerExceptionInterface.php
new file mode 100644
index 00000000..d35c6b4d
--- /dev/null
+++ b/vendor/psr/container/src/ContainerExceptionInterface.php
@@ -0,0 +1,13 @@
+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
+
+
+