From bc3fa5d4515b46524492a54c87cf4a9de7131f78 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Thu, 15 Oct 2015 22:30:45 +1030 Subject: [PATCH] Refactor translation and validation We now use Symfony's Translation component. Yay! We get more powerful pluralisation and better a fallback mechanism. Will want to implement the caching mechanism at some point too. The API is replicated in JavaScript, which could definitely use some testing. Validators have been refactored so that they are decoupled from models completely (i.e. they simply validate arrays of user input). Language packs should include Laravel's validation messages. ref #267 --- framework/core/composer.json | 1 + framework/core/composer.lock | 3642 ----------------- .../js/admin/src/components/PermissionGrid.js | 4 +- .../src/components/PostStreamScrubber.js | 7 +- framework/core/js/lib/App.js | 4 +- framework/core/js/lib/Translator.js | 300 +- .../src/Admin/Controller/ClientController.php | 2 +- .../Api/Middleware/AuthenticateWithHeader.php | 39 +- .../src/Core/Command/CreateGroupHandler.php | 14 +- .../Core/Command/EditDiscussionHandler.php | 12 +- .../src/Core/Command/EditGroupHandler.php | 12 +- .../core/src/Core/Command/EditPostHandler.php | 12 +- .../core/src/Core/Command/EditUserHandler.php | 12 +- .../src/Core/Command/PostReplyHandler.php | 13 +- .../src/Core/Command/RegisterUserHandler.php | 12 +- .../Core/Command/StartDiscussionHandler.php | 12 +- .../core/src/Core/CoreServiceProvider.php | 15 - framework/core/src/Core/User.php | 27 - .../src/Core/Validator/AbstractValidator.php | 109 +- .../Core/Validator/DiscussionValidator.php | 15 +- .../core/src/Core/Validator/PostValidator.php | 13 +- .../core/src/Core/Validator/UserValidator.php | 23 +- ...elValidator.php => ConfigureValidator.php} | 14 +- .../src/Forum/Controller/ClientController.php | 2 +- .../Controller/AbstractClientController.php | 47 +- .../core/src/Http/Controller/ClientView.php | 18 +- .../Middleware/AuthenticateWithCookie.php | 34 +- framework/core/src/Locale/LocaleManager.php | 74 +- .../core/src/Locale/LocaleServiceProvider.php | 17 +- .../core/src/Locale/TranslationCompiler.php | 47 - framework/core/src/Locale/Translator.php | 79 - framework/core/src/Locale/YamlFileLoader.php | 42 + 32 files changed, 578 insertions(+), 4096 deletions(-) delete mode 100644 framework/core/composer.lock rename framework/core/src/Event/{ConfigureModelValidator.php => ConfigureValidator.php} (72%) delete mode 100644 framework/core/src/Locale/TranslationCompiler.php delete mode 100644 framework/core/src/Locale/Translator.php create mode 100644 framework/core/src/Locale/YamlFileLoader.php diff --git a/framework/core/composer.json b/framework/core/composer.json index 476562d8c..c81c3f702 100644 --- a/framework/core/composer.json +++ b/framework/core/composer.json @@ -46,6 +46,7 @@ "dflydev/fig-cookies": "^1.0", "symfony/console": "^2.7", "symfony/yaml": "^2.7", + "symfony/translation": "^2.7", "doctrine/dbal": "^2.5", "monolog/monolog": "^1.16.0", "franzl/whoops-middleware": "^0.1.0", diff --git a/framework/core/composer.lock b/framework/core/composer.lock deleted file mode 100644 index 3c4c54245..000000000 --- a/framework/core/composer.lock +++ /dev/null @@ -1,3642 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "0b4a3140d826b9566b0fde2c36fdf81f", - "content-hash": "c770bf3b6d5906b52fa2066708d07959", - "packages": [ - { - "name": "danielstjules/stringy", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/danielstjules/Stringy.git", - "reference": "4749c205db47ee5b32e8d1adf6d9aff8db6caf3b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/danielstjules/Stringy/zipball/4749c205db47ee5b32e8d1adf6d9aff8db6caf3b", - "reference": "4749c205db47ee5b32e8d1adf6d9aff8db6caf3b", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Stringy\\": "src/" - }, - "files": [ - "src/Create.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel St. Jules", - "email": "danielst.jules@gmail.com", - "homepage": "http://www.danielstjules.com" - } - ], - "description": "A string manipulation library with multibyte support", - "homepage": "https://github.com/danielstjules/Stringy", - "keywords": [ - "UTF", - "helpers", - "manipulation", - "methods", - "multibyte", - "string", - "utf-8", - "utility", - "utils" - ], - "time": "2015-07-23 00:54:12" - }, - { - "name": "dflydev/fig-cookies", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/dflydev/dflydev-fig-cookies.git", - "reference": "3777cdff8d47fd914034e00a335c836c4ef8e84e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dflydev/dflydev-fig-cookies/zipball/3777cdff8d47fd914034e00a335c836c4ef8e84e", - "reference": "3777cdff8d47fd914034e00a335c836c4ef8e84e", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "psr/http-message": "~1.0" - }, - "require-dev": { - "codeclimate/php-test-reporter": "~0.1@dev", - "phpunit/phpunit": "~4.5", - "squizlabs/php_codesniffer": "~2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Dflydev\\FigCookies\\": "src/Dflydev/FigCookies" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Beau Simensen", - "email": "beau@dflydev.com" - } - ], - "description": "Cookies for PSR-7 HTTP Message Interface.", - "keywords": [ - "cookies", - "psr-7", - "psr7" - ], - "time": "2015-06-03 18:02:30" - }, - { - "name": "doctrine/annotations", - "version": "v1.2.7", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", - "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", - "shasum": "" - }, - "require": { - "doctrine/lexer": "1.*", - "php": ">=5.3.2" - }, - "require-dev": { - "doctrine/cache": "1.*", - "phpunit/phpunit": "4.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Annotations\\": "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": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "time": "2015-08-31 12:32:49" - }, - { - "name": "doctrine/cache", - "version": "v1.4.2", - "source": { - "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/8c434000f420ade76a07c64cbe08ca47e5c101ca", - "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" - }, - "require-dev": { - "phpunit/phpunit": ">=3.7", - "predis/predis": "~1.0", - "satooshi/php-coveralls": "~0.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Cache\\": "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": "Caching library offering an object-oriented API for many cache backends", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "cache", - "caching" - ], - "time": "2015-08-31 12:36:41" - }, - { - "name": "doctrine/collections", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/collections.git", - "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", - "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Collections\\": "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": "Collections Abstraction library", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "array", - "collections", - "iterator" - ], - "time": "2015-04-14 22:21:58" - }, - { - "name": "doctrine/common", - "version": "v2.5.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/common.git", - "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/0009b8f0d4a917aabc971fb089eba80e872f83f9", - "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9", - "shasum": "" - }, - "require": { - "doctrine/annotations": "1.*", - "doctrine/cache": "1.*", - "doctrine/collections": "1.*", - "doctrine/inflector": "1.*", - "doctrine/lexer": "1.*", - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~3.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\": "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 Library for Doctrine projects", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "collections", - "eventmanager", - "persistence", - "spl" - ], - "time": "2015-08-31 13:00:22" - }, - { - "name": "doctrine/dbal", - "version": "v2.5.2", - "source": { - "type": "git", - "url": "https://github.com/doctrine/dbal.git", - "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/01dbcbc5cd0a913d751418e635434a18a2f2a75c", - "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c", - "shasum": "" - }, - "require": { - "doctrine/common": ">=2.4,<2.6-dev", - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "4.*", - "symfony/console": "2.*" - }, - "suggest": { - "symfony/console": "For helpful console commands such as SQL execution and import of files." - }, - "bin": [ - "bin/doctrine-dbal" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\DBAL\\": "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" - } - ], - "description": "Database Abstraction Layer", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "database", - "dbal", - "persistence", - "queryobject" - ], - "time": "2015-09-16 16:29:33" - }, - { - "name": "doctrine/inflector", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/inflector.git", - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604", - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.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": "2014-12-20 21:24:13" - }, - { - "name": "doctrine/lexer", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "lexer", - "parser" - ], - "time": "2014-09-09 13:34:57" - }, - { - "name": "filp/whoops", - "version": "1.1.7", - "source": { - "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "72538eeb70bbfb11964412a3d098d109efd012f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/72538eeb70bbfb11964412a3d098d109efd012f7", - "reference": "72538eeb70bbfb11964412a3d098d109efd012f7", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "mockery/mockery": "0.9.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "psr-0": { - "Whoops": "src/" - }, - "classmap": [ - "src/deprecated" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" - } - ], - "description": "php error handling for cool kids", - "homepage": "https://github.com/filp/whoops", - "keywords": [ - "error", - "exception", - "handling", - "library", - "silex-provider", - "whoops", - "zf2" - ], - "time": "2015-06-29 05:42:04" - }, - { - "name": "franzl/whoops-middleware", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/franzliedke/whoops-middleware.git", - "reference": "4f87c4d36653d95b27fbe85d21954e0d2de58136" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/franzliedke/whoops-middleware/zipball/4f87c4d36653d95b27fbe85d21954e0d2de58136", - "reference": "4f87c4d36653d95b27fbe85d21954e0d2de58136", - "shasum": "" - }, - "require": { - "filp/whoops": "^1.1", - "zendframework/zend-diactoros": "^1.1@dev", - "zendframework/zend-stratigility": "^1.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Franzl\\Middleware\\Whoops\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "time": "2015-06-17 00:08:50" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "4ef919b0cf3b1989523138b60163bbcb7ba1ff7e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/4ef919b0cf3b1989523138b60163bbcb7ba1ff7e", - "reference": "4ef919b0cf3b1989523138b60163bbcb7ba1ff7e", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "PSR-7 message implementation", - "keywords": [ - "http", - "message", - "stream", - "uri" - ], - "time": "2015-08-15 19:32:36" - }, - { - "name": "illuminate/bus", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/bus.git", - "reference": "f06735223936552d56733a6e7657040029dd7a7d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/bus/zipball/f06735223936552d56733a6e7657040029dd7a7d", - "reference": "f06735223936552d56733a6e7657040029dd7a7d", - "shasum": "" - }, - "require": { - "illuminate/contracts": "5.1.*", - "illuminate/pipeline": "5.1.*", - "illuminate/support": "5.1.*", - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Bus\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Bus package.", - "homepage": "http://laravel.com", - "time": "2015-08-25 00:21:39" - }, - { - "name": "illuminate/cache", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/cache.git", - "reference": "dcd7551151aa752324562ad220e4fe4ee0687116" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/cache/zipball/dcd7551151aa752324562ad220e4fe4ee0687116", - "reference": "dcd7551151aa752324562ad220e4fe4ee0687116", - "shasum": "" - }, - "require": { - "illuminate/contracts": "5.1.*", - "illuminate/support": "5.1.*", - "nesbot/carbon": "~1.19", - "php": ">=5.5.9" - }, - "suggest": { - "illuminate/database": "Required to use the database cache driver (5.1.*).", - "illuminate/filesystem": "Required to use the file cache driver (5.1.*).", - "illuminate/redis": "Required to use the redis cache driver (5.1.*)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Cache\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Cache package.", - "homepage": "http://laravel.com", - "time": "2015-09-03 11:44:03" - }, - { - "name": "illuminate/config", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/config.git", - "reference": "de6c1cc0f2745645dec3f8bab0e43a3aa141d12d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/config/zipball/de6c1cc0f2745645dec3f8bab0e43a3aa141d12d", - "reference": "de6c1cc0f2745645dec3f8bab0e43a3aa141d12d", - "shasum": "" - }, - "require": { - "illuminate/contracts": "5.1.*", - "illuminate/filesystem": "5.1.*", - "illuminate/support": "5.1.*", - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Config\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Config package.", - "homepage": "http://laravel.com", - "time": "2015-06-18 02:16:31" - }, - { - "name": "illuminate/container", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/container.git", - "reference": "66621248395705cc64bc1ce9262b99b4bfa606f2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/container/zipball/66621248395705cc64bc1ce9262b99b4bfa606f2", - "reference": "66621248395705cc64bc1ce9262b99b4bfa606f2", - "shasum": "" - }, - "require": { - "illuminate/contracts": "5.1.*", - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Container\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Container package.", - "homepage": "http://laravel.com", - "time": "2015-08-26 23:00:38" - }, - { - "name": "illuminate/contracts", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/contracts.git", - "reference": "610aea16e3d91dfd85db4cf43703403a83b7cba2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/610aea16e3d91dfd85db4cf43703403a83b7cba2", - "reference": "610aea16e3d91dfd85db4cf43703403a83b7cba2", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Contracts\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Contracts package.", - "homepage": "http://laravel.com", - "time": "2015-08-31 12:59:22" - }, - { - "name": "illuminate/database", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/database.git", - "reference": "7655e39c507776c9b9226a8f5619ed9933d3396e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/database/zipball/7655e39c507776c9b9226a8f5619ed9933d3396e", - "reference": "7655e39c507776c9b9226a8f5619ed9933d3396e", - "shasum": "" - }, - "require": { - "illuminate/container": "5.1.*", - "illuminate/contracts": "5.1.*", - "illuminate/support": "5.1.*", - "nesbot/carbon": "~1.19", - "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.1.*).", - "illuminate/events": "Required to use the observers with Eloquent (5.1.*).", - "illuminate/filesystem": "Required to use the migrations (5.1.*)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-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-09-03 14:53:32" - }, - { - "name": "illuminate/events", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/events.git", - "reference": "851c2351401145d81674991fe8491d560e620ec6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/events/zipball/851c2351401145d81674991fe8491d560e620ec6", - "reference": "851c2351401145d81674991fe8491d560e620ec6", - "shasum": "" - }, - "require": { - "illuminate/container": "5.1.*", - "illuminate/contracts": "5.1.*", - "illuminate/support": "5.1.*", - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Events\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Events package.", - "homepage": "http://laravel.com", - "time": "2015-08-08 13:06:30" - }, - { - "name": "illuminate/filesystem", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/filesystem.git", - "reference": "b93043ad8efe4a2ccd0bb202d8493255bb865720" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/filesystem/zipball/b93043ad8efe4a2ccd0bb202d8493255bb865720", - "reference": "b93043ad8efe4a2ccd0bb202d8493255bb865720", - "shasum": "" - }, - "require": { - "illuminate/contracts": "5.1.*", - "illuminate/support": "5.1.*", - "php": ">=5.5.9", - "symfony/finder": "2.7.*" - }, - "suggest": { - "league/flysystem": "Required to use the Flysystem local and FTP drivers (~1.0).", - "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", - "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Filesystem\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Filesystem package.", - "homepage": "http://laravel.com", - "time": "2015-08-24 08:44:48" - }, - { - "name": "illuminate/hashing", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/hashing.git", - "reference": "86d12970c19823809314eae180939de62d4fab2c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/hashing/zipball/86d12970c19823809314eae180939de62d4fab2c", - "reference": "86d12970c19823809314eae180939de62d4fab2c", - "shasum": "" - }, - "require": { - "illuminate/contracts": "5.1.*", - "illuminate/support": "5.1.*", - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Hashing\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Hashing package.", - "homepage": "http://laravel.com", - "time": "2015-07-16 20:28:10" - }, - { - "name": "illuminate/mail", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/mail.git", - "reference": "467d6b7d4b8edbd8acb94248c4b294108773760d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/mail/zipball/467d6b7d4b8edbd8acb94248c4b294108773760d", - "reference": "467d6b7d4b8edbd8acb94248c4b294108773760d", - "shasum": "" - }, - "require": { - "illuminate/container": "5.1.*", - "illuminate/contracts": "5.1.*", - "illuminate/support": "5.1.*", - "php": ">=5.5.9", - "psr/log": "~1.0", - "swiftmailer/swiftmailer": "~5.1" - }, - "suggest": { - "aws/aws-sdk-php": "Required to use the SES mail driver (~3.0).", - "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers (~5.3|~6.0)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Mail\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Mail package.", - "homepage": "http://laravel.com", - "time": "2015-08-08 22:00:02" - }, - { - "name": "illuminate/pipeline", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/pipeline.git", - "reference": "579c8c6f270a13225e26e1801d6797283ecd153a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/pipeline/zipball/579c8c6f270a13225e26e1801d6797283ecd153a", - "reference": "579c8c6f270a13225e26e1801d6797283ecd153a", - "shasum": "" - }, - "require": { - "illuminate/contracts": "5.1.*", - "illuminate/support": "5.1.*", - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Pipeline\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Pipeline package.", - "homepage": "http://laravel.com", - "time": "2015-06-01 15:39:11" - }, - { - "name": "illuminate/support", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/support.git", - "reference": "c5389968d48517b3b51cfd8cd4abd72f0cc1575b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/c5389968d48517b3b51cfd8cd4abd72f0cc1575b", - "reference": "c5389968d48517b3b51cfd8cd4abd72f0cc1575b", - "shasum": "" - }, - "require": { - "danielstjules/stringy": "~1.8", - "doctrine/inflector": "~1.0", - "ext-mbstring": "*", - "illuminate/contracts": "5.1.*", - "php": ">=5.5.9" - }, - "suggest": { - "jeremeamia/superclosure": "Required to be able to serialize closures (~2.0).", - "symfony/var-dumper": "Required to use the dd function (2.7.*)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Support\\": "" - }, - "files": [ - "helpers.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Support package.", - "homepage": "http://laravel.com", - "time": "2015-09-03 15:47:41" - }, - { - "name": "illuminate/validation", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/validation.git", - "reference": "6192667064fd75ff70efb83c6f5366a9edeac275" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/validation/zipball/6192667064fd75ff70efb83c6f5366a9edeac275", - "reference": "6192667064fd75ff70efb83c6f5366a9edeac275", - "shasum": "" - }, - "require": { - "illuminate/container": "5.1.*", - "illuminate/contracts": "5.1.*", - "illuminate/support": "5.1.*", - "php": ">=5.5.9", - "symfony/http-foundation": "2.7.*", - "symfony/translation": "2.7.*" - }, - "suggest": { - "illuminate/database": "Required to use the database presence verifier (5.1.*)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Validation\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate Validation package.", - "homepage": "http://laravel.com", - "time": "2015-08-17 22:03:13" - }, - { - "name": "illuminate/view", - "version": "v5.1.16", - "source": { - "type": "git", - "url": "https://github.com/illuminate/view.git", - "reference": "82c5bc657554360a7325ace0761c24f26de9e771" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/view/zipball/82c5bc657554360a7325ace0761c24f26de9e771", - "reference": "82c5bc657554360a7325ace0761c24f26de9e771", - "shasum": "" - }, - "require": { - "illuminate/container": "5.1.*", - "illuminate/contracts": "5.1.*", - "illuminate/events": "5.1.*", - "illuminate/filesystem": "5.1.*", - "illuminate/support": "5.1.*", - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\View\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Illuminate View package.", - "homepage": "http://laravel.com", - "time": "2015-09-04 12:45:07" - }, - { - "name": "intervention/image", - "version": "2.3.2", - "source": { - "type": "git", - "url": "https://github.com/Intervention/image.git", - "reference": "1124ff3c6298f0dcf9edf9156623904d7a5c3428" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Intervention/image/zipball/1124ff3c6298f0dcf9edf9156623904d7a5c3428", - "reference": "1124ff3c6298f0dcf9edf9156623904d7a5c3428", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "guzzlehttp/psr7": "~1.1", - "php": ">=5.4.0" - }, - "require-dev": { - "mockery/mockery": "~0.9.2", - "phpunit/phpunit": "3.*" - }, - "suggest": { - "ext-gd": "to use GD library based image processing.", - "ext-imagick": "to use Imagick based image processing.", - "intervention/imagecache": "Caching extension for the Intervention Image library" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-4": { - "Intervention\\Image\\": "src/Intervention/Image" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Oliver Vogel", - "email": "oliver@olivervogel.net", - "homepage": "http://olivervogel.net/" - } - ], - "description": "Image handling and manipulation library with support for Laravel integration", - "homepage": "http://image.intervention.io/", - "keywords": [ - "gd", - "image", - "imagick", - "laravel", - "thumbnail", - "watermark" - ], - "time": "2015-08-16 15:31:59" - }, - { - "name": "league/flysystem", - "version": "1.0.15", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem.git", - "reference": "31525caf9e8772683672fefd8a1ca0c0736020f4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/31525caf9e8772683672fefd8a1ca0c0736020f4", - "reference": "31525caf9e8772683672fefd8a1ca0c0736020f4", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "conflict": { - "league/flysystem-sftp": "<1.0.6" - }, - "require-dev": { - "ext-fileinfo": "*", - "mockery/mockery": "~0.9", - "phpspec/phpspec": "^2.2", - "phpspec/prophecy-phpunit": "~1.0", - "phpunit/phpunit": "~4.1" - }, - "suggest": { - "ext-fileinfo": "Required for MimeType", - "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", - "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", - "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", - "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", - "league/flysystem-copy": "Allows you to use Copy.com storage", - "league/flysystem-dropbox": "Allows you to use Dropbox storage", - "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", - "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", - "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", - "league/flysystem-webdav": "Allows you to use WebDAV storage", - "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Flysystem\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frenky.net" - } - ], - "description": "Filesystem abstraction: Many filesystems, one API.", - "keywords": [ - "Cloud Files", - "WebDAV", - "abstraction", - "aws", - "cloud", - "copy.com", - "dropbox", - "file systems", - "files", - "filesystem", - "filesystems", - "ftp", - "rackspace", - "remote", - "s3", - "sftp", - "storage" - ], - "time": "2015-09-30 22:26:59" - }, - { - "name": "matthiasmullie/minify", - "version": "1.3.28", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/minify.git", - "reference": "2cee2544198d97bca4ba094bc2df27d6458da1af" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/2cee2544198d97bca4ba094bc2df27d6458da1af", - "reference": "2cee2544198d97bca4ba094bc2df27d6458da1af", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "matthiasmullie/path-converter": "~1.0", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "4.3.*", - "satooshi/php-coveralls": "dev-master", - "scrapbook/psr-cache": "~0.2" - }, - "bin": [ - "bin/minifycss", - "bin/minifyjs" - ], - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\Minify\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "minify@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "CSS & JS minifier", - "homepage": "http://www.minifier.org", - "keywords": [ - "JS", - "css", - "javascript", - "minifier", - "minify" - ], - "time": "2015-08-20 14:49:37" - }, - { - "name": "matthiasmullie/path-converter", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/path-converter.git", - "reference": "b1e31c51e8c207ad6114f5b4ac4e652bc936c380" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/b1e31c51e8c207ad6114f5b4ac4e652bc936c380", - "reference": "b1e31c51e8c207ad6114f5b4ac4e652bc936c380", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "4.3.*", - "satooshi/php-coveralls": "dev-master" - }, - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\PathConverter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "pathconverter@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "Relative path converter", - "homepage": "http://github.com/matthiasmullie/path-converter", - "keywords": [ - "converter", - "path", - "paths", - "relative" - ], - "time": "2015-06-01 15:20:30" - }, - { - "name": "monolog/monolog", - "version": "1.17.1", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "0524c87587ab85bc4c2d6f5b41253ccb930a5422" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/0524c87587ab85bc4c2d6f5b41253ccb930a5422", - "reference": "0524c87587ab85bc4c2d6f5b41253ccb930a5422", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "psr/log": "~1.0" - }, - "provide": { - "psr/log-implementation": "1.0.0" - }, - "require-dev": { - "aws/aws-sdk-php": "^2.4.9", - "doctrine/couchdb": "~1.0@dev", - "graylog2/gelf-php": "~1.0", - "php-console/php-console": "^3.1.3", - "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "2.3.0", - "raven/raven": "~0.11", - "ruflin/elastica": ">=0.90 <3.0", - "swiftmailer/swiftmailer": "~5.3", - "videlalvaro/php-amqplib": "~2.4" - }, - "suggest": { - "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", - "doctrine/couchdb": "Allow sending log messages to a CouchDB server", - "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-mongo": "Allow sending log messages to a MongoDB server", - "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", - "php-console/php-console": "Allow sending log messages to Google Chrome", - "raven/raven": "Allow sending log messages to a Sentry server", - "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server", - "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.16.x-dev" - } - }, - "autoload": { - "psr-4": { - "Monolog\\": "src/Monolog" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", - "keywords": [ - "log", - "logging", - "psr-3" - ], - "time": "2015-08-31 09:17:37" - }, - { - "name": "nesbot/carbon", - "version": "1.20.0", - "source": { - "type": "git", - "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bfd3eaba109c9a2405c92174c8e17f20c2b9caf3", - "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "symfony/translation": "~2.6|~3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Carbon": "src" - } - }, - "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": "2015-06-25 04:19:39" - }, - { - "name": "nikic/fast-route", - "version": "v0.6.0", - "source": { - "type": "git", - "url": "https://github.com/nikic/FastRoute.git", - "reference": "31fa86924556b80735f98b294a7ffdfb26789f22" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/FastRoute/zipball/31fa86924556b80735f98b294a7ffdfb26789f22", - "reference": "31fa86924556b80735f98b294a7ffdfb26789f22", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "FastRoute\\": "src/" - }, - "files": [ - "src/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov", - "email": "nikic@php.net" - } - ], - "description": "Fast request router for PHP", - "keywords": [ - "router", - "routing" - ], - "time": "2015-06-18 19:15:47" - }, - { - "name": "oyejorge/less.php", - "version": "v1.7.0.9", - "source": { - "type": "git", - "url": "https://github.com/oyejorge/less.php.git", - "reference": "fb64e2f6ef647a229c50e9fa0f2076240a3484c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/oyejorge/less.php/zipball/fb64e2f6ef647a229c50e9fa0f2076240a3484c6", - "reference": "fb64e2f6ef647a229c50e9fa0f2076240a3484c6", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "bin": [ - "bin/lessc" - ], - "type": "library", - "autoload": { - "psr-0": { - "Less": "lib/" - }, - "classmap": [ - "lessc.inc.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Matt Agar", - "homepage": "https://github.com/agar" - }, - { - "name": "Martin Jantošovič", - "homepage": "https://github.com/Mordred" - }, - { - "name": "Josh Schmidt", - "homepage": "https://github.com/oyejorge" - } - ], - "description": "PHP port of the Javascript version of LESS http://lesscss.org", - "homepage": "http://lessphp.gpeasy.com", - "keywords": [ - "css", - "less", - "less.js", - "lesscss", - "php", - "stylesheet" - ], - "time": "2015-09-28 01:11:47" - }, - { - "name": "psr/http-message", - "version": "1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2015-05-04 20:22:00" - }, - { - "name": "psr/log", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-0": { - "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", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2012-12-21 11:40:51" - }, - { - "name": "s9e/text-formatter", - "version": "0.4.2", - "source": { - "type": "git", - "url": "https://github.com/s9e/TextFormatter.git", - "reference": "1f742f17ad0294d52754b9acc6a053e239d26226" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/1f742f17ad0294d52754b9acc6a053e239d26226", - "reference": "1f742f17ad0294d52754b9acc6a053e239d26226", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-filter": "*", - "lib-pcre": ">=7.2", - "php": ">=5.3.3" - }, - "suggest": { - "ext-intl": "Allows international URLs to be accepted by the URL filter", - "ext-json": "Enables the generation of a JavaScript parser", - "ext-mbstring": "Enables some optimizations in the PHP renderer", - "ext-tokenizer": "Enables optimizations in the PHP renderer", - "ext-xsl": "Enables the XSLT renderer", - "ext-zlib": "Enables gzip compression when scraping content via the MediaEmbed plugin" - }, - "type": "library", - "autoload": { - "psr-4": { - "s9e\\TextFormatter\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Multi-purpose text formatting and markup library. Plugins offer support for BBCodes, Markdown, emoticons, HTML, embedding media (YouTube, etc...), enhanced typography and more.", - "homepage": "https://github.com/s9e/TextFormatter/", - "keywords": [ - "bbcode", - "bbcodes", - "blog", - "censor", - "embed", - "emoji", - "emoticons", - "engine", - "forum", - "html", - "markdown", - "markup", - "media", - "parser", - "shortcodes" - ], - "time": "2015-10-04 10:36:14" - }, - { - "name": "swiftmailer/swiftmailer", - "version": "v5.4.1", - "source": { - "type": "git", - "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/0697e6aa65c83edf97bb0f23d8763f94e3f11421", - "reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "mockery/mockery": "~0.9.1,<0.9.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.4-dev" - } - }, - "autoload": { - "files": [ - "lib/swift_required.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Corbyn" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Swiftmailer, free feature-rich PHP mailer", - "homepage": "http://swiftmailer.org", - "keywords": [ - "email", - "mail", - "mailer" - ], - "time": "2015-06-06 14:19:39" - }, - { - "name": "symfony/console", - "version": "v2.7.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "06cb17c013a82f94a3d840682b49425cd00a2161" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/06cb17c013a82f94a3d840682b49425cd00a2161", - "reference": "06cb17c013a82f94a3d840682b49425cd00a2161", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1", - "symfony/phpunit-bridge": "~2.7", - "symfony/process": "~2.1" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - } - }, - "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 Console Component", - "homepage": "https://symfony.com", - "time": "2015-09-25 08:32:23" - }, - { - "name": "symfony/finder", - "version": "v2.7.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "8262ab605973afbb3ef74b945daabf086f58366f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/8262ab605973afbb3ef74b945daabf086f58366f", - "reference": "8262ab605973afbb3ef74b945daabf086f58366f", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - } - }, - "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 Finder Component", - "homepage": "https://symfony.com", - "time": "2015-09-19 19:59:23" - }, - { - "name": "symfony/http-foundation", - "version": "v2.7.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "e1509119f164a0d0a940d7d924d693a7a28a5470" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e1509119f164a0d0a940d7d924d693a7a28a5470", - "reference": "e1509119f164a0d0a940d7d924d693a7a28a5470", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/expression-language": "~2.4", - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "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": "2015-09-22 13:49:29" - }, - { - "name": "symfony/translation", - "version": "v2.7.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "485877661835e188cd78345c6d4eef1290d17571" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/485877661835e188cd78345c6d4eef1290d17571", - "reference": "485877661835e188cd78345c6d4eef1290d17571", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "conflict": { - "symfony/config": "<2.7" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.7", - "symfony/intl": "~2.4", - "symfony/phpunit-bridge": "~2.7", - "symfony/yaml": "~2.2" - }, - "suggest": { - "psr/log": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Translation\\": "" - } - }, - "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": "2015-09-06 08:36:38" - }, - { - "name": "symfony/yaml", - "version": "v2.7.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "31cb2ad0155c95b88ee55fe12bc7ff92232c1770" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/31cb2ad0155c95b88ee55fe12bc7ff92232c1770", - "reference": "31cb2ad0155c95b88ee55fe12bc7ff92232c1770", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "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 Yaml Component", - "homepage": "https://symfony.com", - "time": "2015-09-14 14:14:09" - }, - { - "name": "tobscure/json-api", - "version": "0.2.x-dev", - "source": { - "type": "git", - "url": "https://github.com/tobscure/json-api.git", - "reference": "e26093389685de3c0c67f4d50145ddd12f967e1b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tobscure/json-api/zipball/e26093389685de3c0c67f4d50145ddd12f967e1b", - "reference": "e26093389685de3c0c67f4d50145ddd12f967e1b", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "Tobscure\\JsonApi\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Toby Zerner", - "email": "toby.zerner@gmail.com" - } - ], - "description": "JSON-API responses in PHP", - "keywords": [ - "api", - "json", - "jsonapi", - "standard" - ], - "time": "2015-10-08 02:08:53" - }, - { - "name": "zendframework/zend-diactoros", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "e2f5c12916c74da384058d0dfbc7fbc0b03d1181" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/e2f5c12916c74da384058d0dfbc7fbc0b03d1181", - "reference": "e2f5c12916c74da384058d0dfbc7fbc0b03d1181", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "~1.0.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.6", - "squizlabs/php_codesniffer": "^2.3.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev", - "dev-develop": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Diactoros\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "description": "PSR HTTP Message implementations", - "homepage": "https://github.com/zendframework/zend-diactoros", - "keywords": [ - "http", - "psr", - "psr-7" - ], - "time": "2015-08-10 20:04:20" - }, - { - "name": "zendframework/zend-escaper", - "version": "2.5.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-escaper.git", - "reference": "a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73", - "reference": "a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73", - "shasum": "" - }, - "require": { - "php": ">=5.3.23" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Escaper\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-escaper", - "keywords": [ - "escaper", - "zf2" - ], - "time": "2015-06-03 14:05:37" - }, - { - "name": "zendframework/zend-stratigility", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-stratigility.git", - "reference": "6a3b7e601dfe7eca0652a8b7f1a469ff4b8f3c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stratigility/zipball/6a3b7e601dfe7eca0652a8b7f1a469ff4b8f3c28", - "reference": "6a3b7e601dfe7eca0652a8b7f1a469ff4b8f3c28", - "shasum": "" - }, - "require": { - "php": ">=5.4.8", - "psr/http-message": "~1.0.0", - "zendframework/zend-escaper": "~2.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.7", - "squizlabs/php_codesniffer": "^2.3.1", - "zendframework/zend-diactoros": "~1.0" - }, - "suggest": { - "psr/http-message-implementation": "Please install a psr/http-message-implementation to consume Stratigility; e.g., zendframework/zend-diactoros" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev", - "dev-develop": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Stratigility\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Middleware for PHP", - "homepage": "https://github.com/zendframework/zend-stratigility", - "keywords": [ - "http", - "middleware", - "psr-7" - ], - "time": "2015-08-25 18:39:13" - } - ], - "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", - "shasum": "" - }, - "require": { - "php": ">=5.3,<8.0-DEV" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2015-06-14 21:17:01" - }, - { - "name": "hamcrest/hamcrest-php", - "version": "v1.2.2", - "source": { - "type": "git", - "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", - "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "replace": { - "cordoval/hamcrest-php": "*", - "davedevelopment/hamcrest-php": "*", - "kodova/hamcrest-php": "*" - }, - "require-dev": { - "phpunit/php-file-iterator": "1.3.3", - "satooshi/php-coveralls": "dev-master" - }, - "type": "library", - "autoload": { - "classmap": [ - "hamcrest" - ], - "files": [ - "hamcrest/Hamcrest.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD" - ], - "description": "This is the PHP port of Hamcrest Matchers", - "keywords": [ - "test" - ], - "time": "2015-05-11 14:41:42" - }, - { - "name": "mockery/mockery", - "version": "0.9.4", - "source": { - "type": "git", - "url": "https://github.com/padraic/mockery.git", - "reference": "70bba85e4aabc9449626651f48b9018ede04f86b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/padraic/mockery/zipball/70bba85e4aabc9449626651f48b9018ede04f86b", - "reference": "70bba85e4aabc9449626651f48b9018ede04f86b", - "shasum": "" - }, - "require": { - "hamcrest/hamcrest-php": "~1.1", - "lib-pcre": ">=7.0", - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.9.x-dev" - } - }, - "autoload": { - "psr-0": { - "Mockery": "library/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Pádraic Brady", - "email": "padraic.brady@gmail.com", - "homepage": "http://blog.astrumfutura.com" - }, - { - "name": "Dave Marshall", - "email": "dave.marshall@atstsolutions.co.uk", - "homepage": "http://davedevelopment.co.uk" - } - ], - "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", - "homepage": "http://github.com/padraic/mockery", - "keywords": [ - "BDD", - "TDD", - "library", - "mock", - "mock objects", - "mockery", - "stub", - "test", - "test double", - "testing" - ], - "time": "2015-04-02 19:54:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "time": "2015-02-03 12:10:50" - }, - { - "name": "phpspec/prophecy", - "version": "v1.5.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", - "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "phpdocumentor/reflection-docblock": "~2.0", - "sebastian/comparator": "~1.1" - }, - "require-dev": { - "phpspec/phpspec": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2015-08-13 10:07:40" - }, - { - "name": "phpunit/php-code-coverage", - "version": "2.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2015-10-06 15:47:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2015-06-21 13:08:43" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21 13:50:34" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2015-06-21 08:01:12" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.4.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2015-09-15 10:49:45" - }, - { - "name": "phpunit/phpunit", - "version": "4.8.11", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bdd199472410fd7e32751f9c814c7e06f2c21bd5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bdd199472410fd7e32751f9c814c7e06f2c21bd5", - "reference": "bdd199472410fd7e32751f9c814c7e06f2c21bd5", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": ">=1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.1", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.8.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2015-10-07 10:39:46" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2015-10-02 06:51:40" - }, - { - "name": "sebastian/comparator", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2015-07-26 15:48:44" - }, - { - "name": "sebastian/diff", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2015-02-22 15:13:53" - }, - { - "name": "sebastian/environment", - "version": "1.3.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44", - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2015-08-03 06:14:51" - }, - { - "name": "sebastian/exporter", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2015-06-21 07:55:53" - }, - { - "name": "sebastian/global-state", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2014-10-06 09:23:50" - }, - { - "name": "sebastian/recursion-context", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba", - "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-06-21 08:04:50" - }, - { - "name": "sebastian/version", - "version": "1.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-06-21 13:59:46" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "2.3.4", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "11a2545c44a5915f883e2e5ec12e14ed345e3ab2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/11a2545c44a5915f883e2e5ec12e14ed345e3ab2", - "reference": "11a2545c44a5915f883e2e5ec12e14ed345e3ab2", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.1.2" - }, - "bin": [ - "scripts/phpcs", - "scripts/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "CodeSniffer.php", - "CodeSniffer/CLI.php", - "CodeSniffer/Exception.php", - "CodeSniffer/File.php", - "CodeSniffer/Fixer.php", - "CodeSniffer/Report.php", - "CodeSniffer/Reporting.php", - "CodeSniffer/Sniff.php", - "CodeSniffer/Tokens.php", - "CodeSniffer/Reports/", - "CodeSniffer/Tokenizers/", - "CodeSniffer/DocGenerators/", - "CodeSniffer/Standards/AbstractPatternSniff.php", - "CodeSniffer/Standards/AbstractScopeSniff.php", - "CodeSniffer/Standards/AbstractVariableSniff.php", - "CodeSniffer/Standards/IncorrectPatternException.php", - "CodeSniffer/Standards/Generic/Sniffs/", - "CodeSniffer/Standards/MySource/Sniffs/", - "CodeSniffer/Standards/PEAR/Sniffs/", - "CodeSniffer/Standards/PSR1/Sniffs/", - "CodeSniffer/Standards/PSR2/Sniffs/", - "CodeSniffer/Standards/Squiz/Sniffs/", - "CodeSniffer/Standards/Zend/Sniffs/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", - "keywords": [ - "phpcs", - "standards" - ], - "time": "2015-09-09 00:18:50" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "tobscure/json-api": 20, - "franzl/whoops-middleware": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.5.9" - }, - "platform-dev": [] -} diff --git a/framework/core/js/admin/src/components/PermissionGrid.js b/framework/core/js/admin/src/components/PermissionGrid.js index b3849eec9..25dd7fcc8 100644 --- a/framework/core/js/admin/src/components/PermissionGrid.js +++ b/framework/core/js/admin/src/components/PermissionGrid.js @@ -123,7 +123,7 @@ export default class PermissionGrid extends Component { return SettingDropdown.component({ defaultLabel: minutes - ? app.trans('core.admin.permissions_allow_some_minutes_button', {count: minutes}) + ? app.translator.transChoice('core.admin.permissions_allow_some_minutes_button', minutes, {count: minutes}) : app.trans('core.admin.permissions_allow_indefinitely_button'), key: 'allow_renaming', options: [ @@ -155,7 +155,7 @@ export default class PermissionGrid extends Component { return SettingDropdown.component({ defaultLabel: minutes - ? app.trans('core.admin.permissions_allow_some_minutes_button', {count: minutes}) + ? app.translator.transChoice('core.admin.permissions_allow_some_minutes_button', minutes, {count: minutes}) : app.trans('core.admin.permissions_allow_indefinitely_button'), key: 'allow_post_editing', options: [ diff --git a/framework/core/js/forum/src/components/PostStreamScrubber.js b/framework/core/js/forum/src/components/PostStreamScrubber.js index e849df409..c5816e475 100644 --- a/framework/core/js/forum/src/components/PostStreamScrubber.js +++ b/framework/core/js/forum/src/components/PostStreamScrubber.js @@ -66,12 +66,13 @@ export default class PostStreamScrubber extends Component { view() { const retain = this.subtree.retain(); + const count = this.count(); const unreadCount = this.props.stream.discussion.unreadCount(); - const unreadPercent = Math.min(this.count() - this.index, unreadCount) / this.count(); + const unreadPercent = Math.min(count - this.index, unreadCount) / count; - const viewing = app.trans('core.forum.post_scrubber_viewing_text', { + const viewing = app.translator.transChoice('core.forum.post_scrubber_viewing_text', count, { index: {retain || formatNumber(this.visibleIndex())}, - count: {formatNumber(this.count())} + count: {formatNumber(count)} }); function styleUnread(element, isInitialized, context) { diff --git a/framework/core/js/lib/App.js b/framework/core/js/lib/App.js index b6ddfb612..08bf62f8c 100644 --- a/framework/core/js/lib/App.js +++ b/framework/core/js/lib/App.js @@ -125,6 +125,8 @@ export default class App { * @public */ boot() { + this.translator.locale = this.locale; + this.initializers.toArray().forEach(initializer => initializer(this)); } @@ -149,8 +151,6 @@ export default class App { * Set the of the page. * * @param {String} title - * @param {Boolean} [separator] Whether or not to separate the given title and - * the forum's title. * @public */ setTitle(title) { diff --git a/framework/core/js/lib/Translator.js b/framework/core/js/lib/Translator.js index d4f9f70b3..1f665634a 100644 --- a/framework/core/js/lib/Translator.js +++ b/framework/core/js/lib/Translator.js @@ -4,7 +4,11 @@ import extractText from 'flarum/utils/extractText'; import extract from 'flarum/utils/extract'; /** - * The `Translator` class translates strings using the loaded localization. + * Translator with the same API as Symfony's. + * + * Derived from https://github.com/willdurand/BazingaJsTranslationBundle + * which is available under the MIT License. + * Copyright (c) William Durand <william.durand1@gmail.com> */ export default class Translator { constructor() { @@ -15,46 +19,35 @@ export default class Translator { * @public */ this.translations = {}; + + this.locale = null; } - /** - * Determine the key of a translation that should be used for the given count. - * The default implementation is for English plurals. It should be overridden - * by a locale's JavaScript file if necessary. - * - * @param {Integer} count - * @return {String} - * @public - */ - plural(count) { - return count === 1 ? 'one' : 'other'; - } + trans(id, parameters) { + const translation = this.translations[id]; - /** - * Translate a string. - * - * @param {String} key - * @param {Object} input - * @param {VirtualElement} fallback - * @return {VirtualElement} - */ - trans(key, input = {}, fallback = null) { - const parts = key.split('.'); - let translation = this.translations; - - // Drill down into the translation tree to find the translation for this - // key. - parts.forEach(part => { - translation = translation && translation[part]; - }); - - // If this translation has multiple options and a 'count' has been provided - // in the input, we'll work out which option to choose using the `plural` - // method. - if (translation && typeof translation === 'object' && typeof input.count !== 'undefined') { - translation = translation[this.plural(extractText(input.count))]; + if (translation) { + return this.apply(translation, parameters || {}); } + return id; + } + + transChoice(id, number, parameters) { + let translation = this.translations[id]; + + if (translation) { + number = parseInt(number, 10); + + translation = this.pluralize(translation, number); + + return this.apply(translation, parameters || {}); + } + + return id; + } + + apply(translation, input) { // If we've been given a user model as one of the input parameters, then // we'll extract the username and use that for the translation. In the // future there should be a hook here to inspect the user and change the @@ -66,37 +59,226 @@ export default class Translator { if (!input.username) input.username = username(user); } - // If we've found the appropriate translation string, then we'll sub in the - // input. - if (typeof translation === 'string') { - translation = translation.split(new RegExp('({[a-z0-9_]+}|</?[a-z0-9_]+>)', 'gi')); + translation = translation.split(new RegExp('({[a-z0-9_]+}|</?[a-z0-9_]+>)', 'gi')); - const hydrated = []; - const open = [hydrated]; + const hydrated = []; + const open = [hydrated]; - translation.forEach(part => { - const match = part.match(new RegExp('{([a-z0-9_]+)}|<(/?)([a-z0-9_]+)>', 'i')); + translation.forEach(part => { + const match = part.match(new RegExp('{([a-z0-9_]+)}|<(/?)([a-z0-9_]+)>', 'i')); - if (match) { - if (match[1]) { - open[0].push(input[match[1]]); - } else if (match[3]) { - if (match[2]) { - open.shift(); - } else { - let tag = input[match[3]] || []; - open[0].push(tag); - open.unshift(tag.children || tag); + if (match) { + if (match[1]) { + open[0].push(input[match[1]]); + } else if (match[3]) { + if (match[2]) { + open.shift(); + } else { + let tag = input[match[3]] || []; + open[0].push(tag); + open.unshift(tag.children || tag); + } + } + } else { + open[0].push(part); + } + }); + + return hydrated.filter(part => part); + } + + pluralize(translation, number) { + const sPluralRegex = new RegExp(/^\w+\: +(.+)$/), + cPluralRegex = new RegExp(/^\s*((\{\s*(\-?\d+[\s*,\s*\-?\d+]*)\s*\})|([\[\]])\s*(-Inf|\-?\d+)\s*,\s*(\+?Inf|\-?\d+)\s*([\[\]]))\s?(.+?)$/), + iPluralRegex = new RegExp(/^\s*(\{\s*(\-?\d+[\s*,\s*\-?\d+]*)\s*\})|([\[\]])\s*(-Inf|\-?\d+)\s*,\s*(\+?Inf|\-?\d+)\s*([\[\]])/), + standardRules = [], + explicitRules = []; + + translation.split('|').forEach(part => { + if (cPluralRegex.test(part)) { + const matches = part.match(cPluralRegex); + explicitRules[matches[0]] = matches[matches.length - 1]; + } else if (sPluralRegex.test(part)) { + const matches = part.match(sPluralRegex); + standardRules.push(matches[1]); + } else { + standardRules.push(part); + } + }); + + explicitRules.forEach((rule, e) => { + if (iPluralRegex.test(e)) { + const matches = e.match(iPluralRegex); + + if (matches[1]) { + const ns = matches[2].split(','); + + for (let n in ns) { + if (number == ns[n]) { + return explicitRules[e]; } } } else { - open[0].push(part); - } - }); + var leftNumber = this.convertNumber(matches[4]); + var rightNumber = this.convertNumber(matches[5]); - return hydrated.filter(part => part); + if (('[' === matches[3] ? number >= leftNumber : number > leftNumber) && + (']' === matches[6] ? number <= rightNumber : number < rightNumber)) { + return explicitRules[e]; + } + } + } + }); + + return standardRules[this.pluralPosition(number, this.locale)] || standardRules[0] || undefined; + } + + convertNumber(number) { + if ('-Inf' === number) { + return Number.NEGATIVE_INFINITY; + } else if ('+Inf' === number || 'Inf' === number) { + return Number.POSITIVE_INFINITY; } - return fallback || [key]; + return parseInt(number, 10); + } + + pluralPosition(number, locale) { + if ('pt_BR' === locale) { + locale = 'xbr'; + } + + if (locale.length > 3) { + locale = locale.split('_')[0]; + } + + switch (locale) { + case 'bo': + case 'dz': + case 'id': + case 'ja': + case 'jv': + case 'ka': + case 'km': + case 'kn': + case 'ko': + case 'ms': + case 'th': + case 'tr': + case 'vi': + case 'zh': + return 0; + case 'af': + case 'az': + case 'bn': + case 'bg': + case 'ca': + case 'da': + case 'de': + case 'el': + case 'en': + case 'eo': + case 'es': + case 'et': + case 'eu': + case 'fa': + case 'fi': + case 'fo': + case 'fur': + case 'fy': + case 'gl': + case 'gu': + case 'ha': + case 'he': + case 'hu': + case 'is': + case 'it': + case 'ku': + case 'lb': + case 'ml': + case 'mn': + case 'mr': + case 'nah': + case 'nb': + case 'ne': + case 'nl': + case 'nn': + case 'no': + case 'om': + case 'or': + case 'pa': + case 'pap': + case 'ps': + case 'pt': + case 'so': + case 'sq': + case 'sv': + case 'sw': + case 'ta': + case 'te': + case 'tk': + case 'ur': + case 'zu': + return (number == 1) ? 0 : 1; + + case 'am': + case 'bh': + case 'fil': + case 'fr': + case 'gun': + case 'hi': + case 'ln': + case 'mg': + case 'nso': + case 'xbr': + case 'ti': + case 'wa': + return ((number === 0) || (number == 1)) ? 0 : 1; + + case 'be': + case 'bs': + case 'hr': + case 'ru': + case 'sr': + case 'uk': + return ((number % 10 == 1) && (number % 100 != 11)) ? 0 : (((number % 10 >= 2) && (number % 10 <= 4) && ((number % 100 < 10) || (number % 100 >= 20))) ? 1 : 2); + + case 'cs': + case 'sk': + return (number == 1) ? 0 : (((number >= 2) && (number <= 4)) ? 1 : 2); + + case 'ga': + return (number == 1) ? 0 : ((number == 2) ? 1 : 2); + + case 'lt': + return ((number % 10 == 1) && (number % 100 != 11)) ? 0 : (((number % 10 >= 2) && ((number % 100 < 10) || (number % 100 >= 20))) ? 1 : 2); + + case 'sl': + return (number % 100 == 1) ? 0 : ((number % 100 == 2) ? 1 : (((number % 100 == 3) || (number % 100 == 4)) ? 2 : 3)); + + case 'mk': + return (number % 10 == 1) ? 0 : 1; + + case 'mt': + return (number == 1) ? 0 : (((number === 0) || ((number % 100 > 1) && (number % 100 < 11))) ? 1 : (((number % 100 > 10) && (number % 100 < 20)) ? 2 : 3)); + + case 'lv': + return (number === 0) ? 0 : (((number % 10 == 1) && (number % 100 != 11)) ? 1 : 2); + + case 'pl': + return (number == 1) ? 0 : (((number % 10 >= 2) && (number % 10 <= 4) && ((number % 100 < 12) || (number % 100 > 14))) ? 1 : 2); + + case 'cy': + return (number == 1) ? 0 : ((number == 2) ? 1 : (((number == 8) || (number == 11)) ? 2 : 3)); + + case 'ro': + return (number == 1) ? 0 : (((number === 0) || ((number % 100 > 0) && (number % 100 < 20))) ? 1 : 2); + + case 'ar': + return (number === 0) ? 0 : ((number == 1) ? 1 : ((number == 2) ? 2 : (((number >= 3) && (number <= 10)) ? 3 : (((number >= 11) && (number <= 99)) ? 4 : 5)))); + + default: + return 0; + } } } diff --git a/framework/core/src/Admin/Controller/ClientController.php b/framework/core/src/Admin/Controller/ClientController.php index d5826e181..61a0aaa66 100644 --- a/framework/core/src/Admin/Controller/ClientController.php +++ b/framework/core/src/Admin/Controller/ClientController.php @@ -13,13 +13,13 @@ namespace Flarum\Admin\Controller; use Flarum\Foundation\Application; use Flarum\Http\Controller\AbstractClientController as BaseClientController; use Flarum\Extension\ExtensionManager; +use Flarum\Locale\LocaleManager; use Illuminate\Contracts\Cache\Repository; use Illuminate\Contracts\Events\Dispatcher; use Psr\Http\Message\ServerRequestInterface as Request; use Flarum\Core\Permission; use Flarum\Api\Client; use Flarum\Settings\SettingsRepository; -use Flarum\Locale\LocaleManager; use Flarum\Event\PrepareUnserializedSettings; class ClientController extends BaseClientController diff --git a/framework/core/src/Api/Middleware/AuthenticateWithHeader.php b/framework/core/src/Api/Middleware/AuthenticateWithHeader.php index 6385ec722..c76d42f4f 100644 --- a/framework/core/src/Api/Middleware/AuthenticateWithHeader.php +++ b/framework/core/src/Api/Middleware/AuthenticateWithHeader.php @@ -14,6 +14,7 @@ use Flarum\Api\AccessToken; use Flarum\Api\ApiKey; use Flarum\Core\Guest; use Flarum\Core\User; +use Flarum\Locale\LocaleManager; use Illuminate\Contracts\Container\Container; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; @@ -21,22 +22,22 @@ use Zend\Stratigility\MiddlewareInterface; class AuthenticateWithHeader implements MiddlewareInterface { - /** - * @var Container - */ - protected $app; - /** * @var string */ protected $prefix = 'Token '; /** - * @param Container $app + * @var LocaleManager */ - public function __construct(Container $app) + protected $locales; + + /** + * @param LocaleManager $locales + */ + public function __construct(LocaleManager $locales) { - $this->app = $app; + $this->locales = $locales; } /** @@ -59,24 +60,34 @@ class AuthenticateWithHeader implements MiddlewareInterface $parts = explode(';', $header); + $actor = new Guest; + if (isset($parts[0]) && starts_with($parts[0], $this->prefix)) { $token = substr($parts[0], strlen($this->prefix)); if (($accessToken = AccessToken::find($token)) && $accessToken->isValid()) { - $user = $accessToken->user; + $actor = $accessToken->user; - $user->updateLastSeen()->save(); - - return $request->withAttribute('actor', $user); + $actor->updateLastSeen()->save(); } elseif (isset($parts[1]) && ($apiKey = ApiKey::valid($token))) { $userParts = explode('=', trim($parts[1])); if (isset($userParts[0]) && $userParts[0] === 'userId') { - return $request->withAttribute('actor', $user = User::find($userParts[1])); + $actor = User::find($userParts[1]); } } } - return $request->withAttribute('actor', new Guest); + if ($actor->exists) { + $locale = $actor->getPreference('locale'); + } else { + $locale = array_get($request->getCookieParams(), 'locale'); + } + + if ($locale && $this->locales->hasLocale($locale)) { + $this->locales->setLocale($locale); + } + + return $request->withAttribute('actor', $actor ?: new Guest); } } diff --git a/framework/core/src/Core/Command/CreateGroupHandler.php b/framework/core/src/Core/Command/CreateGroupHandler.php index b9753910d..1731e06c3 100644 --- a/framework/core/src/Core/Command/CreateGroupHandler.php +++ b/framework/core/src/Core/Command/CreateGroupHandler.php @@ -13,6 +13,7 @@ namespace Flarum\Core\Command; use Flarum\Core\Access\AssertPermissionTrait; use Flarum\Core\Exception\PermissionDeniedException; use Flarum\Core\Group; +use Flarum\Core\Validator\GroupValidator; use Flarum\Event\GroupWillBeSaved; use Flarum\Core\Support\DispatchEventsTrait; use Illuminate\Contracts\Events\Dispatcher; @@ -23,11 +24,18 @@ class CreateGroupHandler use AssertPermissionTrait; /** - * @param Dispatcher $events + * @var GroupValidator */ - public function __construct(Dispatcher $events) + protected $validator; + + /** + * @param Dispatcher $events + * @param GroupValidator $validator + */ + public function __construct(Dispatcher $events, GroupValidator $validator) { $this->events = $events; + $this->validator = $validator; } /** @@ -53,6 +61,8 @@ class CreateGroupHandler new GroupWillBeSaved($group, $actor, $data) ); + $this->validator->assertValid($group->getAttributes()); + $group->save(); $this->dispatchEventsFor($group, $actor); diff --git a/framework/core/src/Core/Command/EditDiscussionHandler.php b/framework/core/src/Core/Command/EditDiscussionHandler.php index af9a888ee..a18c11eb6 100644 --- a/framework/core/src/Core/Command/EditDiscussionHandler.php +++ b/framework/core/src/Core/Command/EditDiscussionHandler.php @@ -14,6 +14,7 @@ use Flarum\Core\Access\AssertPermissionTrait; use Flarum\Core\Exception\PermissionDeniedException; use Flarum\Core\Repository\DiscussionRepository; use Flarum\Core\Support\DispatchEventsTrait; +use Flarum\Core\Validator\DiscussionValidator; use Flarum\Event\DiscussionWillBeSaved; use Illuminate\Contracts\Events\Dispatcher; @@ -27,14 +28,21 @@ class EditDiscussionHandler */ protected $discussions; + /** + * @var DiscussionValidator + */ + protected $validator; + /** * @param Dispatcher $events * @param DiscussionRepository $discussions + * @param DiscussionValidator $validator */ - public function __construct(Dispatcher $events, DiscussionRepository $discussions) + public function __construct(Dispatcher $events, DiscussionRepository $discussions, DiscussionValidator $validator) { $this->events = $events; $this->discussions = $discussions; + $this->validator = $validator; } /** @@ -70,6 +78,8 @@ class EditDiscussionHandler new DiscussionWillBeSaved($discussion, $actor, $data) ); + $this->validator->assertValid($discussion->getDirty()); + $discussion->save(); $this->dispatchEventsFor($discussion, $actor); diff --git a/framework/core/src/Core/Command/EditGroupHandler.php b/framework/core/src/Core/Command/EditGroupHandler.php index 4760de3b9..a556d93a3 100644 --- a/framework/core/src/Core/Command/EditGroupHandler.php +++ b/framework/core/src/Core/Command/EditGroupHandler.php @@ -14,6 +14,7 @@ use Flarum\Core\Access\AssertPermissionTrait; use Flarum\Core\Exception\PermissionDeniedException; use Flarum\Core\Group; use Flarum\Core\Repository\GroupRepository; +use Flarum\Core\Validator\GroupValidator; use Flarum\Event\GroupWillBeSaved; use Flarum\Core\Support\DispatchEventsTrait; use Illuminate\Contracts\Events\Dispatcher; @@ -28,14 +29,21 @@ class EditGroupHandler */ protected $groups; + /** + * @var GroupValidator + */ + protected $validator; + /** * @param Dispatcher $events * @param GroupRepository $groups + * @param GroupValidator $validator */ - public function __construct(Dispatcher $events, GroupRepository $groups) + public function __construct(Dispatcher $events, GroupRepository $groups, GroupValidator $validator) { $this->events = $events; $this->groups = $groups; + $this->validator = $validator; } /** @@ -70,6 +78,8 @@ class EditGroupHandler new GroupWillBeSaved($group, $actor, $data) ); + $this->validator->assertValid($group->getDirty()); + $group->save(); $this->dispatchEventsFor($group, $actor); diff --git a/framework/core/src/Core/Command/EditPostHandler.php b/framework/core/src/Core/Command/EditPostHandler.php index ab7767ff5..9a18d0e0a 100644 --- a/framework/core/src/Core/Command/EditPostHandler.php +++ b/framework/core/src/Core/Command/EditPostHandler.php @@ -12,6 +12,7 @@ namespace Flarum\Core\Command; use Flarum\Core\Access\AssertPermissionTrait; use Flarum\Core\Repository\PostRepository; +use Flarum\Core\Validator\PostValidator; use Flarum\Event\PostWillBeSaved; use Flarum\Core\Support\DispatchEventsTrait; use Flarum\Core\Post\CommentPost; @@ -27,14 +28,21 @@ class EditPostHandler */ protected $posts; + /** + * @var PostValidator + */ + protected $validator; + /** * @param Dispatcher $events * @param PostRepository $posts + * @param PostValidator $validator */ - public function __construct(Dispatcher $events, PostRepository $posts) + public function __construct(Dispatcher $events, PostRepository $posts, PostValidator $validator) { $this->events = $events; $this->posts = $posts; + $this->validator = $validator; } /** @@ -73,6 +81,8 @@ class EditPostHandler new PostWillBeSaved($post, $actor, $data) ); + $this->validator->assertValid($post->getDirty()); + $post->save(); $this->dispatchEventsFor($post, $actor); diff --git a/framework/core/src/Core/Command/EditUserHandler.php b/framework/core/src/Core/Command/EditUserHandler.php index bc13860fa..83fb0298d 100644 --- a/framework/core/src/Core/Command/EditUserHandler.php +++ b/framework/core/src/Core/Command/EditUserHandler.php @@ -13,6 +13,7 @@ namespace Flarum\Core\Command; use Flarum\Core\Access\AssertPermissionTrait; use Flarum\Core\User; use Flarum\Core\Repository\UserRepository; +use Flarum\Core\Validator\UserValidator; use Flarum\Event\UserWillBeSaved; use Flarum\Event\UserGroupsWereChanged; use Flarum\Core\Support\DispatchEventsTrait; @@ -28,14 +29,21 @@ class EditUserHandler */ protected $users; + /** + * @var UserValidator + */ + protected $validator; + /** * @param Dispatcher $events * @param UserRepository $users + * @param UserValidator $validator */ - public function __construct(Dispatcher $events, UserRepository $users) + public function __construct(Dispatcher $events, UserRepository $users, UserValidator $validator) { $this->events = $events; $this->users = $users; + $this->validator = $validator; } /** @@ -119,6 +127,8 @@ class EditUserHandler new UserWillBeSaved($user, $actor, $data) ); + $this->validator->assertValid(array_merge($user->getDirty(), array_only($attributes, ['password', 'email']))); + $user->save(); $this->dispatchEventsFor($user, $actor); diff --git a/framework/core/src/Core/Command/PostReplyHandler.php b/framework/core/src/Core/Command/PostReplyHandler.php index 869ea4a64..78dda1bd5 100644 --- a/framework/core/src/Core/Command/PostReplyHandler.php +++ b/framework/core/src/Core/Command/PostReplyHandler.php @@ -11,6 +11,7 @@ namespace Flarum\Core\Command; use Flarum\Core\Access\AssertPermissionTrait; +use Flarum\Core\Validator\PostValidator; use Flarum\Event\PostWillBeSaved; use Flarum\Core\Repository\DiscussionRepository; use Flarum\Core\Post\CommentPost; @@ -33,19 +34,27 @@ class PostReplyHandler */ protected $notifications; + /** + * @var PostValidator + */ + protected $validator; + /** * @param Dispatcher $events * @param DiscussionRepository $discussions * @param NotificationSyncer $notifications + * @param PostValidator $validator */ public function __construct( Dispatcher $events, DiscussionRepository $discussions, - NotificationSyncer $notifications + NotificationSyncer $notifications, + PostValidator $validator ) { $this->events = $events; $this->discussions = $discussions; $this->notifications = $notifications; + $this->validator = $validator; } /** @@ -79,6 +88,8 @@ class PostReplyHandler new PostWillBeSaved($post, $actor, $command->data) ); + $this->validator->assertValid($post->getAttributes()); + $post->save(); $this->notifications->onePerUser(function () use ($post, $actor) { diff --git a/framework/core/src/Core/Command/RegisterUserHandler.php b/framework/core/src/Core/Command/RegisterUserHandler.php index 04c0e19bd..d4b3dd8b9 100644 --- a/framework/core/src/Core/Command/RegisterUserHandler.php +++ b/framework/core/src/Core/Command/RegisterUserHandler.php @@ -13,6 +13,7 @@ namespace Flarum\Core\Command; use Flarum\Core\Access\AssertPermissionTrait; use Flarum\Core\User; use Flarum\Core\AuthToken; +use Flarum\Core\Validator\UserValidator; use Flarum\Event\UserWillBeSaved; use Flarum\Core\Support\DispatchEventsTrait; use Flarum\Settings\SettingsRepository; @@ -29,14 +30,21 @@ class RegisterUserHandler */ protected $settings; + /** + * @var UserValidator + */ + protected $validator; + /** * @param Dispatcher $events * @param SettingsRepository $settings + * @param UserValidator $validator */ - public function __construct(Dispatcher $events, SettingsRepository $settings) + public function __construct(Dispatcher $events, SettingsRepository $settings, UserValidator $validator) { $this->events = $events; $this->settings = $settings; + $this->validator = $validator; } /** @@ -88,6 +96,8 @@ class RegisterUserHandler new UserWillBeSaved($user, $actor, $data) ); + $this->validator->assertValid(array_merge($user->getAttributes(), compact('password'))); + $user->save(); if (isset($token)) { diff --git a/framework/core/src/Core/Command/StartDiscussionHandler.php b/framework/core/src/Core/Command/StartDiscussionHandler.php index 08580309d..bfd2f2f5c 100644 --- a/framework/core/src/Core/Command/StartDiscussionHandler.php +++ b/framework/core/src/Core/Command/StartDiscussionHandler.php @@ -14,6 +14,7 @@ use Exception; use Flarum\Core\Access\AssertPermissionTrait; use Flarum\Core\Discussion; use Flarum\Core\Support\DispatchEventsTrait; +use Flarum\Core\Validator\DiscussionValidator; use Flarum\Event\DiscussionWillBeSaved; use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher; use Illuminate\Contracts\Events\Dispatcher as EventDispatcher; @@ -28,15 +29,22 @@ class StartDiscussionHandler */ protected $bus; + /** + * @var DiscussionValidator + */ + protected $validator; + /** * @param EventDispatcher $events * @param BusDispatcher $bus + * @param DiscussionValidator $validator * @internal param Forum $forum */ - public function __construct(EventDispatcher $events, BusDispatcher $bus) + public function __construct(EventDispatcher $events, BusDispatcher $bus, DiscussionValidator $validator) { $this->events = $events; $this->bus = $bus; + $this->validator = $validator; } /** @@ -64,6 +72,8 @@ class StartDiscussionHandler new DiscussionWillBeSaved($discussion, $actor, $data) ); + $this->validator->assertValid($discussion->getAttributes()); + $discussion->save(); // Now that the discussion has been created, we can add the first post. diff --git a/framework/core/src/Core/CoreServiceProvider.php b/framework/core/src/Core/CoreServiceProvider.php index bba685fd9..f735aa770 100644 --- a/framework/core/src/Core/CoreServiceProvider.php +++ b/framework/core/src/Core/CoreServiceProvider.php @@ -85,10 +85,6 @@ class CoreServiceProvider extends AbstractServiceProvider User::setHasher($this->app->make('hash')); User::setGate($this->app->make('flarum.gate')); - $this->validateModelWith(User::class, 'Flarum\Core\Validator\UserValidator'); - $this->validateModelWith(Group::class, 'Flarum\Core\Validator\GroupValidator'); - $this->validateModelWith(Post::class, 'Flarum\Core\Validator\PostValidator'); - $events = $this->app->make('events'); $events->subscribe('Flarum\Core\Listener\DiscussionMetadataUpdater'); @@ -129,15 +125,4 @@ class CoreServiceProvider extends AbstractServiceProvider $event->add('indexProfile', 'boolval', true); $event->add('locale'); } - - /** - * @param string $model - * @param string $validator - */ - protected function validateModelWith($model, $validator) - { - $model::saving(function ($model) use ($validator) { - $this->app->make($validator)->assertValid($model); - }); - } } diff --git a/framework/core/src/Core/User.php b/framework/core/src/Core/User.php index 78ba87eca..0a2c1a194 100755 --- a/framework/core/src/Core/User.php +++ b/framework/core/src/Core/User.php @@ -156,8 +156,6 @@ class User extends AbstractModel { $user = new static; - $user->assertValidPassword($password); - $user->username = $username; $user->email = $email; $user->password = $password; @@ -227,15 +225,6 @@ class User extends AbstractModel public function requestEmailChange($email) { if ($email !== $this->email) { - $validator = $this->makeValidator(); - - $validator->setRules(array_only($validator->getRules(), 'email')); - $validator->setData(compact('email')); - - if ($validator->fails()) { - $this->throwValidationException($validator); - } - $this->raise(new UserEmailChangeWasRequested($this, $email)); } @@ -250,8 +239,6 @@ class User extends AbstractModel */ public function changePassword($password) { - $this->assertValidPassword($password); - $this->password = $password; $this->raise(new UserPasswordWasChanged($this)); @@ -259,20 +246,6 @@ class User extends AbstractModel return $this; } - /** - * Validate password input. - * - * @param string $password - * @return void - * @throws \Flarum\Core\Exception\ValidationException - */ - protected function assertValidPassword($password) - { - if (strlen($password) < 8) { - throw new ValidationException(['password' => 'Password must be at least 8 characters']); - } - } - /** * Set the password attribute, storing it as a hash. * diff --git a/framework/core/src/Core/Validator/AbstractValidator.php b/framework/core/src/Core/Validator/AbstractValidator.php index 089bfef81..7231262bb 100644 --- a/framework/core/src/Core/Validator/AbstractValidator.php +++ b/framework/core/src/Core/Validator/AbstractValidator.php @@ -10,14 +10,14 @@ namespace Flarum\Core\Validator; -use Flarum\Database\AbstractModel; -use Flarum\Event\ConfigureModelValidator; +use Flarum\Event\ConfigureValidator; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Validation\ValidationException; use Illuminate\Validation\Factory; use Illuminate\Validation\Validator; +use Symfony\Component\Translation\TranslatorInterface; -class AbstractValidator +abstract class AbstractValidator { /** * @var array @@ -35,39 +35,63 @@ class AbstractValidator protected $events; /** - * @param Factory $validator + * @var TranslatorInterface */ - public function __construct(Factory $validator, Dispatcher $events) + protected $translator; + + /** + * @param Factory $validator + * @param Dispatcher $events + * @param TranslatorInterface $translator + */ + public function __construct(Factory $validator, Dispatcher $events, TranslatorInterface $translator) { $this->validator = $validator; $this->events = $events; + $this->translator = $translator; } /** * Check whether a model is valid. * - * @param AbstractModel $model + * @param array $attributes * @return bool */ - public function valid(AbstractModel $model) + public function valid(array $attributes) { - return $this->makeValidator($model)->passes(); + return $this->makeValidator($attributes)->passes(); } /** * Throw an exception if a model is not valid. * - * @throws ValidationException + * @param array $attributes */ - public function assertValid(AbstractModel $model) + public function assertValid(array $attributes) { - $validator = $this->makeValidator($model); + $validator = $this->makeValidator($attributes); if ($validator->fails()) { $this->throwValidationException($validator); } } + /** + * @return array + */ + protected function getRules() + { + return $this->rules; + } + + /** + * @return array + */ + protected function getMessages() + { + return []; + } + /** * @param Validator $validator * @throws ValidationException @@ -80,72 +104,19 @@ class AbstractValidator /** * Make a new validator instance for this model. * - * @param AbstractModel $model + * @param array $attributes * @return \Illuminate\Validation\Validator */ - protected function makeValidator(AbstractModel $model) + protected function makeValidator(array $attributes) { - $rules = $this->expandUniqueRules($this->rules, $model); + $rules = array_only($this->getRules(), array_keys($attributes)); - $validator = $this->validator->make($model->getAttributes(), $rules); + $validator = $this->validator->make($attributes, $rules, $this->getMessages()); $this->events->fire( - new ConfigureModelValidator($model, $validator) + new ConfigureValidator($this, $validator) ); return $validator; } - - /** - * Expand 'unique' rules in a set of validation rules into a fuller form - * that Laravel's validator can understand. - * - * @param array $rules - * @param AbstractModel $model - * @return array - */ - protected function expandUniqueRules($rules, AbstractModel $model) - { - foreach ($rules as $attribute => &$ruleset) { - if (is_string($ruleset)) { - $ruleset = explode('|', $ruleset); - } - - foreach ($ruleset as &$rule) { - if (strpos($rule, 'unique') === 0) { - $rule = $this->expandUniqueRule($attribute, $rule, $model); - } - } - } - - return $rules; - } - - /** - * Expand a 'unique' rule into a fuller form that Laravel's validator can - * understand, based on this model's properties. - * - * @param string $attribute - * @param string $rule - * @param AbstractModel $model - * @return string - */ - protected function expandUniqueRule($attribute, $rule, AbstractModel $model) - { - $parts = explode(':', $rule); - $key = $model->getKey() ?: 'NULL'; - $rule = 'unique:'.$model->getTable().','.$attribute.','.$key.','.$model->getKeyName(); - - if (! empty($parts[1])) { - $wheres = explode(',', $parts[1]); - - foreach ($wheres as &$where) { - $where .= ','.$this->$where; - } - - $rule .= ','.implode(',', $wheres); - } - - return $rule; - } } diff --git a/framework/core/src/Core/Validator/DiscussionValidator.php b/framework/core/src/Core/Validator/DiscussionValidator.php index a70ff9366..a7901593f 100644 --- a/framework/core/src/Core/Validator/DiscussionValidator.php +++ b/framework/core/src/Core/Validator/DiscussionValidator.php @@ -13,15 +13,10 @@ namespace Flarum\Core\Validator; class DiscussionValidator extends AbstractValidator { protected $rules = [ - 'title' => ['required', 'max:80'], - 'start_time' => ['required', 'date'], - 'comments_count' => ['integer'], - 'participants_count' => ['integer'], - 'start_user_id' => ['integer'], - 'start_post_id' => ['integer'], - 'last_time' => ['date'], - 'last_user_id' => ['integer'], - 'last_post_id' => ['integer'], - 'last_post_number' => ['integer'], + 'title' => [ + 'required', + 'min:3', + 'max:80' + ] ]; } diff --git a/framework/core/src/Core/Validator/PostValidator.php b/framework/core/src/Core/Validator/PostValidator.php index 0b2eebd72..4bcb0ed59 100644 --- a/framework/core/src/Core/Validator/PostValidator.php +++ b/framework/core/src/Core/Validator/PostValidator.php @@ -13,14 +13,9 @@ namespace Flarum\Core\Validator; class PostValidator extends AbstractValidator { protected $rules = [ - 'discussion_id' => ['required', 'integer'], - 'time' => ['required', 'date'], - 'content' => ['required', 'max:65535'], - 'number' => ['integer'], - 'user_id' => ['integer'], - 'edit_time' => ['date'], - 'edit_user_id' => ['integer'], - 'hide_time' => ['date'], - 'hide_user_id' => ['integer'] + 'content' => [ + 'required', + 'max:65535' + ] ]; } diff --git a/framework/core/src/Core/Validator/UserValidator.php b/framework/core/src/Core/Validator/UserValidator.php index 7c92d7217..ea81e9da7 100644 --- a/framework/core/src/Core/Validator/UserValidator.php +++ b/framework/core/src/Core/Validator/UserValidator.php @@ -13,12 +13,21 @@ namespace Flarum\Core\Validator; class UserValidator extends AbstractValidator { protected $rules = [ - 'username' => ['required', 'alpha_dash', 'unique', 'min:3', 'max:30'], - 'email' => ['required', 'email', 'unique'], - 'password' => ['required'], - 'join_time' => ['date'], - 'last_seen_time' => ['date'], - 'discussions_count' => ['integer'], - 'posts_count' => ['integer'] + 'username' => [ + 'required', + 'alpha_dash', + 'unique:users', + 'min:3', + 'max:8' + ], + 'email' => [ + 'required', + 'email', + 'unique:users' + ], + 'password' => [ + 'required', + 'min:8' + ] ]; } diff --git a/framework/core/src/Event/ConfigureModelValidator.php b/framework/core/src/Event/ConfigureValidator.php similarity index 72% rename from framework/core/src/Event/ConfigureModelValidator.php rename to framework/core/src/Event/ConfigureValidator.php index fc2a4382b..5def994b8 100644 --- a/framework/core/src/Event/ConfigureModelValidator.php +++ b/framework/core/src/Event/ConfigureValidator.php @@ -10,7 +10,7 @@ namespace Flarum\Event; -use Flarum\Database\AbstractModel; +use Flarum\Core\Validator\AbstractValidator; use Illuminate\Validation\Validator; /** @@ -18,12 +18,12 @@ use Illuminate\Validation\Validator; * model is being built. This event can be used to add custom rules/extensions * to the validator for when validation takes place. */ -class ConfigureModelValidator +class ConfigureValidator { /** - * @var AbstractModel + * @var AbstractValidator */ - public $model; + public $type; /** * @var Validator @@ -31,12 +31,12 @@ class ConfigureModelValidator public $validator; /** - * @param AbstractModel $model + * @param AbstractValidator $type * @param Validator $validator */ - public function __construct(AbstractModel $model, Validator $validator) + public function __construct(AbstractValidator $type, Validator $validator) { - $this->model = $model; + $this->type = $type; $this->validator = $validator; } } diff --git a/framework/core/src/Forum/Controller/ClientController.php b/framework/core/src/Forum/Controller/ClientController.php index 5c05ded46..0aa7bfff5 100644 --- a/framework/core/src/Forum/Controller/ClientController.php +++ b/framework/core/src/Forum/Controller/ClientController.php @@ -13,8 +13,8 @@ namespace Flarum\Forum\Controller; use Flarum\Api\Client; use Flarum\Formatter\Formatter; use Flarum\Foundation\Application; -use Flarum\Settings\SettingsRepository; use Flarum\Locale\LocaleManager; +use Flarum\Settings\SettingsRepository; use Flarum\Http\Controller\AbstractClientController; use Illuminate\Contracts\Cache\Repository; use Illuminate\Contracts\Events\Dispatcher; diff --git a/framework/core/src/Http/Controller/AbstractClientController.php b/framework/core/src/Http/Controller/AbstractClientController.php index 5d6ee9de6..3288b3898 100644 --- a/framework/core/src/Http/Controller/AbstractClientController.php +++ b/framework/core/src/Http/Controller/AbstractClientController.php @@ -129,7 +129,7 @@ abstract class AbstractClientController extends AbstractHtmlController { $actor = $request->getAttribute('actor'); $assets = $this->getAssets(); - $locale = $this->getLocale($actor, $request); + $locale = $this->locales->getLocale(); $localeCompiler = $locale ? $this->getLocaleCompiler($locale) : null; $view = new ClientView( @@ -157,7 +157,7 @@ abstract class AbstractClientController extends AbstractHtmlController ); if ($localeCompiler) { - $translations = $this->locales->getTranslations($locale); + $translations = $this->locales->getTranslator()->getMessages()['messages']; $translations = $this->filterTranslations($translations, $keys); @@ -293,30 +293,6 @@ abstract class AbstractClientController extends AbstractHtmlController return $compiler; } - /** - * Get the name of the locale to use. - * - * @param User $actor - * @param Request $request - * @return string - */ - protected function getLocale(User $actor, Request $request) - { - if ($actor->exists) { - $locale = $actor->getPreference('locale'); - } else { - $locale = array_get($request->getCookieParams(), 'locale'); - } - - if (! $locale || ! $this->locales->hasLocale($locale)) { - $locale = $this->settings->get('default_locale', 'en'); - } - - if ($this->locales->hasLocale($locale)) { - return $locale; - } - } - /** * Get the path to the directory where assets should be written. * @@ -336,19 +312,12 @@ abstract class AbstractClientController extends AbstractHtmlController */ protected function filterTranslations(array $translations, array $keys) { - $filtered = []; - - foreach ($keys as $key) { - $parts = explode('.', $key); - $level = &$filtered; - - foreach ($parts as $part) { - $level = &$level[$part]; + return array_filter($translations, function ($id) use ($keys) { + foreach ($keys as $key) { + if (substr($id, 0, strlen($key)) === $key) { + return true; + } } - - $level = array_get($translations, $key); - } - - return $filtered; + }, ARRAY_FILTER_USE_KEY); } } diff --git a/framework/core/src/Http/Controller/ClientView.php b/framework/core/src/Http/Controller/ClientView.php index 7c0f359be..e7b89e973 100644 --- a/framework/core/src/Http/Controller/ClientView.php +++ b/framework/core/src/Http/Controller/ClientView.php @@ -96,22 +96,22 @@ class ClientView implements Renderable protected $request; /** - * @var \Flarum\Asset\AssetManager + * @var AssetManager */ protected $assets; /** * @var JsCompiler */ - protected $locale; + protected $localeJs; /** * @param Client $api * @param Request $request * @param User $actor - * @param \Flarum\Asset\AssetManager $assets + * @param AssetManager $assets * @param string $layout - * @param JsCompiler $locale + * @param JsCompiler $localeJs */ public function __construct( Client $api, @@ -119,14 +119,14 @@ class ClientView implements Renderable User $actor, AssetManager $assets, $layout, - JsCompiler $locale = null + JsCompiler $localeJs = null ) { $this->api = $api; $this->request = $request; $this->actor = $actor; $this->assets = $assets; $this->layout = $layout; - $this->locale = $locale; + $this->localeJs = $localeJs; } /** @@ -214,7 +214,7 @@ class ClientView implements Renderable /** * Get the view's asset manager. * - * @return \Flarum\Asset\AssetManager + * @return AssetManager */ public function getAssets() { @@ -264,8 +264,8 @@ class ClientView implements Renderable $view->styles = [$this->assets->getCssFile()]; $view->scripts = [$this->assets->getJsFile()]; - if ($this->locale) { - $view->scripts[] = $this->locale->getFile(); + if ($this->localeJs) { + $view->scripts[] = $this->localeJs->getFile(); } $view->head = implode("\n", $this->headStrings); diff --git a/framework/core/src/Http/Middleware/AuthenticateWithCookie.php b/framework/core/src/Http/Middleware/AuthenticateWithCookie.php index 3d075c785..87d06d8a8 100644 --- a/framework/core/src/Http/Middleware/AuthenticateWithCookie.php +++ b/framework/core/src/Http/Middleware/AuthenticateWithCookie.php @@ -12,12 +12,26 @@ namespace Flarum\Http\Middleware; use Flarum\Api\AccessToken; use Flarum\Core\Guest; +use Flarum\Locale\LocaleManager; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Zend\Stratigility\MiddlewareInterface; class AuthenticateWithCookie implements MiddlewareInterface { + /** + * @var LocaleManager + */ + protected $locales; + + /** + * @param LocaleManager $locales + */ + public function __construct(LocaleManager $locales) + { + $this->locales = $locales; + } + /** * {@inheritdoc} */ @@ -36,17 +50,27 @@ class AuthenticateWithCookie implements MiddlewareInterface */ protected function logIn(Request $request) { + $actor = new Guest; + if ($token = $this->getToken($request)) { if (! $token->isValid()) { // TODO: https://github.com/flarum/core/issues/253 - } elseif ($user = $token->user) { - $user->updateLastSeen()->save(); - - return $request->withAttribute('actor', $user); + } elseif ($actor = $token->user) { + $actor->updateLastSeen()->save(); } } - return $request->withAttribute('actor', new Guest); + if ($actor->exists) { + $locale = $actor->getPreference('locale'); + } else { + $locale = array_get($request->getCookieParams(), 'locale'); + } + + if ($locale && $this->locales->hasLocale($locale)) { + $this->locales->setLocale($locale); + } + + return $request->withAttribute('actor', $actor); } /** diff --git a/framework/core/src/Locale/LocaleManager.php b/framework/core/src/Locale/LocaleManager.php index 398998142..0f37938af 100644 --- a/framework/core/src/Locale/LocaleManager.php +++ b/framework/core/src/Locale/LocaleManager.php @@ -10,15 +10,36 @@ namespace Flarum\Locale; +use Symfony\Component\Translation\Translator; + class LocaleManager { - protected $locales = []; + /** + * @var Translator + */ + protected $translator; - protected $translations = []; + protected $locales = []; protected $js = []; - protected $config = []; + /** + * @param Translator $translator + */ + public function __construct(Translator $translator) + { + $this->translator = $translator; + } + + public function getLocale() + { + return $this->translator->getLocale(); + } + + public function setLocale($locale) + { + $this->translator->setLocale($locale); + } public function addLocale($locale, $name) { @@ -35,9 +56,9 @@ class LocaleManager return isset($this->locales[$locale]); } - public function addTranslations($locale, $translations) + public function addTranslations($locale, $file) { - $this->translations[$locale][] = $translations; + $this->translator->addResource('yaml', $file, $locale); } public function addJsFile($locale, $js) @@ -45,26 +66,6 @@ class LocaleManager $this->js[$locale][] = $js; } - public function addConfig($locale, $config) - { - $this->config[$locale][] = $config; - } - - public function getTranslations($locale) - { - $files = array_get($this->translations, $locale, []); - - $parts = explode('-', $locale); - - if (count($parts) > 1) { - $files = array_merge(array_get($this->translations, $parts[0], []), $files); - } - - $compiler = new TranslationCompiler($locale, $files); - - return $compiler->getTranslations(); - } - public function getJsFiles($locale) { $files = array_get($this->js, $locale, []); @@ -78,18 +79,19 @@ class LocaleManager return $files; } - public function getConfig($locale) + /** + * @return Translator + */ + public function getTranslator() { - if (empty($this->config[$locale])) { - return []; - } + return $this->translator; + } - $config = []; - - foreach ($this->config[$locale] as $file) { - $config = array_merge($config, include $file); - } - - return $config; + /** + * @param Translator $translator + */ + public function setTranslator($translator) + { + $this->translator = $translator; } } diff --git a/framework/core/src/Locale/LocaleServiceProvider.php b/framework/core/src/Locale/LocaleServiceProvider.php index f9495fbbe..d1271312b 100644 --- a/framework/core/src/Locale/LocaleServiceProvider.php +++ b/framework/core/src/Locale/LocaleServiceProvider.php @@ -13,6 +13,8 @@ namespace Flarum\Locale; use Flarum\Event\ConfigureLocales; use Flarum\Foundation\AbstractServiceProvider; use Illuminate\Contracts\Events\Dispatcher; +use Symfony\Component\Translation\MessageSelector; +use Symfony\Component\Translation\Translator; class LocaleServiceProvider extends AbstractServiceProvider { @@ -21,9 +23,9 @@ class LocaleServiceProvider extends AbstractServiceProvider */ public function boot(Dispatcher $events) { - $manager = $this->app->make('flarum.localeManager'); + $locales = $this->app->make('flarum.localeManager'); - $events->fire(new ConfigureLocales($manager)); + $events->fire(new ConfigureLocales($locales)); } /** @@ -32,11 +34,18 @@ class LocaleServiceProvider extends AbstractServiceProvider public function register() { $this->app->singleton('Flarum\Locale\LocaleManager'); - $this->app->alias('Flarum\Locale\LocaleManager', 'flarum.localeManager'); - $this->app->instance('translator', new Translator); + $this->app->singleton('translator', function () { + $defaultLocale = $this->app->make('flarum.settings')->get('default_locale'); + $translator = new Translator($defaultLocale, new MessageSelector()); + $translator->setFallbackLocales([$defaultLocale]); + $translator->addLoader('yaml', new YamlFileLoader()); + + return $translator; + }); + $this->app->alias('translator', 'Symfony\Component\Translation\Translator'); $this->app->alias('translator', 'Symfony\Component\Translation\TranslatorInterface'); } } diff --git a/framework/core/src/Locale/TranslationCompiler.php b/framework/core/src/Locale/TranslationCompiler.php deleted file mode 100644 index 1c96f76b1..000000000 --- a/framework/core/src/Locale/TranslationCompiler.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/* - * This file is part of Flarum. - * - * (c) Toby Zerner <toby.zerner@gmail.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Flarum\Locale; - -use Symfony\Component\Yaml\Yaml; - -class TranslationCompiler -{ - protected $locale; - - protected $filenames; - - public function __construct($locale, array $filenames) - { - $this->locale = $locale; - $this->filenames = $filenames; - } - - public function getTranslations() - { - // @todo caching - - $translations = []; - - foreach ($this->filenames as $filename) { - $translations = array_replace_recursive($translations, Yaml::parse(file_get_contents($filename))); - } - - // Temporary solution to resolve references. - // TODO: Make it do more than one level deep, unit test. - array_walk_recursive($translations, function (&$value, $key) use ($translations) { - if (preg_match('/^=>\s*([a-z0-9_\.]+)$/i', $value, $matches)) { - $value = array_get($translations, $matches[1]); - } - }); - - return $translations; - } -} diff --git a/framework/core/src/Locale/Translator.php b/framework/core/src/Locale/Translator.php deleted file mode 100644 index a8733fe58..000000000 --- a/framework/core/src/Locale/Translator.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php -/* - * This file is part of Flarum. - * - * (c) Toby Zerner <toby.zerner@gmail.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Flarum\Locale; - -use Symfony\Component\Translation\TranslatorInterface; - -class Translator implements TranslatorInterface -{ - protected $translations = []; - - protected $plural; - - public function setTranslations(array $translations) - { - $this->translations = $translations; - } - - public function setPlural(callable $plural) - { - $this->plural = $plural; - } - - protected function plural($count) - { - if ($this->plural) { - $plural = $this->plural; - - return $plural($count); - } - } - - public function getLocale() - { - // - } - - public function setLocale($locale) - { - // - } - - public function trans($id, array $parameters = [], $domain = null, $locale = null) - { - $translation = array_get($this->translations, $id); - - if (is_array($translation) && isset($parameters['count'])) { - $plural = $this->plural($parameters['count']); - - if ($plural) { - $translation = $translation[$plural]; - } - } - - if (is_string($translation)) { - foreach ($parameters as $k => $v) { - $translation = str_replace('{'.$k.'}', $v, $translation); - } - - return $translation; - } - - return $id; - } - - public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null) - { - $parameters['count'] = $number; - - return $this->trans($id, $parameters, $domain, $locale); - } -} diff --git a/framework/core/src/Locale/YamlFileLoader.php b/framework/core/src/Locale/YamlFileLoader.php new file mode 100644 index 000000000..837b90a83 --- /dev/null +++ b/framework/core/src/Locale/YamlFileLoader.php @@ -0,0 +1,42 @@ +<?php +/* + * This file is part of Flarum. + * + * (c) Toby Zerner <toby.zerner@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Locale; + +use Symfony\Component\Translation\Loader\YamlFileLoader as BaseYamlFileLoader; +use Symfony\Component\Translation\MessageCatalogueInterface; + +class YamlFileLoader extends BaseYamlFileLoader +{ + /** + * {@inheritdoc} + */ + public function load($resource, $locale, $domain = 'messages') + { + $messages = parent::load($resource, $locale, $domain); + + foreach ($messages->all($domain) as $id => $translation) { + $messages->set($id, $this->getTranslation($messages, $id, $domain)); + } + + return $messages; + } + + private function getTranslation(MessageCatalogueInterface $messages, $id, $domain) + { + $translation = $messages->get($id, $domain); + + if (preg_match('/^=>\s*([a-z0-9_\.]+)$/i', $translation, $matches)) { + return $this->getTranslation($messages, $matches[1], $domain); + } + + return $translation; + } +} \ No newline at end of file