From 9433e6622d85ebe7c8bc3dcded83e9c48c980c34 Mon Sep 17 00:00:00 2001 From: German Lena Date: Fri, 17 Apr 2015 11:34:05 -0300 Subject: [PATCH 01/10] updated dependencies to start working on it --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index eeabdfa3..c01c3425 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ "license": "MIT", "require": { "php": ">=5.3.0", - "illuminate/support": "4.*", + "illuminate/support": "5.*", "auth0/auth0-php": "0.6.*", "adoy/oauth2": "dev-master", "firebase/php-jwt" : "dev-master" From 3d93be09a04002720cb1e330618c5b02310837fb Mon Sep 17 00:00:00 2001 From: German Lena Date: Fri, 17 Apr 2015 18:05:09 -0300 Subject: [PATCH 02/10] Upgraded dependencies to L5, added middleware and fixes compatibility issues --- .DS_Store | Bin 0 -> 6148 bytes README.md | 5 +-- composer.json | 1 + examples/laravel-api/app/models/User.php | 4 +-- src/Auth0/Login/Auth0Service.php | 18 ++++++----- src/Auth0/Login/Auth0User.php | 6 +++- src/Auth0/Login/Auth0UserProvider.php | 11 ++++--- src/Auth0/Login/LoginServiceProvider.php | 29 ++++++------------ .../Login/Middleware/Auth0JWTMiddleware.php | 26 ++++++++++++++++ 9 files changed, 63 insertions(+), 37 deletions(-) create mode 100644 .DS_Store create mode 100644 src/Auth0/Login/Middleware/Auth0JWTMiddleware.php diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0auth0)) { - $auth0Config = Config::get('auth0::config'); + $auth0Config = config('laravel-auth0'); + $auth0Config['store'] = new LaravelSessionStore(); $this->auth0 = new Auth0($auth0Config); } @@ -38,9 +39,10 @@ public function getUserInfo() { // Get the user info from auth0 $auth0 = $this->getSDK(); $userInfo = $auth0->getUserInfo(); - $accessToken = $auth0->getAccessToken(); - $auth0User = new Auth0User($userInfo, $accessToken); + if ($userInfo === null) return null; + + $auth0User = new Auth0User($userInfo, $auth0->getAccessToken()); return $auth0User; } @@ -64,18 +66,18 @@ public function callOnLogin($auth0User) { private $apiuser; public function decodeJWT($encUser) { - $secret = Config::get('auth0::api.secret'); + $secret = config('laravel-auth0.client_secret'); $canDecode = false; try { // Decode the user - $this->apiuser = \JWT::decode($encUser, base64_decode(strtr($secret, '-_', '+/')) ); + $this->apiuser = \JWT::decode($encUser, base64_decode(strtr($secret, '-_', '+/')), ['HS256']); // validate that this JWT was made for us - if ($this->apiuser->aud == Config::get('auth0::api.audience')) { + if ($this->apiuser->aud == config('laravel-auth0.client_id')) { $canDecode = true; } - } catch(\UnexpectedValueException $e) { - } + + } catch(\UnexpectedValueException $e) {} return $canDecode; } diff --git a/src/Auth0/Login/Auth0User.php b/src/Auth0/Login/Auth0User.php index 2f5683ad..a2c01888 100644 --- a/src/Auth0/Login/Auth0User.php +++ b/src/Auth0/Login/Auth0User.php @@ -5,7 +5,7 @@ * given by Auth0. * */ -class Auth0User implements \Illuminate\Auth\UserInterface { +class Auth0User implements \Illuminate\Contracts\Auth\Authenticatable { private $userInfo; private $accessToken; @@ -57,4 +57,8 @@ public function __get($name) { return $this->userInfo[$name]; } + public function getUserInfo() { + return $this->userInfo; + } + } diff --git a/src/Auth0/Login/Auth0UserProvider.php b/src/Auth0/Login/Auth0UserProvider.php index e5b1fbba..64d2c981 100644 --- a/src/Auth0/Login/Auth0UserProvider.php +++ b/src/Auth0/Login/Auth0UserProvider.php @@ -1,16 +1,17 @@ getUserInfo(); if ($auth0User && $auth0User->getAuthIdentifier() == $identifier) { return $auth0User; @@ -35,13 +36,13 @@ public function retrieveByToken($identifier, $token) { /** * Required method by the UserProviderInterface, we don't implement it */ - public function updateRememberToken(\Illuminate\Auth\UserInterface $user, $token) { + public function updateRememberToken(Authenticatable $user, $token) { } /** * Required method by the UserProviderInterface, we don't implement it */ - public function validateCredentials(\Illuminate\Auth\UserInterface $user, array $credentials) { + public function validateCredentials(Authenticatable $user, array $credentials) { return false; } } \ No newline at end of file diff --git a/src/Auth0/Login/LoginServiceProvider.php b/src/Auth0/Login/LoginServiceProvider.php index e55fe275..a85f4d98 100644 --- a/src/Auth0/Login/LoginServiceProvider.php +++ b/src/Auth0/Login/LoginServiceProvider.php @@ -18,12 +18,20 @@ class LoginServiceProvider extends ServiceProvider { */ public function boot() { - $this->package('auth0/login','auth0'); +// $this->package('auth0/login','auth0'); + \Auth::extend('auth0', function($app) { - $provider = new Auth0UserProvider(); + $provider = new Auth0UserProvider(); return new \Illuminate\Auth\Guard($provider, $app['session.store']); + }); + + + + $this->publishes([ + __DIR__.'/../../config/config.php' => config_path('laravel-auth0.php'), + ]); } /** @@ -38,28 +46,11 @@ public function register() return new Auth0Service(); }); - // When Laravel logs out, logout the auth0 SDK trough the service \Event::listen('auth.logout', function() { \App::make("auth0")->logout(); }); - // Create a filter (maybe find a better place) - \Route::filter('auth-jwt', function($route, $request) { - // Get the encrypted user - $authorizationHeader = $request->header("Authorization"); - $encUser = str_replace('Bearer ', '', $authorizationHeader); - if (trim($encUser) != '') { - $canDecode = \App::make('auth0')->decodeJWT($encUser); - } else { - $canDecode = false; - } - - if (!$canDecode) { - return \Response::make("Unauthorized user", 401); - } - }); - } /** diff --git a/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php b/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php new file mode 100644 index 00000000..1dc69daa --- /dev/null +++ b/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php @@ -0,0 +1,26 @@ +header("Authorization"); + $encUser = str_replace('Bearer ', '', $authorizationHeader); + if (trim($encUser) != '') { + $canDecode = \App::make('auth0')->decodeJWT($encUser); + } else { + $canDecode = false; + } + + if (!$canDecode) { + return \Response::make("Unauthorized user", 401); + } + + return $next($request); + } + +} \ No newline at end of file From a8abba77f6866140d2c72641d06cda6538ec2a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Lena?= Date: Fri, 17 Apr 2015 18:57:10 -0300 Subject: [PATCH 03/10] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a177dc0f..589e96c9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This plugin helps you integrate your Laravel WebApp with [Auth0](https://auth0.c To install this plugin add the following dependency to your composer.json ```js -"auth0/login" : "1.0.8" +"auth0/login" : "2.0.0" ``` and run `composer update` @@ -46,7 +46,7 @@ To configure the plugin, you need to publish the plugin configuration and comple To publish the example configuration file use this command - php artisan config:publish auth0/login + php artisan vendor:publish ### 4. Setup the callback action From b5e1ed9117d5ef2e1db229c358b0ae36f1b17be0 Mon Sep 17 00:00:00 2001 From: German Lena Date: Mon, 20 Apr 2015 12:31:34 -0300 Subject: [PATCH 04/10] Added the ability to inject an Auth0UserProvider instead of events --- src/Auth0/Login/Auth0JWTUser.php | 62 +++++++++++++++++++ src/Auth0/Login/Auth0Service.php | 10 ++- src/Auth0/Login/Auth0UserProvider.php | 11 ++-- .../Login/Contract/Auth0UserRepository.php | 9 +++ src/Auth0/Login/LoginServiceProvider.php | 14 +++-- .../Login/Middleware/Auth0JWTMiddleware.php | 20 +++++- .../Login/Repository/Auth0UserRepository.php | 32 ++++++++++ src/controllers/Auth0Controller.php | 16 ++++- 8 files changed, 160 insertions(+), 14 deletions(-) create mode 100644 src/Auth0/Login/Auth0JWTUser.php create mode 100644 src/Auth0/Login/Contract/Auth0UserRepository.php create mode 100644 src/Auth0/Login/Repository/Auth0UserRepository.php diff --git a/src/Auth0/Login/Auth0JWTUser.php b/src/Auth0/Login/Auth0JWTUser.php new file mode 100644 index 00000000..74c4d2d4 --- /dev/null +++ b/src/Auth0/Login/Auth0JWTUser.php @@ -0,0 +1,62 @@ +userInfo = $userInfo; + } + /** + * Get the unique identifier for the user. + * + * @return mixed + */ + public function getAuthIdentifier() { + return $this->userInfo->sub; + } + + /** + * Get the password for the user. + * + * @return string + */ + public function getAuthPassword() { + return null; + } + + public function getRememberToken() { + return null; + } + + public function setRememberToken($value) { + + } + + public function getRememberTokenName() { + return null; + } + + /** + * Add a generic getter to get all the properties of the userInfo + * + * @return the related value or null if it is not set + */ + public function __get($name) { + + if (!array_key_exists($name, $this->userInfo)) { + return null; + } + + return $this->userInfo[$name]; + } + + public function getUserInfo() { + return $this->userInfo; + } + +} diff --git a/src/Auth0/Login/Auth0Service.php b/src/Auth0/Login/Auth0Service.php index c49f2861..a3f07608 100644 --- a/src/Auth0/Login/Auth0Service.php +++ b/src/Auth0/Login/Auth0Service.php @@ -33,7 +33,7 @@ public function logout() { /** * If the user is logged in, returns the user information - * @return \Auth0\LaravelAuth0\Auth0User User info as described in https://docs.auth0.com/user-profile + * @return User info as described in https://docs.auth0.com/user-profile */ public function getUserInfo() { // Get the user info from auth0 @@ -42,8 +42,14 @@ public function getUserInfo() { if ($userInfo === null) return null; - $auth0User = new Auth0User($userInfo, $auth0->getAccessToken()); + return [ + 'profile' => $userInfo, + 'accessToken' => $auth0->getAccessToken() + ]; + /* + $auth0User = new Auth0UserInfo($userInfo, $auth0->getAccessToken()); return $auth0User; + */ } private $_onLoginCb = null; diff --git a/src/Auth0/Login/Auth0UserProvider.php b/src/Auth0/Login/Auth0UserProvider.php index 64d2c981..c35d0733 100644 --- a/src/Auth0/Login/Auth0UserProvider.php +++ b/src/Auth0/Login/Auth0UserProvider.php @@ -1,4 +1,6 @@ userRepository = $userRepository; + } public function retrieveByID($identifier) { - $auth0User = \App::make('auth0')->getUserInfo(); - if ($auth0User && $auth0User->getAuthIdentifier() == $identifier) { - return $auth0User; - } + return $this->userRepository->getUserByIdentifier($identifier); } diff --git a/src/Auth0/Login/Contract/Auth0UserRepository.php b/src/Auth0/Login/Contract/Auth0UserRepository.php new file mode 100644 index 00000000..cde46ac7 --- /dev/null +++ b/src/Auth0/Login/Contract/Auth0UserRepository.php @@ -0,0 +1,9 @@ +package('auth0/login','auth0'); - \Auth::extend('auth0', function($app) { - $provider = new Auth0UserProvider(); - return new \Illuminate\Auth\Guard($provider, $app['session.store']); - }); + $userRepository = \App::make('\Auth0\Login\Contract\Auth0UserRepository'); + $provider = new Auth0UserProvider($userRepository); + return new \Illuminate\Auth\Guard($provider, $app['session.store']); + + }); $this->publishes([ __DIR__.'/../../config/config.php' => config_path('laravel-auth0.php'), @@ -51,6 +51,10 @@ public function register() \App::make("auth0")->logout(); }); + $this->app->bind( + '\Auth0\Login\Contract\Auth0UserRepository', + '\Auth0\Login\Repository\Auth0UserRepository'); + } /** diff --git a/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php b/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php index 1dc69daa..3d5dc5e9 100644 --- a/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php +++ b/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php @@ -1,17 +1,27 @@ userRepository = $userRepository; + } + public function handle($request, \Closure $next) { + $auth0 = \App::make('auth0'); + // Get the encrypted user $authorizationHeader = $request->header("Authorization"); $encUser = str_replace('Bearer ', '', $authorizationHeader); + if (trim($encUser) != '') { - $canDecode = \App::make('auth0')->decodeJWT($encUser); + $canDecode = $auth0->decodeJWT($encUser); } else { $canDecode = false; } @@ -20,6 +30,14 @@ public function handle($request, \Closure $next) return \Response::make("Unauthorized user", 401); } + $user = $this->userRepository->getUserByDecodedJWT($auth0->jwtuser()); + + if (!$user) { + return \Response::make("Unauthorized user", 401); + } + + \Auth::login($user); + return $next($request); } diff --git a/src/Auth0/Login/Repository/Auth0UserRepository.php b/src/Auth0/Login/Repository/Auth0UserRepository.php new file mode 100644 index 00000000..bb901cda --- /dev/null +++ b/src/Auth0/Login/Repository/Auth0UserRepository.php @@ -0,0 +1,32 @@ +getUserInfo(); + + $auth0User = $this->getUserByUserInfo($userInfo); + + if ($auth0User && $auth0User->getAuthIdentifier() == $identifier) { + return $auth0User; + } + } + +} \ No newline at end of file diff --git a/src/controllers/Auth0Controller.php b/src/controllers/Auth0Controller.php index 6456a874..2afa0bae 100644 --- a/src/controllers/Auth0Controller.php +++ b/src/controllers/Auth0Controller.php @@ -1,9 +1,19 @@ userRepository = $userRepository; + } + /** * Callback action that should be called by auth0, logs the user in */ @@ -11,8 +21,10 @@ public function callback() { // Get a handle of the Auth0 service (we don't know if it has an alias) $service = \App::make('auth0'); - // Try to get the user informatio - $auth0User = $service->getUserInfo(); + // Try to get the user information + $profile = $service->getUserInfo(); + $auth0User = $this->userRepository->getUserByUserInfo($profile); + if ($auth0User) { // If we have, we are going to log him in, buut, if // there is an onLogin defined we need to allow the Laravel developer From bf1db0b0f7a389abf9742b316c48aee4c7933787 Mon Sep 17 00:00:00 2001 From: German Lena Date: Mon, 20 Apr 2015 13:26:26 -0300 Subject: [PATCH 05/10] Updated readme --- README.md | 87 +++++++++++++++++++----- src/Auth0/Login/LoginServiceProvider.php | 4 -- 2 files changed, 70 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 589e96c9..69e5a35f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # Laravel Auth0 Plugin -This plugin helps you integrate your Laravel WebApp with [Auth0](https://auth0.com/) to achieve Single Sign On with a few simple steps. You can see an example application [here](https://github.com/auth0/laravel-auth0-sample). +This plugin helps you integrate your Laravel WebApp with [Auth0](https://auth0.com/) to achieve Single Sign On with a few simple steps. You can see an example application [here](https://github.com/auth0/laravel-5-auth0-sample). + +##Laravel Compatibility + +The last version (2.x) targets Laravel 5 compatibility. + +If you are working with an older version (Laravel 4.x) you need to point to composer.json to the version 1.0.* ### 1. Install the plugin and its dependencies @@ -11,7 +17,7 @@ To install this plugin add the following dependency to your composer.json and run `composer update` -NOTE: The plugin dependencies are not tagged, so you have to either change the `minimum-stability` to `dev` or you have to add the dependencies manually. +NOTE: Some plugin dependencies are not tagged, so you have to either change the `minimum-stability` to `dev` or you have to add the dependencies manually. ```js "adoy/oauth2": "dev-master", @@ -38,11 +44,42 @@ Optionally, if you want to use the [facade](http://laravel.com/docs/facades) cal ); ``` -That lets you call the service method like `Auth0::getUserInfo()` or `Auth0::onLogin(function(...))`. +Now, you will be able to access to the logged user info with `Auth0::getUserInfo()` and hook to the onLogin event `Auth0::onLogin(function(...))`. + +If you want to restrict access with the Auth0 Middleware, you will need to add it in `app/Http/Kernel.php` + +```php +... + +protected $routeMiddleware = [ + ... + 'auth0.jwt' => 'Auth0\Login\Middleware\Auth0JWTMiddleware', + ]; + +... +``` + +Finally, you will need to bind a class that provides the users (your app model user) each time a user is logged in or a JWT is decoded. You can use the `Auth0UserRepository` provided by this package or build your own (which should implement the `\Auth0\Login\Contract\Auth0UserRepository` interface). +For this you need to add to your AppServiceProvider the following line: + +```php +... + +public function register() +{ + + $this->app->bind( + '\Auth0\Login\Contract\Auth0UserRepository', + '\Auth0\Login\Repository\Auth0UserRepository'); + +} + +... +``` ### 3. Configure it -To configure the plugin, you need to publish the plugin configuration and complete the file `app/config/packages/auth0/login/config.php` using the information of your Auth0 account. +To configure the plugin, you need to publish the plugin configuration and complete the file `app/config/laravel-auth0.php` using the information of your Auth0 account. To publish the example configuration file use this command @@ -60,22 +97,28 @@ Route::get('/auth0/callback', 'Auth0\Login\Auth0Controller@callback'); ### 5. Triggering login manually or integrating the Auth0 widget -You can trigger the login in different ways, like redirecting to a login link or you can use the [Login Widget](https://docs.auth0.com/login-widget2), by adding the following javascript into a Laravel view or layout +You can trigger the login in different ways, like redirecting to a login link or you can use [Lock](https://auth0.com/docs/lock), by adding the following javascript into a Laravel view or layout ```html - + + - -``` + + +``` ### 6. Defining a user and a user provider @@ -87,6 +130,16 @@ The plugin comes with an authentication driver called auth0. This driver defines This works fine for basic testing or if you don't really need to persist the user. At any point you can call `Auth::check()` to see if there is a user logged in and `Auth::user()` to get the wrapper with the user information. +To enable this driver, you need to change the following line in `/config/auth.php`: + +```php +... + 'driver' => 'auth0', +... +``` + +If you need to implement a more advanced custom solution, you can always extend the Auth0UserRepository (or implement your own) in order to get and update the user data on your database and event more advaced validations. + #### 6.2. Using other driver If you want to persist the user you can use the authentication driver you like. The plugin gives you a hook that is called with the *Normalized User Profile* when the callback is succesful, there you can store the user structure as you want. For example, if we use Eloquent, we can add the following code, to persist the user in the database @@ -108,14 +161,14 @@ Auth0::onLogin(function($auth0User) { }); ``` -Note that this hook must return the new user, which must implement the `Illuminate\Contracts\Auth\UserInterface`. The onLogin function is going to be called just once, when the callback uri is called, then its up to the selected auth driver to get the user from the database. +Note that this hook must return the new user, which must implement the `Illuminate\Contracts\Auth\Authenticatable`. The onLogin function is going to be called just once, when the callback uri is called, then its up to the selected auth driver to get the user from the database. ### 7. Use it! -Now you can use Laravel filters as you would normally do to restrict access, for example +Now you can use Laravel middleware as you would normally do to restrict access, for example ```php -Route::get('admin', array('before' => 'auth', function() { +Route::get('admin', array('before' => 'middleware' => 'auth0.jwt', function() { // ... })); ``` @@ -141,4 +194,4 @@ If you have found a bug or if you have a feature request, please report them at ## License -This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. +This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. \ No newline at end of file diff --git a/src/Auth0/Login/LoginServiceProvider.php b/src/Auth0/Login/LoginServiceProvider.php index e3f0418d..032874af 100644 --- a/src/Auth0/Login/LoginServiceProvider.php +++ b/src/Auth0/Login/LoginServiceProvider.php @@ -51,10 +51,6 @@ public function register() \App::make("auth0")->logout(); }); - $this->app->bind( - '\Auth0\Login\Contract\Auth0UserRepository', - '\Auth0\Login\Repository\Auth0UserRepository'); - } /** From fc951382ca4c12164925993728a54bf06b8fc7e4 Mon Sep 17 00:00:00 2001 From: German Lena Date: Mon, 20 Apr 2015 14:30:31 -0300 Subject: [PATCH 06/10] Added comments to code --- src/Auth0/Login/Auth0JWTUser.php | 3 ++- src/Auth0/Login/Auth0Service.php | 6 +----- src/Auth0/Login/Auth0User.php | 2 +- src/Auth0/Login/Auth0UserProvider.php | 8 ++++++-- src/Auth0/Login/Contract/Auth0UserRepository.php | 14 ++++++++++++++ src/Auth0/Login/LoginServiceProvider.php | 2 +- src/Auth0/Login/Middleware/Auth0JWTMiddleware.php | 6 +++++- src/Auth0/Login/Repository/Auth0UserRepository.php | 3 +++ src/controllers/Auth0Controller.php | 2 ++ 9 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/Auth0/Login/Auth0JWTUser.php b/src/Auth0/Login/Auth0JWTUser.php index 74c4d2d4..df2bf9ca 100644 --- a/src/Auth0/Login/Auth0JWTUser.php +++ b/src/Auth0/Login/Auth0JWTUser.php @@ -2,12 +2,13 @@ /** * This class represents a generic user initialized with the user information - * given by Auth0. + * given by Auth0 and provides a way to access to the decoded JWT data. * */ class Auth0JWTUser implements \Illuminate\Contracts\Auth\Authenticatable { private $userInfo; + function __construct ($userInfo) { $this->userInfo = $userInfo; } diff --git a/src/Auth0/Login/Auth0Service.php b/src/Auth0/Login/Auth0Service.php index a3f07608..0b5d7eef 100644 --- a/src/Auth0/Login/Auth0Service.php +++ b/src/Auth0/Login/Auth0Service.php @@ -33,7 +33,7 @@ public function logout() { /** * If the user is logged in, returns the user information - * @return User info as described in https://docs.auth0.com/user-profile + * @return array with the User info as described in https://docs.auth0.com/user-profile and the user access token */ public function getUserInfo() { // Get the user info from auth0 @@ -46,10 +46,6 @@ public function getUserInfo() { 'profile' => $userInfo, 'accessToken' => $auth0->getAccessToken() ]; - /* - $auth0User = new Auth0UserInfo($userInfo, $auth0->getAccessToken()); - return $auth0User; - */ } private $_onLoginCb = null; diff --git a/src/Auth0/Login/Auth0User.php b/src/Auth0/Login/Auth0User.php index a2c01888..0a07669e 100644 --- a/src/Auth0/Login/Auth0User.php +++ b/src/Auth0/Login/Auth0User.php @@ -2,7 +2,7 @@ /** * This class represents a generic user initialized with the user information - * given by Auth0. + * given by Auth0 and provides a way to access to the user profile. * */ class Auth0User implements \Illuminate\Contracts\Auth\Authenticatable { diff --git a/src/Auth0/Login/Auth0UserProvider.php b/src/Auth0/Login/Auth0UserProvider.php index c35d0733..7df571f5 100644 --- a/src/Auth0/Login/Auth0UserProvider.php +++ b/src/Auth0/Login/Auth0UserProvider.php @@ -16,10 +16,14 @@ public function __construct(Auth0UserRepository $userRepository) { $this->userRepository = $userRepository; } + /** + * Lets make the repository take care of returning the user related to the + * identifier + * @param mixed $identifier + * @return Authenticatable + */ public function retrieveByID($identifier) { - return $this->userRepository->getUserByIdentifier($identifier); - } /** diff --git a/src/Auth0/Login/Contract/Auth0UserRepository.php b/src/Auth0/Login/Contract/Auth0UserRepository.php index cde46ac7..312620ff 100644 --- a/src/Auth0/Login/Contract/Auth0UserRepository.php +++ b/src/Auth0/Login/Contract/Auth0UserRepository.php @@ -2,8 +2,22 @@ interface Auth0UserRepository { + /** + * @param stdClass $jwt with the data provided in the JWT + * @return \Illuminate\Contracts\Auth\Authenticatable + */ public function getUserByDecodedJWT($jwt); + + /** + * @param array $userInfo representing the user profile and user accessToken + * @return \Illuminate\Contracts\Auth\Authenticatable + */ public function getUserByUserInfo($userInfo); + + /** + * @param $identifier the user id + * @return \Illuminate\Contracts\Auth\Authenticatable + */ public function getUserByIdentifier($identifier); } \ No newline at end of file diff --git a/src/Auth0/Login/LoginServiceProvider.php b/src/Auth0/Login/LoginServiceProvider.php index 032874af..bf189cc5 100644 --- a/src/Auth0/Login/LoginServiceProvider.php +++ b/src/Auth0/Login/LoginServiceProvider.php @@ -20,7 +20,7 @@ public function boot() { \Auth::extend('auth0', function($app) { - + // Let the container build the repository for us $userRepository = \App::make('\Auth0\Login\Contract\Auth0UserRepository'); $provider = new Auth0UserProvider($userRepository); diff --git a/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php b/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php index 3d5dc5e9..d565d93a 100644 --- a/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php +++ b/src/Auth0/Login/Middleware/Auth0JWTMiddleware.php @@ -16,7 +16,7 @@ public function handle($request, \Closure $next) { $auth0 = \App::make('auth0'); - // Get the encrypted user + // Get the encrypted user JWT $authorizationHeader = $request->header("Authorization"); $encUser = str_replace('Bearer ', '', $authorizationHeader); @@ -26,18 +26,22 @@ public function handle($request, \Closure $next) $canDecode = false; } + // if it is not valid, return a HTTP 401 if (!$canDecode) { return \Response::make("Unauthorized user", 401); } + // if it does not represent a valid user, return a HTTP 401 $user = $this->userRepository->getUserByDecodedJWT($auth0->jwtuser()); if (!$user) { return \Response::make("Unauthorized user", 401); } + // lets log the user in so it is accesible \Auth::login($user); + // continue the excecution return $next($request); } diff --git a/src/Auth0/Login/Repository/Auth0UserRepository.php b/src/Auth0/Login/Repository/Auth0UserRepository.php index bb901cda..39b13620 100644 --- a/src/Auth0/Login/Repository/Auth0UserRepository.php +++ b/src/Auth0/Login/Repository/Auth0UserRepository.php @@ -20,10 +20,13 @@ public function getUserByUserInfo($userInfo) { } public function getUserByIdentifier($identifier) { + //Get the user info of the user logged in (probably in session) $userInfo = \App::make('auth0')->getUserInfo(); + // build the user $auth0User = $this->getUserByUserInfo($userInfo); + // it is not the same user as logged in, it is not valid if ($auth0User && $auth0User->getAuthIdentifier() == $identifier) { return $auth0User; } diff --git a/src/controllers/Auth0Controller.php b/src/controllers/Auth0Controller.php index 2afa0bae..0db948a2 100644 --- a/src/controllers/Auth0Controller.php +++ b/src/controllers/Auth0Controller.php @@ -23,6 +23,8 @@ public function callback() { // Try to get the user information $profile = $service->getUserInfo(); + + // Get the user related to the profile $auth0User = $this->userRepository->getUserByUserInfo($profile); if ($auth0User) { From 2bba74202cb73ddcf8a4b02413001ed138d3adf3 Mon Sep 17 00:00:00 2001 From: German Lena Date: Mon, 20 Apr 2015 14:59:15 -0300 Subject: [PATCH 07/10] removed composer.lock with old dependencies --- composer.lock | 194 -------------------------------------------------- 1 file changed, 194 deletions(-) delete mode 100644 composer.lock diff --git a/composer.lock b/composer.lock deleted file mode 100644 index d284c28d..00000000 --- a/composer.lock +++ /dev/null @@ -1,194 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "7dac250b3f6428ec975777f867036458", - "packages": [ - { - "name": "adoy/oauth2", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/adoy/PHP-OAuth2.git", - "reference": "27c0d7f65e25074ce1c4a916c798db3a29c85e9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/adoy/PHP-OAuth2/zipball/27c0d7f65e25074ce1c4a916c798db3a29c85e9d", - "reference": "27c0d7f65e25074ce1c4a916c798db3a29c85e9d", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "OAuth2": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1" - ], - "authors": [ - { - "name": "Pierrick Charron", - "email": "pierrick@webstart.fr" - }, - { - "name": "Berejeb Anis", - "email": "anis.berejeb@gmail.com" - } - ], - "description": "Light PHP wrapper for the OAuth 2.0 protocol (based on OAuth 2.0 Authorization Protocol draft-ietf-oauth-v2-15)", - "time": "2014-03-07 16:05:00" - }, - { - "name": "auth0/auth0-php", - "version": "0.6.6", - "source": { - "type": "git", - "url": "https://github.com/auth0/Auth0-PHP.git", - "reference": "638f032fe38691da3c7ce9276040d045d40116ce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/auth0/Auth0-PHP/zipball/638f032fe38691da3c7ce9276040d045d40116ce", - "reference": "638f032fe38691da3c7ce9276040d045d40116ce", - "shasum": "" - }, - "require": { - "adoy/oauth2": "dev-master", - "ext-curl": "*", - "ext-json": "*", - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Auth0", - "email": "support@auth0.com", - "homepage": "http://www.auth0.com/" - } - ], - "description": "Auth0 PHP SDK.", - "time": "2014-04-14 21:25:24" - }, - { - "name": "firebase/php-jwt", - "version": "dev-master", - "target-dir": "Firebase/PHP-JWT", - "source": { - "type": "git", - "url": "https://github.com/firebase/php-jwt.git", - "reference": "fa7e362eeeec5ee808124626c3f1a612aadbce52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/fa7e362eeeec5ee808124626c3f1a612aadbce52", - "reference": "fa7e362eeeec5ee808124626c3f1a612aadbce52", - "shasum": "" - }, - "require": { - "php": ">=5.2.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "Authentication/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Neuman Vong", - "email": "neuman+pear@twilio.com", - "role": "Developer" - }, - { - "name": "Anant Narayanan", - "email": "anant@php.net", - "role": "Developer" - } - ], - "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", - "homepage": "https://github.com/firebase/php-jwt", - "time": "2014-06-25 21:20:33" - }, - { - "name": "illuminate/support", - "version": "4.2.x-dev", - "target-dir": "Illuminate/Support", - "source": { - "type": "git", - "url": "https://github.com/illuminate/support.git", - "reference": "b658e4cf1251d059c184a8909a4e670e2b00a683" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/b658e4cf1251d059c184a8909a4e670e2b00a683", - "reference": "b658e4cf1251d059c184a8909a4e670e2b00a683", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "jeremeamia/superclosure": "~1.0", - "patchwork/utf8": "1.1.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, - "autoload": { - "psr-0": { - "Illuminate\\Support": "" - }, - "files": [ - "Illuminate/Support/helpers.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "time": "2014-07-23 18:26:20" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "dev", - "stability-flags": { - "adoy/oauth2": 20, - "firebase/php-jwt": 20 - }, - "prefer-stable": false, - "platform": { - "php": ">=5.3.0" - }, - "platform-dev": [] -} From 3bb1703b71a2256a3e3f65bc40bf27c282630380 Mon Sep 17 00:00:00 2001 From: German Lena Date: Mon, 20 Apr 2015 15:57:18 -0300 Subject: [PATCH 08/10] Updated the example --- src/config/api.php | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 src/config/api.php diff --git a/src/config/api.php b/src/config/api.php deleted file mode 100644 index 336fbead..00000000 --- a/src/config/api.php +++ /dev/null @@ -1,24 +0,0 @@ - 'XXXX', - /* - |-------------------------------------------------------------------------- - | JWT Secret - |-------------------------------------------------------------------------- - | The secret used to encrypt the JWT - | - */ - - 'secret' => 'XXXX' - -); From 26e08668e860f9874ff066ce2f62012d76c3dada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Lena?= Date: Mon, 20 Apr 2015 15:59:01 -0300 Subject: [PATCH 09/10] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 69e5a35f..6ee17519 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Laravel Auth0 Plugin -This plugin helps you integrate your Laravel WebApp with [Auth0](https://auth0.com/) to achieve Single Sign On with a few simple steps. You can see an example application [here](https://github.com/auth0/laravel-5-auth0-sample). +This plugin helps you integrate your Laravel WebApp with [Auth0](https://auth0.com/) to achieve Single Sign On with a few simple steps. You can see an example application [on the example directory](https://github.com/auth0/laravel-auth0/tree/master/examples/laravel-api). ##Laravel Compatibility @@ -194,4 +194,4 @@ If you have found a bug or if you have a feature request, please report them at ## License -This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. \ No newline at end of file +This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. From b7b42b6906b6a5080d16a2bd9943b010b7dff5b3 Mon Sep 17 00:00:00 2001 From: German Lena Date: Mon, 20 Apr 2015 16:01:24 -0300 Subject: [PATCH 10/10] Updated the example --- .DS_Store | Bin 6148 -> 6148 bytes examples/.DS_Store | Bin 0 -> 6148 bytes examples/laravel-api/CONTRIBUTING.md | 3 - examples/laravel-api/Procfile | 1 - examples/laravel-api/app/Commands/Command.php | 7 + .../app/Console/Commands/Inspire.php | 32 + examples/laravel-api/app/Console/Kernel.php | 29 + examples/laravel-api/app/Events/Event.php | 7 + .../laravel-api/app/Exceptions/Handler.php | 42 + .../{commands => Handlers/Commands}/.gitkeep | 0 .../packages => Handlers/Events}/.gitkeep | 0 .../Http/Controllers/Auth/AuthController.php | 38 + .../Controllers/Auth/PasswordController.php | 38 + .../app/Http/Controllers/Controller.php | 11 + .../app/Http/Controllers/HomeController.php | 36 + .../Http/Controllers/WelcomeController.php | 60 + examples/laravel-api/app/Http/Kernel.php | 33 + .../app/Http/Middleware/Authenticate.php | 50 + .../Middleware/RedirectIfAuthenticated.php | 44 + .../app/Http/Middleware/VerifyCsrfToken.php | 20 + .../laravel-api/app/Http/Requests/Request.php | 9 + examples/laravel-api/app/Http/routes.php | 22 + .../app/Providers/AppServiceProvider.php | 38 + .../app/Providers/BusServiceProvider.php | 34 + .../app/Providers/ConfigServiceProvider.php | 23 + .../app/Providers/EventServiceProvider.php | 32 + .../app/Providers/RouteServiceProvider.php | 44 + .../laravel-api/app/Services/Registrar.php | 39 + examples/laravel-api/app/User.php | 34 + examples/laravel-api/app/config/cache.php | 89 - examples/laravel-api/app/config/compile.php | 18 - examples/laravel-api/app/config/local/app.php | 18 - .../laravel-api/app/config/local/database.php | 47 - .../app/config/packages/auth0/login/api.php | 24 - .../packages/barryvdh/laravel-cors/config.php | 36 - examples/laravel-api/app/config/remote.php | 59 - .../laravel-api/app/config/testing/cache.php | 20 - .../app/config/testing/session.php | 21 - examples/laravel-api/app/config/workbench.php | 31 - .../app/controllers/BaseController.php | 18 - .../app/controllers/HomeController.php | 23 - .../app/database/production.sqlite | 0 .../laravel-api/app/database/seeds/.gitkeep | 0 examples/laravel-api/app/filters.php | 90 - examples/laravel-api/app/models/User.php | 26 - examples/laravel-api/app/routes.php | 20 - examples/laravel-api/app/start/artisan.php | 13 - examples/laravel-api/app/start/global.php | 81 - examples/laravel-api/app/start/local.php | 3 - examples/laravel-api/app/storage/.gitignore | 1 - .../laravel-api/app/storage/meta/.gitignore | 2 - .../app/storage/sessions/.gitignore | 2 - .../laravel-api/app/storage/views/.gitignore | 2 - examples/laravel-api/app/tests/TestCase.php | 19 - .../app/views/emails/auth/reminder.blade.php | 14 - examples/laravel-api/app/views/hello.php | 42 - examples/laravel-api/artisan | 39 +- examples/laravel-api/bootstrap/app.php | 55 + examples/laravel-api/bootstrap/autoload.php | 46 +- examples/laravel-api/bootstrap/paths.php | 57 - examples/laravel-api/bootstrap/start.php | 73 - examples/laravel-api/composer.json | 32 +- examples/laravel-api/composer.lock | 2512 ++++++++++++----- examples/laravel-api/{app => }/config/app.php | 147 +- .../laravel-api/{app => }/config/auth.php | 30 +- examples/laravel-api/config/cache.php | 79 + examples/laravel-api/config/compile.php | 41 + .../laravel-api/{app => }/config/database.php | 59 +- examples/laravel-api/config/filesystems.php | 71 + .../config.php => config/laravel-auth0.php} | 0 .../laravel-api/{app => }/config/mail.php | 16 +- .../laravel-api/{app => }/config/queue.php | 47 +- .../laravel-api/{app => }/config/services.php | 25 +- .../laravel-api/{app => }/config/session.php | 23 +- .../laravel-api/{app => }/config/view.php | 18 +- examples/laravel-api/database/.gitignore | 1 + .../migrations}/.gitkeep | 0 .../2014_10_12_000000_create_users_table.php | 36 + ...12_100000_create_password_resets_table.php | 33 + .../controllers => database/seeds}/.gitkeep | 0 .../database/seeds/DatabaseSeeder.php | 5 +- examples/laravel-api/gulpfile.js | 16 + examples/laravel-api/package.json | 7 + examples/laravel-api/phpspec.yml | 5 + examples/laravel-api/phpunit.xml | 11 +- .../app/home/auth0_logo_final_blue_RGB.png | Bin 0 -> 17757 bytes examples/laravel-api/public/app/home/home.css | 92 + .../laravel-api/public/app/home/home.html | 6 + examples/laravel-api/public/app/home/home.js | 27 + .../laravel-api/public/app/login/login.css | 3 + .../laravel-api/public/app/login/login.html | 8 + .../laravel-api/public/app/login/login.js | 16 + .../.gitkeep => public/css/app.css} | 0 .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 ++ .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes examples/laravel-api/public/index.php | 37 +- examples/laravel-api/public/js/app.js | 63 + .../laravel-api/public/js/auth0-variables.js | 3 + examples/laravel-api/public/packages/.gitkeep | 0 examples/laravel-api/readme.md | 33 +- .../resources/assets/less/app.less | 8 + .../assets/less/bootstrap/alerts.less | 68 + .../assets/less/bootstrap/badges.less | 61 + .../assets/less/bootstrap/bootstrap.less | 50 + .../assets/less/bootstrap/breadcrumbs.less | 26 + .../assets/less/bootstrap/button-groups.less | 243 ++ .../assets/less/bootstrap/buttons.less | 160 ++ .../assets/less/bootstrap/carousel.less | 267 ++ .../assets/less/bootstrap/close.less | 33 + .../resources/assets/less/bootstrap/code.less | 69 + .../less/bootstrap/component-animations.less | 34 + .../assets/less/bootstrap/dropdowns.less | 213 ++ .../assets/less/bootstrap/forms.less | 546 ++++ .../assets/less/bootstrap/glyphicons.less | 234 ++ .../resources/assets/less/bootstrap/grid.less | 84 + .../assets/less/bootstrap/input-groups.less | 166 ++ .../assets/less/bootstrap/jumbotron.less | 49 + .../assets/less/bootstrap/labels.less | 64 + .../assets/less/bootstrap/list-group.less | 124 + .../assets/less/bootstrap/media.less | 47 + .../assets/less/bootstrap/mixins.less | 39 + .../assets/less/bootstrap/mixins/alerts.less | 14 + .../bootstrap/mixins/background-variant.less | 8 + .../less/bootstrap/mixins/border-radius.less | 18 + .../assets/less/bootstrap/mixins/buttons.less | 52 + .../less/bootstrap/mixins/center-block.less | 7 + .../less/bootstrap/mixins/clearfix.less | 22 + .../assets/less/bootstrap/mixins/forms.less | 85 + .../less/bootstrap/mixins/gradients.less | 59 + .../less/bootstrap/mixins/grid-framework.less | 91 + .../assets/less/bootstrap/mixins/grid.less | 122 + .../less/bootstrap/mixins/hide-text.less | 21 + .../assets/less/bootstrap/mixins/image.less | 33 + .../assets/less/bootstrap/mixins/labels.less | 12 + .../less/bootstrap/mixins/list-group.less | 29 + .../less/bootstrap/mixins/nav-divider.less | 10 + .../bootstrap/mixins/nav-vertical-align.less | 9 + .../assets/less/bootstrap/mixins/opacity.less | 8 + .../less/bootstrap/mixins/pagination.less | 23 + .../assets/less/bootstrap/mixins/panels.less | 24 + .../less/bootstrap/mixins/progress-bar.less | 10 + .../less/bootstrap/mixins/reset-filter.less | 8 + .../assets/less/bootstrap/mixins/resize.less | 6 + .../mixins/responsive-visibility.less | 15 + .../assets/less/bootstrap/mixins/size.less | 10 + .../less/bootstrap/mixins/tab-focus.less | 9 + .../less/bootstrap/mixins/table-row.less | 28 + .../less/bootstrap/mixins/text-emphasis.less | 8 + .../less/bootstrap/mixins/text-overflow.less | 8 + .../bootstrap/mixins/vendor-prefixes.less | 227 ++ .../assets/less/bootstrap/modals.less | 148 + .../assets/less/bootstrap/navbar.less | 660 +++++ .../resources/assets/less/bootstrap/navs.less | 244 ++ .../assets/less/bootstrap/normalize.less | 427 +++ .../assets/less/bootstrap/pager.less | 54 + .../assets/less/bootstrap/pagination.less | 88 + .../assets/less/bootstrap/panels.less | 261 ++ .../assets/less/bootstrap/popovers.less | 135 + .../assets/less/bootstrap/print.less | 107 + .../assets/less/bootstrap/progress-bars.less | 87 + .../less/bootstrap/responsive-embed.less | 35 + .../less/bootstrap/responsive-utilities.less | 194 ++ .../assets/less/bootstrap/scaffolding.less | 150 + .../assets/less/bootstrap/tables.less | 234 ++ .../assets/less/bootstrap/theme.less | 272 ++ .../assets/less/bootstrap/thumbnails.less | 36 + .../assets/less/bootstrap/tooltip.less | 103 + .../resources/assets/less/bootstrap/type.less | 302 ++ .../assets/less/bootstrap/utilities.less | 56 + .../assets/less/bootstrap/variables.less | 856 ++++++ .../assets/less/bootstrap/wells.less | 29 + .../{app => resources}/lang/en/pagination.php | 5 +- .../lang/en/passwords.php} | 10 +- .../{app => resources}/lang/en/validation.php | 33 +- .../laravel-api/resources/views/app.blade.php | 62 + .../resources/views/auth/login.blade.php | 61 + .../resources/views/auth/password.blade.php | 50 + .../resources/views/auth/register.blade.php | 65 + .../resources/views/auth/reset.blade.php | 59 + .../resources/views/emails/password.blade.php | 1 + .../resources/views/errors/503.blade.php | 41 + .../resources/views/home.blade.php | 17 + .../resources/views/layouts/master.blade.php | 10 + .../resources/views/welcome.blade.php | 48 + .../resources/views/welcome/index.blade.php | 14 + .../resources/views/welcome/login.blade.php | 24 + .../resources/views/welcome/spa.blade.php | 33 + examples/laravel-api/server.php | 21 +- .../storage/cache => storage/app}/.gitignore | 0 .../laravel-api/storage/framework/.gitignore | 6 + .../framework/cache}/.gitignore | 0 .../storage/framework/sessions/.gitignore | 2 + .../storage/framework/views/.gitignore | 2 + examples/laravel-api/storage/logs/.gitignore | 2 + .../{app => }/tests/ExampleTest.php | 4 +- examples/laravel-api/tests/TestCase.php | 19 + 199 files changed, 12223 insertions(+), 1910 deletions(-) create mode 100644 examples/.DS_Store delete mode 100644 examples/laravel-api/CONTRIBUTING.md delete mode 100644 examples/laravel-api/Procfile create mode 100644 examples/laravel-api/app/Commands/Command.php create mode 100644 examples/laravel-api/app/Console/Commands/Inspire.php create mode 100644 examples/laravel-api/app/Console/Kernel.php create mode 100644 examples/laravel-api/app/Events/Event.php create mode 100644 examples/laravel-api/app/Exceptions/Handler.php rename examples/laravel-api/app/{commands => Handlers/Commands}/.gitkeep (100%) rename examples/laravel-api/app/{config/packages => Handlers/Events}/.gitkeep (100%) create mode 100644 examples/laravel-api/app/Http/Controllers/Auth/AuthController.php create mode 100644 examples/laravel-api/app/Http/Controllers/Auth/PasswordController.php create mode 100644 examples/laravel-api/app/Http/Controllers/Controller.php create mode 100644 examples/laravel-api/app/Http/Controllers/HomeController.php create mode 100644 examples/laravel-api/app/Http/Controllers/WelcomeController.php create mode 100644 examples/laravel-api/app/Http/Kernel.php create mode 100644 examples/laravel-api/app/Http/Middleware/Authenticate.php create mode 100644 examples/laravel-api/app/Http/Middleware/RedirectIfAuthenticated.php create mode 100644 examples/laravel-api/app/Http/Middleware/VerifyCsrfToken.php create mode 100644 examples/laravel-api/app/Http/Requests/Request.php create mode 100644 examples/laravel-api/app/Http/routes.php create mode 100644 examples/laravel-api/app/Providers/AppServiceProvider.php create mode 100644 examples/laravel-api/app/Providers/BusServiceProvider.php create mode 100644 examples/laravel-api/app/Providers/ConfigServiceProvider.php create mode 100644 examples/laravel-api/app/Providers/EventServiceProvider.php create mode 100644 examples/laravel-api/app/Providers/RouteServiceProvider.php create mode 100644 examples/laravel-api/app/Services/Registrar.php create mode 100644 examples/laravel-api/app/User.php delete mode 100644 examples/laravel-api/app/config/cache.php delete mode 100644 examples/laravel-api/app/config/compile.php delete mode 100644 examples/laravel-api/app/config/local/app.php delete mode 100644 examples/laravel-api/app/config/local/database.php delete mode 100644 examples/laravel-api/app/config/packages/auth0/login/api.php delete mode 100644 examples/laravel-api/app/config/packages/barryvdh/laravel-cors/config.php delete mode 100644 examples/laravel-api/app/config/remote.php delete mode 100644 examples/laravel-api/app/config/testing/cache.php delete mode 100644 examples/laravel-api/app/config/testing/session.php delete mode 100644 examples/laravel-api/app/config/workbench.php delete mode 100644 examples/laravel-api/app/controllers/BaseController.php delete mode 100644 examples/laravel-api/app/controllers/HomeController.php delete mode 100644 examples/laravel-api/app/database/production.sqlite delete mode 100644 examples/laravel-api/app/database/seeds/.gitkeep delete mode 100644 examples/laravel-api/app/filters.php delete mode 100644 examples/laravel-api/app/models/User.php delete mode 100644 examples/laravel-api/app/routes.php delete mode 100644 examples/laravel-api/app/start/artisan.php delete mode 100644 examples/laravel-api/app/start/global.php delete mode 100644 examples/laravel-api/app/start/local.php delete mode 100644 examples/laravel-api/app/storage/.gitignore delete mode 100644 examples/laravel-api/app/storage/meta/.gitignore delete mode 100644 examples/laravel-api/app/storage/sessions/.gitignore delete mode 100644 examples/laravel-api/app/storage/views/.gitignore delete mode 100644 examples/laravel-api/app/tests/TestCase.php delete mode 100644 examples/laravel-api/app/views/emails/auth/reminder.blade.php delete mode 100644 examples/laravel-api/app/views/hello.php mode change 100755 => 100644 examples/laravel-api/artisan create mode 100644 examples/laravel-api/bootstrap/app.php delete mode 100644 examples/laravel-api/bootstrap/paths.php delete mode 100644 examples/laravel-api/bootstrap/start.php rename examples/laravel-api/{app => }/config/app.php (58%) rename examples/laravel-api/{app => }/config/auth.php (77%) create mode 100644 examples/laravel-api/config/cache.php create mode 100644 examples/laravel-api/config/compile.php rename examples/laravel-api/{app => }/config/database.php (77%) create mode 100644 examples/laravel-api/config/filesystems.php rename examples/laravel-api/{app/config/packages/auth0/login/config.php => config/laravel-auth0.php} (100%) rename examples/laravel-api/{app => }/config/mail.php (93%) rename examples/laravel-api/{app => }/config/queue.php (80%) mode change 100755 => 100644 rename examples/laravel-api/{app => }/config/services.php (74%) rename examples/laravel-api/{app => }/config/session.php (88%) rename examples/laravel-api/{app => }/config/view.php (61%) create mode 100644 examples/laravel-api/database/.gitignore rename examples/laravel-api/{app/config/packages/barryvdh/laravel-cors => database/migrations}/.gitkeep (100%) create mode 100644 examples/laravel-api/database/migrations/2014_10_12_000000_create_users_table.php create mode 100644 examples/laravel-api/database/migrations/2014_10_12_100000_create_password_resets_table.php rename examples/laravel-api/{app/controllers => database/seeds}/.gitkeep (100%) rename examples/laravel-api/{app => }/database/seeds/DatabaseSeeder.php (65%) create mode 100644 examples/laravel-api/gulpfile.js create mode 100644 examples/laravel-api/package.json create mode 100644 examples/laravel-api/phpspec.yml create mode 100644 examples/laravel-api/public/app/home/auth0_logo_final_blue_RGB.png create mode 100644 examples/laravel-api/public/app/home/home.css create mode 100644 examples/laravel-api/public/app/home/home.html create mode 100644 examples/laravel-api/public/app/home/home.js create mode 100644 examples/laravel-api/public/app/login/login.css create mode 100644 examples/laravel-api/public/app/login/login.html create mode 100644 examples/laravel-api/public/app/login/login.js rename examples/laravel-api/{app/database/migrations/.gitkeep => public/css/app.css} (100%) create mode 100644 examples/laravel-api/public/fonts/glyphicons-halflings-regular.eot create mode 100644 examples/laravel-api/public/fonts/glyphicons-halflings-regular.svg create mode 100644 examples/laravel-api/public/fonts/glyphicons-halflings-regular.ttf create mode 100644 examples/laravel-api/public/fonts/glyphicons-halflings-regular.woff create mode 100644 examples/laravel-api/public/fonts/glyphicons-halflings-regular.woff2 create mode 100644 examples/laravel-api/public/js/app.js create mode 100644 examples/laravel-api/public/js/auth0-variables.js delete mode 100644 examples/laravel-api/public/packages/.gitkeep create mode 100644 examples/laravel-api/resources/assets/less/app.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/alerts.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/badges.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/bootstrap.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/breadcrumbs.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/button-groups.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/buttons.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/carousel.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/close.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/code.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/component-animations.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/dropdowns.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/forms.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/glyphicons.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/grid.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/input-groups.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/jumbotron.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/labels.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/list-group.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/media.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/alerts.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/background-variant.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/border-radius.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/buttons.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/center-block.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/clearfix.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/forms.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/gradients.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/grid-framework.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/grid.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/hide-text.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/image.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/labels.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/list-group.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/nav-divider.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/nav-vertical-align.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/opacity.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/pagination.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/panels.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/progress-bar.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/reset-filter.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/resize.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/responsive-visibility.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/size.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/tab-focus.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/table-row.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/text-emphasis.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/text-overflow.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/mixins/vendor-prefixes.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/modals.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/navbar.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/navs.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/normalize.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/pager.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/pagination.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/panels.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/popovers.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/print.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/progress-bars.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/responsive-embed.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/responsive-utilities.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/scaffolding.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/tables.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/theme.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/thumbnails.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/tooltip.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/type.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/utilities.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/variables.less create mode 100644 examples/laravel-api/resources/assets/less/bootstrap/wells.less rename examples/laravel-api/{app => resources}/lang/en/pagination.php (96%) rename examples/laravel-api/{app/lang/en/reminders.php => resources/lang/en/passwords.php} (84%) rename examples/laravel-api/{app => resources}/lang/en/validation.php (91%) create mode 100644 examples/laravel-api/resources/views/app.blade.php create mode 100644 examples/laravel-api/resources/views/auth/login.blade.php create mode 100644 examples/laravel-api/resources/views/auth/password.blade.php create mode 100644 examples/laravel-api/resources/views/auth/register.blade.php create mode 100644 examples/laravel-api/resources/views/auth/reset.blade.php create mode 100644 examples/laravel-api/resources/views/emails/password.blade.php create mode 100644 examples/laravel-api/resources/views/errors/503.blade.php create mode 100644 examples/laravel-api/resources/views/home.blade.php create mode 100644 examples/laravel-api/resources/views/layouts/master.blade.php create mode 100644 examples/laravel-api/resources/views/welcome.blade.php create mode 100644 examples/laravel-api/resources/views/welcome/index.blade.php create mode 100644 examples/laravel-api/resources/views/welcome/login.blade.php create mode 100644 examples/laravel-api/resources/views/welcome/spa.blade.php rename examples/laravel-api/{app/storage/cache => storage/app}/.gitignore (100%) create mode 100644 examples/laravel-api/storage/framework/.gitignore rename examples/laravel-api/{app/storage/logs => storage/framework/cache}/.gitignore (100%) create mode 100644 examples/laravel-api/storage/framework/sessions/.gitignore create mode 100644 examples/laravel-api/storage/framework/views/.gitignore create mode 100644 examples/laravel-api/storage/logs/.gitignore rename examples/laravel-api/{app => }/tests/ExampleTest.php (59%) create mode 100644 examples/laravel-api/tests/TestCase.php diff --git a/.DS_Store b/.DS_Store index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..2606934491266a4973c24a5b809a11b26d518c2d 100644 GIT binary patch literal 6148 zcmeHK-HOvd6h70|HEj_hx*~X!ONFvjMY@;SZdX`vrEFvuakVB*pd;B#Nz$!S3b_;? z!~fS1z4QU}NxZD*%*^Vx)eCP#+&ST#@66egAcZw}vQ%w4i~>f1e@y{;ch5l|1RTN;mghAB?l19{*b~jCqzfn_pR}TsgCH)~eR( zblK-?550jHd%2&FvbLW-kS!iYfzG>rJ~+`Rl$jn;a@X-*r?Wc_Bd z;j~(<>C}F1Sy!&z+Ss{2oW6MZ>h+tq@7{m-C?^gK7f5LrG#@ltzY4opy8#{8k(@&a7Z_g_7-jr%0 zteK-xz$oxX3efuCpcA?p3x#s&z#xwRh!yOXhBh>FVe5rZi@ z_B*=H)mSK0bYS}M!Ss`vKA|xAbR6H2<-lBpCK?5d0`m%#Rnw;Zf9v<>|9O&W83l|2 z|CIu)((yWNoRZ#KmnKJht%Lp;os8-Vg_43nZ^tsBt@tv!G`#0fg6L{26k-pW`4EsY Lm|zt6s|tJvPKlfA delta 66 zcmZoMXfc=|#>AjHu~2NHo+1YW5HK<@2y7PQ5M$Y_z%h$?Gdl-A2T%b}u84%9H(hI5x+KtY8KJ$3PAT diff --git a/examples/.DS_Store b/examples/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6e956da6da08abd1bfa9281148b86bab5e83d5cb GIT binary patch literal 6148 zcmeHKUrQT75TA`{y_lCPRVnzgj|wTIEhRpl(F%PK0x629q<6i8EF5MO6#Wu@5+Ci%?nad8tA;Xj%>HI)XLj#?d+Z+o5Y0jO4!{Kf2bHi?!Qug-cG4*+ zSr4JmeH=psF}wvIdQ;Ktm_-I??y5LvKJ-!V&Y$`mr{97&4KRX!k8RXdRB>~I<)c}_ zFzeZ@>!25_EU(wEL}{-4;^n+kS*X(EzFIhHchg}z_wzy4^!o?8rot$&cFWJZ6Z=b= z#<#W~?5b$kaThn!B==Pk_3xw}?x`e9hs|`5gxO)+^tY$NyxVb?TK(u4Q(Jx#?W#-# zDpvW4Q=zBhE{{g<8|yV$AJ^n){X@Mb8;!ZJncomment(PHP_EOL.Inspiring::quote().PHP_EOL); + } + +} diff --git a/examples/laravel-api/app/Console/Kernel.php b/examples/laravel-api/app/Console/Kernel.php new file mode 100644 index 00000000..0c088c89 --- /dev/null +++ b/examples/laravel-api/app/Console/Kernel.php @@ -0,0 +1,29 @@ +command('inspire') + ->hourly(); + } + +} diff --git a/examples/laravel-api/app/Events/Event.php b/examples/laravel-api/app/Events/Event.php new file mode 100644 index 00000000..d59f7690 --- /dev/null +++ b/examples/laravel-api/app/Events/Event.php @@ -0,0 +1,7 @@ +auth = $auth; + $this->registrar = $registrar; + + $this->middleware('guest', ['except' => 'getLogout']); + } + +} diff --git a/examples/laravel-api/app/Http/Controllers/Auth/PasswordController.php b/examples/laravel-api/app/Http/Controllers/Auth/PasswordController.php new file mode 100644 index 00000000..31061935 --- /dev/null +++ b/examples/laravel-api/app/Http/Controllers/Auth/PasswordController.php @@ -0,0 +1,38 @@ +auth = $auth; + $this->passwords = $passwords; + + $this->middleware('guest'); + } + +} diff --git a/examples/laravel-api/app/Http/Controllers/Controller.php b/examples/laravel-api/app/Http/Controllers/Controller.php new file mode 100644 index 00000000..27b3f452 --- /dev/null +++ b/examples/laravel-api/app/Http/Controllers/Controller.php @@ -0,0 +1,11 @@ +middleware('auth'); + } + + /** + * Show the application dashboard to the user. + * + * @return Response + */ + public function index() + { + return view('home'); + } + +} diff --git a/examples/laravel-api/app/Http/Controllers/WelcomeController.php b/examples/laravel-api/app/Http/Controllers/WelcomeController.php new file mode 100644 index 00000000..8c111b08 --- /dev/null +++ b/examples/laravel-api/app/Http/Controllers/WelcomeController.php @@ -0,0 +1,60 @@ +middleware('guest'); + } + + /** + * Show the application welcome screen to the user. + * + * @return Response + */ + public function index() + { + $isLoggedIn = \Auth::check(); + return view('welcome.index')->with('isLoggedIn', $isLoggedIn); + } + + public function login() { + $auth0Config = config('laravel-auth0'); + return view('welcome.login')->with('auth0Config',$auth0Config); + } + + public function spa() { + return view('welcome.spa'); + } + + public function logout() { + \Auth::logout(); + return \Redirect::intended('/'); + } + + public function dump() { + dd(\Auth::user()->getUserInfo()); + } + + public function api() { + return response()->json(['status' => 'pong!']); + } + + +} diff --git a/examples/laravel-api/app/Http/Kernel.php b/examples/laravel-api/app/Http/Kernel.php new file mode 100644 index 00000000..1266e3d5 --- /dev/null +++ b/examples/laravel-api/app/Http/Kernel.php @@ -0,0 +1,33 @@ + 'App\Http\Middleware\Authenticate', + 'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth', + 'guest' => 'App\Http\Middleware\RedirectIfAuthenticated', + 'auth0.jwt' => 'Auth0\Login\Middleware\Auth0JWTMiddleware', + ]; + +} diff --git a/examples/laravel-api/app/Http/Middleware/Authenticate.php b/examples/laravel-api/app/Http/Middleware/Authenticate.php new file mode 100644 index 00000000..72a7613a --- /dev/null +++ b/examples/laravel-api/app/Http/Middleware/Authenticate.php @@ -0,0 +1,50 @@ +auth = $auth; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + if ($this->auth->guest()) + { + if ($request->ajax()) + { + return response('Unauthorized.', 401); + } + else + { + return redirect()->guest('auth/login'); + } + } + + return $next($request); + } + +} diff --git a/examples/laravel-api/app/Http/Middleware/RedirectIfAuthenticated.php b/examples/laravel-api/app/Http/Middleware/RedirectIfAuthenticated.php new file mode 100644 index 00000000..dd5a8672 --- /dev/null +++ b/examples/laravel-api/app/Http/Middleware/RedirectIfAuthenticated.php @@ -0,0 +1,44 @@ +auth = $auth; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + if ($this->auth->check()) + { + return new RedirectResponse(url('/home')); + } + + return $next($request); + } + +} diff --git a/examples/laravel-api/app/Http/Middleware/VerifyCsrfToken.php b/examples/laravel-api/app/Http/Middleware/VerifyCsrfToken.php new file mode 100644 index 00000000..750a39b1 --- /dev/null +++ b/examples/laravel-api/app/Http/Middleware/VerifyCsrfToken.php @@ -0,0 +1,20 @@ + 'home', 'uses' => 'WelcomeController@index']); +Route::get('/auth/login', ['as' => 'login', 'uses' => 'WelcomeController@login']); +Route::get('/logout', ['as' => 'logout', 'uses' => 'WelcomeController@logout']); +Route::get('/auth0/callback', ['as' => 'logincallback', 'uses' => '\Auth0\Login\Auth0Controller@callback']); + +Route::get('/dump', ['as' => 'dump', 'uses' => 'WelcomeController@dump', 'middleware' => 'auth']); + +Route::get('/spa', ['as' => 'spa', 'uses' => 'WelcomeController@spa']); +Route::get('/api/ping', ['as' => 'api', 'uses' => 'WelcomeController@api', 'middleware' => 'auth0.jwt']); diff --git a/examples/laravel-api/app/Providers/AppServiceProvider.php b/examples/laravel-api/app/Providers/AppServiceProvider.php new file mode 100644 index 00000000..576e7708 --- /dev/null +++ b/examples/laravel-api/app/Providers/AppServiceProvider.php @@ -0,0 +1,38 @@ +app->bind( + 'Illuminate\Contracts\Auth\Registrar', + 'App\Services\Registrar' + ); + + $this->app->bind( + '\Auth0\Login\Contract\Auth0UserRepository', + '\Auth0\Login\Repository\Auth0UserRepository'); + } + +} diff --git a/examples/laravel-api/app/Providers/BusServiceProvider.php b/examples/laravel-api/app/Providers/BusServiceProvider.php new file mode 100644 index 00000000..f0d9be6f --- /dev/null +++ b/examples/laravel-api/app/Providers/BusServiceProvider.php @@ -0,0 +1,34 @@ +mapUsing(function($command) + { + return Dispatcher::simpleMapping( + $command, 'App\Commands', 'App\Handlers\Commands' + ); + }); + } + + /** + * Register any application services. + * + * @return void + */ + public function register() + { + // + } + +} diff --git a/examples/laravel-api/app/Providers/ConfigServiceProvider.php b/examples/laravel-api/app/Providers/ConfigServiceProvider.php new file mode 100644 index 00000000..06e57992 --- /dev/null +++ b/examples/laravel-api/app/Providers/ConfigServiceProvider.php @@ -0,0 +1,23 @@ + [ + 'EventListener', + ], + ]; + + /** + * Register any other events for your application. + * + * @param \Illuminate\Contracts\Events\Dispatcher $events + * @return void + */ + public function boot(DispatcherContract $events) + { + parent::boot($events); + + // + } + +} diff --git a/examples/laravel-api/app/Providers/RouteServiceProvider.php b/examples/laravel-api/app/Providers/RouteServiceProvider.php new file mode 100644 index 00000000..e533e0e9 --- /dev/null +++ b/examples/laravel-api/app/Providers/RouteServiceProvider.php @@ -0,0 +1,44 @@ +group(['namespace' => $this->namespace], function($router) + { + require app_path('Http/routes.php'); + }); + } + +} diff --git a/examples/laravel-api/app/Services/Registrar.php b/examples/laravel-api/app/Services/Registrar.php new file mode 100644 index 00000000..10354681 --- /dev/null +++ b/examples/laravel-api/app/Services/Registrar.php @@ -0,0 +1,39 @@ + 'required|max:255', + 'email' => 'required|email|max:255|unique:users', + 'password' => 'required|confirmed|min:6', + ]); + } + + /** + * Create a new user instance after a valid registration. + * + * @param array $data + * @return User + */ + public function create(array $data) + { + return User::create([ + 'name' => $data['name'], + 'email' => $data['email'], + 'password' => bcrypt($data['password']), + ]); + } + +} diff --git a/examples/laravel-api/app/User.php b/examples/laravel-api/app/User.php new file mode 100644 index 00000000..2dae8479 --- /dev/null +++ b/examples/laravel-api/app/User.php @@ -0,0 +1,34 @@ + 'file', - - /* - |-------------------------------------------------------------------------- - | File Cache Location - |-------------------------------------------------------------------------- - | - | When using the "file" cache driver, we need a location where the cache - | files may be stored. A sensible default has been specified, but you - | are free to change it to any other place on disk that you desire. - | - */ - - 'path' => storage_path().'/cache', - - /* - |-------------------------------------------------------------------------- - | Database Cache Connection - |-------------------------------------------------------------------------- - | - | When using the "database" cache driver you may specify the connection - | that should be used to store the cached items. When this option is - | null the default database connection will be utilized for cache. - | - */ - - 'connection' => null, - - /* - |-------------------------------------------------------------------------- - | Database Cache Table - |-------------------------------------------------------------------------- - | - | When using the "database" cache driver we need to know the table that - | should be used to store the cached items. A default table name has - | been provided but you're free to change it however you deem fit. - | - */ - - 'table' => 'cache', - - /* - |-------------------------------------------------------------------------- - | Memcached Servers - |-------------------------------------------------------------------------- - | - | Now you may specify an array of your Memcached servers that should be - | used when utilizing the Memcached cache driver. All of the servers - | should contain a value for "host", "port", and "weight" options. - | - */ - - 'memcached' => array( - - array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100), - - ), - - /* - |-------------------------------------------------------------------------- - | Cache Key Prefix - |-------------------------------------------------------------------------- - | - | When utilizing a RAM based store such as APC or Memcached, there might - | be other applications utilizing the same cache. So, we'll specify a - | value to get prefixed to all our keys so we can avoid collisions. - | - */ - - 'prefix' => 'laravel', - -); diff --git a/examples/laravel-api/app/config/compile.php b/examples/laravel-api/app/config/compile.php deleted file mode 100644 index d5e55181..00000000 --- a/examples/laravel-api/app/config/compile.php +++ /dev/null @@ -1,18 +0,0 @@ - true, - -); diff --git a/examples/laravel-api/app/config/local/database.php b/examples/laravel-api/app/config/local/database.php deleted file mode 100644 index fbcb95ae..00000000 --- a/examples/laravel-api/app/config/local/database.php +++ /dev/null @@ -1,47 +0,0 @@ - array( - - 'mysql' => array( - 'driver' => 'mysql', - 'host' => 'localhost', - 'database' => 'homestead', - 'username' => 'homestead', - 'password' => 'secret', - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => '', - ), - - 'pgsql' => array( - 'driver' => 'pgsql', - 'host' => 'localhost', - 'database' => 'homestead', - 'username' => 'homestead', - 'password' => 'secret', - 'charset' => 'utf8', - 'prefix' => '', - 'schema' => 'public', - ), - - ), - -); diff --git a/examples/laravel-api/app/config/packages/auth0/login/api.php b/examples/laravel-api/app/config/packages/auth0/login/api.php deleted file mode 100644 index 3678a79c..00000000 --- a/examples/laravel-api/app/config/packages/auth0/login/api.php +++ /dev/null @@ -1,24 +0,0 @@ - getenv('AUTH0_CLIENT_ID'), - /* - |-------------------------------------------------------------------------- - | JWT Secret - |-------------------------------------------------------------------------- - | The secret used to encrypt the JWT - | - */ - - 'secret' => getenv('AUTH0_CLIENT_SECRET') - -); diff --git a/examples/laravel-api/app/config/packages/barryvdh/laravel-cors/config.php b/examples/laravel-api/app/config/packages/barryvdh/laravel-cors/config.php deleted file mode 100644 index e8d4d915..00000000 --- a/examples/laravel-api/app/config/packages/barryvdh/laravel-cors/config.php +++ /dev/null @@ -1,36 +0,0 @@ - array( - 'supportsCredentials' => false, - 'allowedOrigins' => array(), - 'allowedHeaders' => array(), - 'allowedMethods' => array(), - 'exposedHeaders' => array(), - 'maxAge' => 0, - 'hosts' => array(), - ), - - 'paths' => array( - '*' => array( - 'allowedOrigins' => array('*'), - 'allowedHeaders' => array('Content-Type', 'Authorization', 'Accept'), - 'allowedMethods' => array('POST', 'PUT', 'GET', 'DELETE') - ), - ), - -); diff --git a/examples/laravel-api/app/config/remote.php b/examples/laravel-api/app/config/remote.php deleted file mode 100644 index 2169c434..00000000 --- a/examples/laravel-api/app/config/remote.php +++ /dev/null @@ -1,59 +0,0 @@ - 'production', - - /* - |-------------------------------------------------------------------------- - | Remote Server Connections - |-------------------------------------------------------------------------- - | - | These are the servers that will be accessible via the SSH task runner - | facilities of Laravel. This feature radically simplifies executing - | tasks on your servers, such as deploying out these applications. - | - */ - - 'connections' => array( - - 'production' => array( - 'host' => '', - 'username' => '', - 'password' => '', - 'key' => '', - 'keyphrase' => '', - 'root' => '/var/www', - ), - - ), - - /* - |-------------------------------------------------------------------------- - | Remote Server Groups - |-------------------------------------------------------------------------- - | - | Here you may list connections under a single group name, which allows - | you to easily access all of the servers at once using a short name - | that is extremely easy to remember, such as "web" or "database". - | - */ - - 'groups' => array( - - 'web' => array('production') - - ), - -); diff --git a/examples/laravel-api/app/config/testing/cache.php b/examples/laravel-api/app/config/testing/cache.php deleted file mode 100644 index 66a8a39a..00000000 --- a/examples/laravel-api/app/config/testing/cache.php +++ /dev/null @@ -1,20 +0,0 @@ - 'array', - -); diff --git a/examples/laravel-api/app/config/testing/session.php b/examples/laravel-api/app/config/testing/session.php deleted file mode 100644 index 0364b63d..00000000 --- a/examples/laravel-api/app/config/testing/session.php +++ /dev/null @@ -1,21 +0,0 @@ - 'array', - -); diff --git a/examples/laravel-api/app/config/workbench.php b/examples/laravel-api/app/config/workbench.php deleted file mode 100644 index 87c5e387..00000000 --- a/examples/laravel-api/app/config/workbench.php +++ /dev/null @@ -1,31 +0,0 @@ - '', - - /* - |-------------------------------------------------------------------------- - | Workbench Author E-Mail Address - |-------------------------------------------------------------------------- - | - | Like the option above, your e-mail address is used when generating new - | workbench packages. The e-mail is placed in your composer.json file - | automatically after the package is created by the workbench tool. - | - */ - - 'email' => '', - -); diff --git a/examples/laravel-api/app/controllers/BaseController.php b/examples/laravel-api/app/controllers/BaseController.php deleted file mode 100644 index 2bee4644..00000000 --- a/examples/laravel-api/app/controllers/BaseController.php +++ /dev/null @@ -1,18 +0,0 @@ -layout)) - { - $this->layout = View::make($this->layout); - } - } - -} diff --git a/examples/laravel-api/app/controllers/HomeController.php b/examples/laravel-api/app/controllers/HomeController.php deleted file mode 100644 index ede41a7a..00000000 --- a/examples/laravel-api/app/controllers/HomeController.php +++ /dev/null @@ -1,23 +0,0 @@ -'auth-jwt', function() { - return "All good. You only get this message if you're authenticated"; -})); diff --git a/examples/laravel-api/app/start/artisan.php b/examples/laravel-api/app/start/artisan.php deleted file mode 100644 index 1df850bc..00000000 --- a/examples/laravel-api/app/start/artisan.php +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - -

Password Reset

- -
- To reset your password, complete this form: {{ URL::to('password/reset', array($token)) }}.
- This link will expire in {{ Config::get('auth.reminder.expire', 60) }} minutes. -
- - diff --git a/examples/laravel-api/app/views/hello.php b/examples/laravel-api/app/views/hello.php deleted file mode 100644 index 64842421..00000000 --- a/examples/laravel-api/app/views/hello.php +++ /dev/null @@ -1,42 +0,0 @@ - - - - - Laravel PHP Framework - - - -
- Laravel PHP Framework -

You have arrived.

-
- - diff --git a/examples/laravel-api/artisan b/examples/laravel-api/artisan old mode 100755 new mode 100644 index 5c408ad8..eb5e2bb6 --- a/examples/laravel-api/artisan +++ b/examples/laravel-api/artisan @@ -15,35 +15,7 @@ require __DIR__.'/bootstrap/autoload.php'; -/* -|-------------------------------------------------------------------------- -| Turn On The Lights -|-------------------------------------------------------------------------- -| -| We need to illuminate PHP development, so let's turn on the lights. -| This bootstraps the framework and gets it ready for and then it -| will load up this application so that we can run it and send -| the responses back to the browser and delight these users. -| -*/ - -$app = require_once __DIR__.'/bootstrap/start.php'; - -/* -|-------------------------------------------------------------------------- -| Load The Artisan Console Application -|-------------------------------------------------------------------------- -| -| We'll need to run the script to load and return the Artisan console -| application. We keep this in its own script so that we will load -| the console application independent of running commands which -| will allow us to fire commands from Routes when we want to. -| -*/ - -$app->setRequestForConsoleEnvironment(); - -$artisan = Illuminate\Console\Application::start($app); +$app = require_once __DIR__.'/bootstrap/app.php'; /* |-------------------------------------------------------------------------- @@ -56,7 +28,12 @@ $artisan = Illuminate\Console\Application::start($app); | */ -$status = $artisan->run(); +$kernel = $app->make('Illuminate\Contracts\Console\Kernel'); + +$status = $kernel->handle( + $input = new Symfony\Component\Console\Input\ArgvInput, + new Symfony\Component\Console\Output\ConsoleOutput +); /* |-------------------------------------------------------------------------- @@ -69,6 +46,6 @@ $status = $artisan->run(); | */ -$app->shutdown(); +$kernel->terminate($input, $status); exit($status); diff --git a/examples/laravel-api/bootstrap/app.php b/examples/laravel-api/bootstrap/app.php new file mode 100644 index 00000000..f50a3f72 --- /dev/null +++ b/examples/laravel-api/bootstrap/app.php @@ -0,0 +1,55 @@ +singleton( + 'Illuminate\Contracts\Http\Kernel', + 'App\Http\Kernel' +); + +$app->singleton( + 'Illuminate\Contracts\Console\Kernel', + 'App\Console\Kernel' +); + +$app->singleton( + 'Illuminate\Contracts\Debug\ExceptionHandler', + 'App\Exceptions\Handler' +); + +/* +|-------------------------------------------------------------------------- +| Return The Application +|-------------------------------------------------------------------------- +| +| This script returns the application instance. The instance is given to +| the calling script so we can separate the building of the instances +| from the actual running of the application and sending responses. +| +*/ + +return $app; diff --git a/examples/laravel-api/bootstrap/autoload.php b/examples/laravel-api/bootstrap/autoload.php index 6b329312..e0d3db1c 100644 --- a/examples/laravel-api/bootstrap/autoload.php +++ b/examples/laravel-api/bootstrap/autoload.php @@ -27,49 +27,11 @@ | */ -if (file_exists($compiled = __DIR__.'/compiled.php')) +if (file_exists($compiledPath = __DIR__.'/../vendor/compiled.php')) { - require $compiled; + require $compiledPath; } - -/* -|-------------------------------------------------------------------------- -| Setup Patchwork UTF-8 Handling -|-------------------------------------------------------------------------- -| -| The Patchwork library provides solid handling of UTF-8 strings as well -| as provides replacements for all mb_* and iconv type functions that -| are not available by default in PHP. We'll setup this stuff here. -| -*/ - -Patchwork\Utf8\Bootup::initMbstring(); - -/* -|-------------------------------------------------------------------------- -| Register The Laravel Auto Loader -|-------------------------------------------------------------------------- -| -| We register an auto-loader "behind" the Composer loader that can load -| model classes on the fly, even if the autoload files have not been -| regenerated for the application. We'll add it to the stack here. -| -*/ - -Illuminate\Support\ClassLoader::register(); - -/* -|-------------------------------------------------------------------------- -| Register The Workbench Loaders -|-------------------------------------------------------------------------- -| -| The Laravel workbench provides a convenient place to develop packages -| when working locally. However we will need to load in the Composer -| auto-load files for the packages so that these can be used here. -| -*/ - -if (is_dir($workbench = __DIR__.'/../workbench')) +elseif (file_exists($compiledPath = __DIR__.'/../storage/framework/compiled.php')) { - Illuminate\Workbench\Starter::start($workbench); + require $compiledPath; } diff --git a/examples/laravel-api/bootstrap/paths.php b/examples/laravel-api/bootstrap/paths.php deleted file mode 100644 index 5a1f640b..00000000 --- a/examples/laravel-api/bootstrap/paths.php +++ /dev/null @@ -1,57 +0,0 @@ - __DIR__.'/../app', - - /* - |-------------------------------------------------------------------------- - | Public Path - |-------------------------------------------------------------------------- - | - | The public path contains the assets for your web application, such as - | your JavaScript and CSS files, and also contains the primary entry - | point for web requests into these applications from the outside. - | - */ - - 'public' => __DIR__.'/../public', - - /* - |-------------------------------------------------------------------------- - | Base Path - |-------------------------------------------------------------------------- - | - | The base path is the root of the Laravel installation. Most likely you - | will not need to change this value. But, if for some wild reason it - | is necessary you will do so here, just proceed with some caution. - | - */ - - 'base' => __DIR__.'/..', - - /* - |-------------------------------------------------------------------------- - | Storage Path - |-------------------------------------------------------------------------- - | - | The storage path is used by Laravel to store cached Blade views, logs - | and other pieces of information. You may modify the path here when - | you want to change the location of this directory for your apps. - | - */ - - 'storage' => __DIR__.'/../app/storage', - -); diff --git a/examples/laravel-api/bootstrap/start.php b/examples/laravel-api/bootstrap/start.php deleted file mode 100644 index 84559be3..00000000 --- a/examples/laravel-api/bootstrap/start.php +++ /dev/null @@ -1,73 +0,0 @@ -detectEnvironment(array( - - 'local' => array('homestead'), - -)); - -/* -|-------------------------------------------------------------------------- -| Bind Paths -|-------------------------------------------------------------------------- -| -| Here we are binding the paths configured in paths.php to the app. You -| should not be changing these here. If you need to change these you -| may do so within the paths.php file and they will be bound here. -| -*/ - -$app->bindInstallPaths(require __DIR__.'/paths.php'); - -/* -|-------------------------------------------------------------------------- -| Load The Application -|-------------------------------------------------------------------------- -| -| Here we will load this Illuminate application. We will keep this in a -| separate location so we can isolate the creation of an application -| from the actual running of the application with a given request. -| -*/ - -$framework = $app['path.base']. - '/vendor/laravel/framework/src'; - -require $framework.'/Illuminate/Foundation/start.php'; - -/* -|-------------------------------------------------------------------------- -| Return The Application -|-------------------------------------------------------------------------- -| -| This script returns the application instance. The instance is given to -| the calling script so we can separate the building of the instances -| from the actual running of the application and sending responses. -| -*/ - -return $app; diff --git a/examples/laravel-api/composer.json b/examples/laravel-api/composer.json index 4833e4e5..c54d5c1a 100644 --- a/examples/laravel-api/composer.json +++ b/examples/laravel-api/composer.json @@ -3,20 +3,28 @@ "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", + "type": "project", "require": { - "laravel/framework": "4.2.*", - "auth0/login" : "1.0.6", - "vlucas/phpdotenv": "dev-master", - "barryvdh/laravel-cors": "0.2.x" + "laravel/framework": "5.0.*", + "adoy/oauth2": "dev-master", + "firebase/php-jwt" : "dev-master", + "auth0/login": "2.x.x-dev" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "phpspec/phpspec": "~2.1" }, "autoload": { "classmap": [ - "app/commands", - "app/controllers", - "app/models", - "app/database/migrations", - "app/database/seeds", - "app/tests/TestCase.php" + "database" + ], + "psr-4": { + "App\\": "app/" + } + }, + "autoload-dev": { + "classmap": [ + "tests/TestCase.php" ] }, "scripts": { @@ -29,11 +37,11 @@ "php artisan optimize" ], "post-create-project-cmd": [ + "php -r \"copy('.env.example', '.env');\"", "php artisan key:generate" ] }, "config": { "preferred-install": "dist" - }, - "minimum-stability": "dev" + } } diff --git a/examples/laravel-api/composer.lock b/examples/laravel-api/composer.lock index 8a2ea64c..06540dfd 100644 --- a/examples/laravel-api/composer.lock +++ b/examples/laravel-api/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "61c2a5a5d3ee1765c2f1fc159ceb277b", + "hash": "eb9fcfccc9f70b20ec4144dd62ea5af9", "packages": [ { "name": "adoy/oauth2", @@ -46,49 +46,6 @@ "description": "Light PHP wrapper for the OAuth 2.0 protocol (based on OAuth 2.0 Authorization Protocol draft-ietf-oauth-v2-15)", "time": "2014-03-07 16:05:00" }, - { - "name": "asm89/stack-cors", - "version": "0.2.1", - "source": { - "type": "git", - "url": "https://github.com/asm89/stack-cors.git", - "reference": "2d77e77251a434e4527315313a672f5801b29fa2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/asm89/stack-cors/zipball/2d77e77251a434e4527315313a672f5801b29fa2", - "reference": "2d77e77251a434e4527315313a672f5801b29fa2", - "shasum": "" - }, - "require": { - "php": ">=5.3.2", - "symfony/http-foundation": "~2.1", - "symfony/http-kernel": "~2.1" - }, - "type": "library", - "autoload": { - "psr-0": { - "Asm89\\Stack": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alexander", - "email": "iam.asm89@gmail.com" - } - ], - "description": "Cross-origin resource sharing library and stack middleware", - "homepage": "https://github.com/asm89/stack-cors", - "keywords": [ - "cors", - "stack" - ], - "time": "2014-07-28 07:22:35" - }, { "name": "auth0/auth0-php", "version": "0.6.6", @@ -131,23 +88,24 @@ }, { "name": "auth0/login", - "version": "1.0.6", + "version": "2.x-dev", "source": { "type": "git", "url": "https://github.com/auth0/laravel-auth0.git", - "reference": "272d84817251c7d1065d141bb107a53be276ddd9" + "reference": "fc951382ca4c12164925993728a54bf06b8fc7e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/auth0/laravel-auth0/zipball/272d84817251c7d1065d141bb107a53be276ddd9", - "reference": "272d84817251c7d1065d141bb107a53be276ddd9", + "url": "https://api.github.com/repos/auth0/laravel-auth0/zipball/fc951382ca4c12164925993728a54bf06b8fc7e4", + "reference": "fc951382ca4c12164925993728a54bf06b8fc7e4", "shasum": "" }, "require": { "adoy/oauth2": "dev-master", "auth0/auth0-php": "0.6.*", "firebase/php-jwt": "dev-master", - "illuminate/support": "4.*", + "illuminate/contracts": "5.*", + "illuminate/support": "5.*", "php": ">=5.3.0" }, "type": "library", @@ -171,31 +129,44 @@ } ], "description": "Laravel plugin that helps authenticate with the auth0 service", - "time": "2014-08-01 19:59:23" + "time": "2015-04-20 17:30:31" }, { - "name": "barryvdh/laravel-cors", - "version": "v0.2.2", + "name": "classpreloader/classpreloader", + "version": "1.3.0", "source": { "type": "git", - "url": "https://github.com/barryvdh/laravel-cors.git", - "reference": "ce25db72385c135b74cdaf061dbd444957c363d2" + "url": "https://github.com/ClassPreloader/ClassPreloader.git", + "reference": "0544616ba33fb2a6b792b3a7822650810c6d65d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-cors/zipball/ce25db72385c135b74cdaf061dbd444957c363d2", - "reference": "ce25db72385c135b74cdaf061dbd444957c363d2", + "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/0544616ba33fb2a6b792b3a7822650810c6d65d9", + "reference": "0544616ba33fb2a6b792b3a7822650810c6d65d9", "shasum": "" }, "require": { - "asm89/stack-cors": "0.2.x", - "illuminate/support": "~4.1", - "php": ">=5.3.0" + "nikic/php-parser": "^1.2.2", + "php": ">=5.3.3", + "symfony/console": "~2.1", + "symfony/filesystem": "~2.1", + "symfony/finder": "~2.1" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" }, + "bin": [ + "classpreloader.php" + ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, "autoload": { "psr-4": { - "Barryvdh\\Cors\\": "src/" + "ClassPreloader\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -204,133 +175,141 @@ ], "authors": [ { - "name": "Barry vd. Heuvel", - "email": "barryvdh@gmail.com" + "name": "Graham Campbell", + "email": "graham@mineuk.com" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com" } ], - "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application", + "description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case", "keywords": [ - "api", - "cors", - "crossdomain", - "laravel" + "autoload", + "class", + "preload" ], - "time": "2014-05-30 18:49:44" + "time": "2015-04-15 21:59:30" }, { - "name": "classpreloader/classpreloader", - "version": "dev-master", + "name": "danielstjules/stringy", + "version": "1.9.0", "source": { "type": "git", - "url": "https://github.com/mtdowling/ClassPreloader.git", - "reference": "2c9f3bcbab329570c57339895bd11b5dd3b00877" + "url": "https://github.com/danielstjules/Stringy.git", + "reference": "3cf18e9e424a6dedc38b7eb7ef580edb0929461b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mtdowling/ClassPreloader/zipball/2c9f3bcbab329570c57339895bd11b5dd3b00877", - "reference": "2c9f3bcbab329570c57339895bd11b5dd3b00877", + "url": "https://api.github.com/repos/danielstjules/Stringy/zipball/3cf18e9e424a6dedc38b7eb7ef580edb0929461b", + "reference": "3cf18e9e424a6dedc38b7eb7ef580edb0929461b", "shasum": "" }, "require": { - "nikic/php-parser": "~0.9", - "php": ">=5.3.3", - "symfony/console": "~2.1", - "symfony/filesystem": "~2.1", - "symfony/finder": "~2.1" + "ext-mbstring": "*", + "php": ">=5.3.0" }, - "bin": [ - "classpreloader.php" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } + "require-dev": { + "phpunit/phpunit": "~4.0" }, + "type": "library", "autoload": { - "psr-0": { - "ClassPreloader": "src/" - } + "psr-4": { + "Stringy\\": "src/" + }, + "files": [ + "src/Create.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case", + "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": [ - "autoload", - "class", - "preload" + "UTF", + "helpers", + "manipulation", + "methods", + "multibyte", + "string", + "utf-8", + "utility", + "utils" ], - "time": "2014-03-12 00:05:31" + "time": "2015-02-10 06:19:18" }, { - "name": "d11wtq/boris", - "version": "v1.0.8", + "name": "dnoegel/php-xdg-base-dir", + "version": "0.1", "source": { "type": "git", - "url": "https://github.com/d11wtq/boris.git", - "reference": "125dd4e5752639af7678a22ea597115646d89c6e" + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/d11wtq/boris/zipball/125dd4e5752639af7678a22ea597115646d89c6e", - "reference": "125dd4e5752639af7678a22ea597115646d89c6e", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/265b8593498b997dc2d31e75b89f053b5cc9621a", + "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=5.3.2" }, - "suggest": { - "ext-pcntl": "*", - "ext-posix": "*", - "ext-readline": "*" + "require-dev": { + "phpunit/phpunit": "@stable" }, - "bin": [ - "bin/boris" - ], - "type": "library", + "type": "project", "autoload": { - "psr-0": { - "Boris": "lib" + "psr-4": { + "XdgBaseDir\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", - "time": "2014-01-17 12:21:18" + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "time": "2014-10-24 07:27:01" }, { - "name": "filp/whoops", - "version": "1.1.2", + "name": "doctrine/inflector", + "version": "v1.0.1", "source": { "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "9f451fbc7b8cad5e71300672c340c28c6bec09ff" + "url": "https://github.com/doctrine/inflector.git", + "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/9f451fbc7b8cad5e71300672c340c28c6bec09ff", - "reference": "9f451fbc7b8cad5e71300672c340c28c6bec09ff", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604", + "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=5.3.2" }, "require-dev": { - "mockery/mockery": "0.9.*" + "phpunit/phpunit": "4.*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { "psr-0": { - "Whoops": "src/" - }, - "classmap": [ - "src/deprecated" - ] + "Doctrine\\Common\\Inflector\\": "lib/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -338,37 +317,48 @@ ], "authors": [ { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" + "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": "php error handling for cool kids", - "homepage": "https://github.com/filp/whoops", + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", "keywords": [ - "error", - "exception", - "handling", - "library", - "silex-provider", - "whoops", - "zf2" - ], - "time": "2014-07-11 05:56:54" + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2014-12-20 21:24:13" }, { "name": "firebase/php-jwt", "version": "dev-master", - "target-dir": "Firebase/PHP-JWT", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "fa7e362eeeec5ee808124626c3f1a612aadbce52" + "reference": "652f3c62094b2447a0c4cad6b11541bef19ebfaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/fa7e362eeeec5ee808124626c3f1a612aadbce52", - "reference": "fa7e362eeeec5ee808124626c3f1a612aadbce52", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/652f3c62094b2447a0c4cad6b11541bef19ebfaa", + "reference": "652f3c62094b2447a0c4cad6b11541bef19ebfaa", "shasum": "" }, "require": { @@ -377,7 +367,8 @@ "type": "library", "autoload": { "classmap": [ - "Authentication/" + "Authentication/", + "Exceptions/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -398,22 +389,25 @@ ], "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", "homepage": "https://github.com/firebase/php-jwt", - "time": "2014-06-25 21:20:33" + "time": "2015-04-13 18:10:21" }, { "name": "ircmaxell/password-compat", - "version": "1.0.x-dev", + "version": "v1.0.4", "source": { "type": "git", "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "1fc1521b5e9794ea77e4eca30717be9635f1d4f4" + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/1fc1521b5e9794ea77e4eca30717be9635f1d4f4", - "reference": "1fc1521b5e9794ea77e4eca30717be9635f1d4f4", + "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", "shasum": "" }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, "type": "library", "autoload": { "files": [ @@ -427,7 +421,7 @@ "authors": [ { "name": "Anthony Ferrara", - "email": "ircmaxell@ircmaxell.com", + "email": "ircmaxell@php.net", "homepage": "http://blog.ircmaxell.com" } ], @@ -437,33 +431,125 @@ "hashing", "password" ], - "time": "2013-04-30 19:58:08" + "time": "2014-11-20 16:49:30" + }, + { + "name": "jakub-onderka/php-console-color", + "version": "0.1", + "source": { + "type": "git", + "url": "https://github.com/JakubOnderka/PHP-Console-Color.git", + "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1", + "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "jakub-onderka/php-code-style": "1.0", + "jakub-onderka/php-parallel-lint": "0.*", + "jakub-onderka/php-var-dump-check": "0.*", + "phpunit/phpunit": "3.7.*", + "squizlabs/php_codesniffer": "1.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "JakubOnderka\\PhpConsoleColor": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Jakub Onderka", + "email": "jakub.onderka@gmail.com", + "homepage": "http://www.acci.cz" + } + ], + "time": "2014-04-08 15:00:19" + }, + { + "name": "jakub-onderka/php-console-highlighter", + "version": "v0.3.1", + "source": { + "type": "git", + "url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git", + "reference": "05bce997da20acf873e6bf396276798f3cd2c76a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/05bce997da20acf873e6bf396276798f3cd2c76a", + "reference": "05bce997da20acf873e6bf396276798f3cd2c76a", + "shasum": "" + }, + "require": { + "jakub-onderka/php-console-color": "~0.1", + "php": ">=5.3.0" + }, + "require-dev": { + "jakub-onderka/php-code-style": "~1.0", + "jakub-onderka/php-parallel-lint": "~0.5", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JakubOnderka\\PhpConsoleHighlighter": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jakub Onderka", + "email": "acci@acci.cz", + "homepage": "http://www.acci.cz/" + } + ], + "time": "2014-07-14 20:59:35" }, { "name": "jeremeamia/SuperClosure", - "version": "1.0.1", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/jeremeamia/super_closure.git", - "reference": "d05400085f7d4ae6f20ba30d36550836c0d061e8" + "reference": "b712f39c671e5ead60c7ebfe662545456aade833" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/d05400085f7d4ae6f20ba30d36550836c0d061e8", - "reference": "d05400085f7d4ae6f20ba30d36550836c0d061e8", + "url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/b712f39c671e5ead60c7ebfe662545456aade833", + "reference": "b712f39c671e5ead60c7ebfe662545456aade833", "shasum": "" }, "require": { - "nikic/php-parser": "~0.9", - "php": ">=5.3.3" + "nikic/php-parser": "~1.0", + "php": ">=5.4" }, "require-dev": { - "phpunit/phpunit": "~3.7" + "codeclimate/php-test-reporter": "~0.1.2", + "phpunit/phpunit": "~4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, "autoload": { - "psr-0": { - "Jeremeamia\\SuperClosure": "src/" + "psr-4": { + "SuperClosure\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -472,68 +558,75 @@ ], "authors": [ { - "name": "Jeremy Lindblom" + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia", + "role": "Developer" } ], - "description": "Doing interesting things with closures like serialization.", + "description": "Serialize Closure objects, including their context and binding", "homepage": "https://github.com/jeremeamia/super_closure", "keywords": [ "closure", "function", + "lambda", "parser", "serializable", "serialize", "tokenizer" ], - "time": "2013-10-09 04:20:00" + "time": "2015-03-11 20:06:43" }, { "name": "laravel/framework", - "version": "4.2.x-dev", + "version": "v5.0.27", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "60ff646d50fef973c8f9a49f047334e551ca8a94" + "reference": "4d6330118a295086ce9ff8eed2200d5b67f17688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/60ff646d50fef973c8f9a49f047334e551ca8a94", - "reference": "60ff646d50fef973c8f9a49f047334e551ca8a94", + "url": "https://api.github.com/repos/laravel/framework/zipball/4d6330118a295086ce9ff8eed2200d5b67f17688", + "reference": "4d6330118a295086ce9ff8eed2200d5b67f17688", "shasum": "" }, "require": { - "classpreloader/classpreloader": "~1.0", - "d11wtq/boris": "~1.0", - "filp/whoops": "1.1.*", + "classpreloader/classpreloader": "~1.2", + "danielstjules/stringy": "~1.8", + "doctrine/inflector": "~1.0", + "ext-mbstring": "*", + "ext-mcrypt": "*", + "ext-openssl": "*", "ircmaxell/password-compat": "~1.0", - "jeremeamia/superclosure": "~1.0", - "monolog/monolog": "~1.6", + "jeremeamia/superclosure": "~2.0", + "league/flysystem": "~1.0", + "monolog/monolog": "~1.11", + "mtdowling/cron-expression": "~1.0", "nesbot/carbon": "~1.0", - "patchwork/utf8": "1.1.*", "php": ">=5.4.0", - "phpseclib/phpseclib": "0.3.*", - "predis/predis": "0.8.*", - "stack/builder": "~1.0", + "psy/psysh": "0.4.*", "swiftmailer/swiftmailer": "~5.1", - "symfony/browser-kit": "2.5.*", - "symfony/console": "2.5.*", - "symfony/css-selector": "2.5.*", - "symfony/debug": "2.5.*", - "symfony/dom-crawler": "2.5.*", - "symfony/finder": "2.5.*", - "symfony/http-foundation": "2.5.*", - "symfony/http-kernel": "2.5.*", - "symfony/process": "2.5.*", - "symfony/routing": "2.5.*", - "symfony/security-core": "2.5.*", - "symfony/translation": "2.5.*" + "symfony/console": "2.6.*", + "symfony/debug": "2.6.*", + "symfony/finder": "2.6.*", + "symfony/http-foundation": "2.6.*", + "symfony/http-kernel": "2.6.*", + "symfony/process": "2.6.*", + "symfony/routing": "2.6.*", + "symfony/security-core": "2.6.*", + "symfony/translation": "2.6.*", + "symfony/var-dumper": "2.6.*", + "vlucas/phpdotenv": "~1.0" }, "replace": { "illuminate/auth": "self.version", + "illuminate/bus": "self.version", "illuminate/cache": "self.version", "illuminate/config": "self.version", "illuminate/console": "self.version", "illuminate/container": "self.version", + "illuminate/contracts": "self.version", "illuminate/cookie": "self.version", "illuminate/database": "self.version", "illuminate/encryption": "self.version", @@ -542,36 +635,42 @@ "illuminate/filesystem": "self.version", "illuminate/foundation": "self.version", "illuminate/hashing": "self.version", - "illuminate/html": "self.version", "illuminate/http": "self.version", "illuminate/log": "self.version", "illuminate/mail": "self.version", "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", "illuminate/queue": "self.version", "illuminate/redis": "self.version", - "illuminate/remote": "self.version", "illuminate/routing": "self.version", "illuminate/session": "self.version", "illuminate/support": "self.version", "illuminate/translation": "self.version", "illuminate/validation": "self.version", - "illuminate/view": "self.version", - "illuminate/workbench": "self.version" + "illuminate/view": "self.version" }, "require-dev": { - "aws/aws-sdk-php": "~2.6", + "aws/aws-sdk-php": "~2.4", "iron-io/iron_mq": "~1.5", "mockery/mockery": "~0.9", - "pda/pheanstalk": "~2.1", - "phpunit/phpunit": "~4.0" + "pda/pheanstalk": "~3.0", + "phpunit/phpunit": "~4.0", + "predis/predis": "~1.0" }, "suggest": { - "doctrine/dbal": "Allow renaming columns and dropping SQLite columns." + "aws/aws-sdk-php": "Required to use the SQS queue driver (~2.4).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).", + "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers (~5.0).", + "iron-io/iron_mq": "Required to use the iron queue driver (~1.5).", + "league/flysystem-aws-s3-v2": "Required to use the Flysystem S3 driver (~1.0).", + "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).", + "predis/predis": "Required to use the redis cache and queue drivers (~1.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -579,10 +678,11 @@ "src/Illuminate/Queue/IlluminateQueueClosure.php" ], "files": [ + "src/Illuminate/Foundation/helpers.php", "src/Illuminate/Support/helpers.php" ], - "psr-0": { - "Illuminate": "src/" + "psr-4": { + "Illuminate\\": "src/Illuminate/" } }, "notification-url": "https://packagist.org/downloads/", @@ -596,24 +696,108 @@ } ], "description": "The Laravel Framework.", + "homepage": "http://laravel.com", "keywords": [ "framework", "laravel" ], - "time": "2014-08-04 01:09:30" + "time": "2015-04-04 01:34:57" + }, + { + "name": "league/flysystem", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "3c2400a99ccc3be6884d40361890010449c6b447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3c2400a99ccc3be6884d40361890010449c6b447", + "reference": "3c2400a99ccc3be6884d40361890010449c6b447", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "ext-fileinfo": "*", + "league/phpunit-coverage-listener": "~1.1", + "mockery/mockery": "~0.9", + "phpspec/phpspec": "~2.0", + "phpspec/prophecy-phpunit": "~1.0", + "phpunit/phpunit": "~4.1", + "predis/predis": "~1.0", + "tedivm/stash": "~0.12.0" + }, + "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", + "predis/predis": "Allows you to use Predis for caching" + }, + "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": "Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ], + "time": "2015-03-29 14:01:43" }, { "name": "monolog/monolog", - "version": "dev-master", + "version": "1.13.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "12545cda2f7a0bd82a110f742ef455fe735e60cf" + "reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/12545cda2f7a0bd82a110f742ef455fe735e60cf", - "reference": "12545cda2f7a0bd82a110f742ef455fe735e60cf", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c31a2c4e8db5da8b46c74cf275d7f109c0f249ac", + "reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac", "shasum": "" }, "require": { @@ -627,9 +811,10 @@ "aws/aws-sdk-php": "~2.4, >2.4.8", "doctrine/couchdb": "~1.0@dev", "graylog2/gelf-php": "~1.0", - "phpunit/phpunit": "~3.7.0", + "phpunit/phpunit": "~4.0", "raven/raven": "~0.5", "ruflin/elastica": "0.90.*", + "swiftmailer/swiftmailer": "~5.3", "videlalvaro/php-amqplib": "~2.4" }, "suggest": { @@ -646,7 +831,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-master": "1.13.x-dev" } }, "autoload": { @@ -672,24 +857,69 @@ "logging", "psr-3" ], - "time": "2014-07-31 22:12:22" + "time": "2015-03-09 09:58:04" + }, + { + "name": "mtdowling/cron-expression", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/mtdowling/cron-expression.git", + "reference": "fd92e883195e5dfa77720b1868cf084b08be4412" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/fd92e883195e5dfa77720b1868cf084b08be4412", + "reference": "fd92e883195e5dfa77720b1868cf084b08be4412", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Cron": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "time": "2015-01-11 23:07:46" }, { "name": "nesbot/carbon", - "version": "1.10.0", + "version": "1.18.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "9b42a1aec56011c2ac4d75c0ddad0794762344fc" + "reference": "99e2f69f7bdc2cc4334b2d00f1e0ba450623ea36" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/9b42a1aec56011c2ac4d75c0ddad0794762344fc", - "reference": "9b42a1aec56011c2ac4d75c0ddad0794762344fc", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/99e2f69f7bdc2cc4334b2d00f1e0ba450623ea36", + "reference": "99e2f69f7bdc2cc4334b2d00f1e0ba450623ea36", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=5.3.0", + "symfony/translation": "2.6.*" }, "require-dev": { "phpunit/phpunit": "~4.0" @@ -712,42 +942,42 @@ } ], "description": "A simple API extension for DateTime.", - "homepage": "https://github.com/briannesbitt/Carbon", + "homepage": "http://carbon.nesbot.com", "keywords": [ "date", "datetime", "time" ], - "time": "2014-07-18 03:44:47" + "time": "2015-03-26 03:05:57" }, { "name": "nikic/php-parser", - "version": "0.9.x-dev", + "version": "v1.2.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb" + "reference": "08f97eb4efa029e2fafb6d8c98b71731bf0cf621" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ef70767475434bdb3615b43c327e2cae17ef12eb", - "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/08f97eb4efa029e2fafb6d8c98b71731bf0cf621", + "reference": "08f97eb4efa029e2fafb6d8c98b71731bf0cf621", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.2" + "php": ">=5.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.9-dev" + "dev-master": "1.2-dev" } }, "autoload": { - "psr-0": { - "PHPParser": "lib/" - } + "files": [ + "lib/bootstrap.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -763,230 +993,207 @@ "parser", "php" ], - "time": "2014-07-23 18:24:17" + "time": "2015-04-03 14:33:59" }, { - "name": "patchwork/utf8", - "version": "v1.1.24", + "name": "psr/log", + "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/nicolas-grekas/Patchwork-UTF8.git", - "reference": "40f552c019956f446553b19f7de2da2f9c74d730" + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nicolas-grekas/Patchwork-UTF8/zipball/40f552c019956f446553b19f7de2da2f9c74d730", - "reference": "40f552c019956f446553b19f7de2da2f9c74d730", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", "shasum": "" }, - "require": { - "lib-pcre": ">=7.3", - "php": ">=5.3.0" - }, - "suggest": { - "ext-iconv": "Use iconv for best performance", - "ext-intl": "Use Intl for best performance", - "ext-mbstring": "Use Mbstring for best performance" - }, "type": "library", "autoload": { "psr-0": { - "Patchwork": "class/", - "Normalizer": "class/" + "Psr\\Log\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "(Apache-2.0 or GPL-2.0)" + "MIT" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com", - "role": "Developer" + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } ], - "description": "Extensive, portable and performant handling of UTF-8 and grapheme clusters for PHP", - "homepage": "https://github.com/nicolas-grekas/Patchwork-UTF8", + "description": "Common interface for logging libraries", "keywords": [ - "i18n", - "unicode", - "utf-8", - "utf8" + "log", + "psr", + "psr-3" ], - "time": "2014-06-17 08:23:06" + "time": "2012-12-21 11:40:51" }, { - "name": "phpseclib/phpseclib", - "version": "dev-master", + "name": "psy/psysh", + "version": "v0.4.4", "source": { "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "4d70e7eda14ee186eaf1634d993597c7758e4fc1" + "url": "https://github.com/bobthecow/psysh.git", + "reference": "489816db71649bd95b416e3ed9062d40528ab0ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4d70e7eda14ee186eaf1634d993597c7758e4fc1", - "reference": "4d70e7eda14ee186eaf1634d993597c7758e4fc1", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/489816db71649bd95b416e3ed9062d40528ab0ac", + "reference": "489816db71649bd95b416e3ed9062d40528ab0ac", "shasum": "" }, "require": { - "php": ">=5.0.0" + "dnoegel/php-xdg-base-dir": "0.1", + "jakub-onderka/php-console-highlighter": "0.3.*", + "nikic/php-parser": "~1.0", + "php": ">=5.3.0", + "symfony/console": "~2.3.10|~2.4.2|~2.5" }, "require-dev": { - "phing/phing": "2.7.*", - "phpunit/phpunit": "4.0.*", - "sami/sami": "1.*", - "squizlabs/php_codesniffer": "1.*" + "fabpot/php-cs-fixer": "~1.5", + "phpunit/phpunit": "~3.7|~4.0", + "squizlabs/php_codesniffer": "~2.0", + "symfony/finder": "~2.1|~3.0" }, "suggest": { - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.", - "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 4.3.3." + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." }, + "bin": [ + "bin/psysh" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "0.3-dev" + "dev-develop": "0.4.x-dev" } }, "autoload": { - "psr-0": { - "Crypt": "phpseclib/", - "File": "phpseclib/", - "Math": "phpseclib/", - "Net": "phpseclib/", - "System": "phpseclib/" - }, "files": [ - "phpseclib/Crypt/Random.php" - ] + "src/Psy/functions.php" + ], + "psr-0": { + "Psy\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "phpseclib/" - ], "license": [ "MIT" ], "authors": [ { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" - }, - { - "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" - }, - { - "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" } ], - "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", - "homepage": "http://phpseclib.sourceforge.net", + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", "keywords": [ - "BigInteger", - "aes", - "asn.1", - "asn1", - "blowfish", - "crypto", - "cryptography", - "encryption", - "rsa", - "security", - "sftp", - "signature", - "signing", - "ssh", - "twofish", - "x.509", - "x509" - ], - "time": "2014-08-04 11:13:37" + "REPL", + "console", + "interactive", + "shell" + ], + "time": "2015-03-26 18:43:54" }, { - "name": "predis/predis", - "version": "0.8.x-dev", + "name": "swiftmailer/swiftmailer", + "version": "v5.4.0", "source": { "type": "git", - "url": "https://github.com/nrk/predis.git", - "reference": "4123fcd85d61354c6c9900db76c9597dbd129bf6" + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "31454f258f10329ae7c48763eb898a75c39e0a9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nrk/predis/zipball/4123fcd85d61354c6c9900db76c9597dbd129bf6", - "reference": "4123fcd85d61354c6c9900db76c9597dbd129bf6", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/31454f258f10329ae7c48763eb898a75c39e0a9f", + "reference": "31454f258f10329ae7c48763eb898a75c39e0a9f", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "ext-curl": "Allows access to Webdis when paired with phpiredis", - "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" + "mockery/mockery": "~0.9.1" }, "type": "library", - "autoload": { - "psr-0": { - "Predis": "lib/" + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" } }, + "autoload": { + "files": [ + "lib/swift_required.php" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Daniele Alessandri", - "email": "suppakilla@gmail.com", - "homepage": "http://clorophilla.net" + "name": "Chris Corbyn" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "Flexible and feature-complete PHP client library for Redis", - "homepage": "http://github.com/nrk/predis", + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "http://swiftmailer.org", "keywords": [ - "nosql", - "predis", - "redis" + "mail", + "mailer" ], - "time": "2014-08-01 09:43:10" + "time": "2015-03-14 06:06:39" }, { - "name": "psr/log", - "version": "dev-master", + "name": "symfony/console", + "version": "v2.6.6", + "target-dir": "Symfony/Component/Console", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "a78d6504ff5d4367497785ab2ade91db3a9fbe11" + "url": "https://github.com/symfony/Console.git", + "reference": "5b91dc4ed5eb08553f57f6df04c4730a73992667" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/a78d6504ff5d4367497785ab2ade91db3a9fbe11", - "reference": "a78d6504ff5d4367497785ab2ade91db3a9fbe11", + "url": "https://api.github.com/repos/symfony/Console/zipball/5b91dc4ed5eb08553f57f6df04c4730a73992667", + "reference": "5b91dc4ed5eb08553f57f6df04c4730a73992667", "shasum": "" }, + "require": { + "php": ">=5.3.3" + }, + "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": "1.0.x-dev" + "dev-master": "2.6-dev" } }, "autoload": { "psr-0": { - "Psr\\Log\\": "" + "Symfony\\Component\\Console\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -995,49 +1202,59 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "Common interface for logging libraries", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2014-01-18 15:33:09" + "description": "Symfony Console Component", + "homepage": "http://symfony.com", + "time": "2015-03-30 15:54:10" }, { - "name": "stack/builder", - "version": "dev-master", + "name": "symfony/debug", + "version": "v2.6.6", + "target-dir": "Symfony/Component/Debug", "source": { "type": "git", - "url": "https://github.com/stackphp/builder.git", - "reference": "d760dccb15e8db668c52359f8eb0ce3ecd37ce82" + "url": "https://github.com/symfony/Debug.git", + "reference": "d49a46a20a8f0544aedac54466750ad787d3d3e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stackphp/builder/zipball/d760dccb15e8db668c52359f8eb0ce3ecd37ce82", - "reference": "d760dccb15e8db668c52359f8eb0ce3ecd37ce82", + "url": "https://api.github.com/repos/symfony/Debug/zipball/d49a46a20a8f0544aedac54466750ad787d3d3e3", + "reference": "d49a46a20a8f0544aedac54466750ad787d3d3e3", "shasum": "" }, "require": { - "php": ">=5.3.0", - "symfony/http-foundation": "~2.1", - "symfony/http-kernel": "~2.1" + "php": ">=5.3.3", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" }, "require-dev": { - "silex/silex": "~1.0" + "symfony/class-loader": "~2.2", + "symfony/http-foundation": "~2.1", + "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2", + "symfony/phpunit-bridge": "~2.7" + }, + "suggest": { + "symfony/http-foundation": "", + "symfony/http-kernel": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.6-dev" } }, "autoload": { "psr-0": { - "Stack": "src" + "Symfony\\Component\\Debug\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1046,47 +1263,58 @@ ], "authors": [ { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch", - "homepage": "http://wiedler.ch/igor/" + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "Builder for stack middlewares based on HttpKernelInterface.", - "keywords": [ - "stack" - ], - "time": "2014-05-19 00:39:19" + "description": "Symfony Debug Component", + "homepage": "http://symfony.com", + "time": "2015-03-22 16:55:57" }, { - "name": "swiftmailer/swiftmailer", - "version": "dev-master", + "name": "symfony/event-dispatcher", + "version": "v2.6.6", + "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", - "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "62478c4c4ed84939a5457b15f9b978b58d0db849" + "url": "https://github.com/symfony/EventDispatcher.git", + "reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/62478c4c4ed84939a5457b15f9b978b58d0db849", - "reference": "62478c4c4ed84939a5457b15f9b978b58d0db849", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/70f7c8478739ad21e3deef0d977b38c77f1fb284", + "reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284", "shasum": "" }, "require": { - "php": ">=5.2.4" + "php": ">=5.3.3" }, "require-dev": { - "mockery/mockery": "~0.9.1" + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5", + "symfony/dependency-injection": "~2.6", + "symfony/expression-language": "~2.6", + "symfony/phpunit-bridge": "~2.7", + "symfony/stopwatch": "~2.3" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.2-dev" + "dev-master": "2.6-dev" } }, "autoload": { - "files": [ - "lib/swift_required.php" - ] + "psr-0": { + "Symfony\\Component\\EventDispatcher\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1094,56 +1322,48 @@ ], "authors": [ { - "name": "Chris Corbyn" + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" } ], - "description": "Swiftmailer, free feature-rich PHP mailer", - "homepage": "http://swiftmailer.org", - "keywords": [ - "mail", - "mailer" - ], - "time": "2014-07-28 09:34:50" + "description": "Symfony EventDispatcher Component", + "homepage": "http://symfony.com", + "time": "2015-03-13 17:37:22" }, { - "name": "symfony/browser-kit", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/BrowserKit", + "name": "symfony/filesystem", + "version": "v2.6.6", + "target-dir": "Symfony/Component/Filesystem", "source": { "type": "git", - "url": "https://github.com/symfony/BrowserKit.git", - "reference": "854b02dc6dc8e5743ca8e4040235c40ec412c898" + "url": "https://github.com/symfony/Filesystem.git", + "reference": "4983964b3693e4f13449cb3800c64a9112c301b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/854b02dc6dc8e5743ca8e4040235c40ec412c898", - "reference": "854b02dc6dc8e5743ca8e4040235c40ec412c898", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/4983964b3693e4f13449cb3800c64a9112c301b4", + "reference": "4983964b3693e4f13449cb3800c64a9112c301b4", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/dom-crawler": "~2.0" + "php": ">=5.3.3" }, "require-dev": { - "symfony/css-selector": "~2.0", - "symfony/process": "~2.0" - }, - "suggest": { - "symfony/process": "" + "symfony/phpunit-bridge": "~2.7" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.6-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\BrowserKit\\": "" + "Symfony\\Component\\Filesystem\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1160,45 +1380,40 @@ "email": "fabien@symfony.com" } ], - "description": "Symfony BrowserKit Component", + "description": "Symfony Filesystem Component", "homepage": "http://symfony.com", - "time": "2014-07-28 13:20:46" + "time": "2015-03-22 16:55:57" }, { - "name": "symfony/console", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/Console", + "name": "symfony/finder", + "version": "v2.6.6", + "target-dir": "Symfony/Component/Finder", "source": { "type": "git", - "url": "https://github.com/symfony/Console.git", - "reference": "fae03eba0b01d2a45f35080de50096ebb1901475" + "url": "https://github.com/symfony/Finder.git", + "reference": "5dbe2e73a580618f5b4880fda93406eed25de251" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/fae03eba0b01d2a45f35080de50096ebb1901475", - "reference": "fae03eba0b01d2a45f35080de50096ebb1901475", + "url": "https://api.github.com/repos/symfony/Finder/zipball/5dbe2e73a580618f5b4880fda93406eed25de251", + "reference": "5dbe2e73a580618f5b4880fda93406eed25de251", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "" + "symfony/phpunit-bridge": "~2.7" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.6-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\Console\\": "" + "Symfony\\Component\\Finder\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1215,98 +1430,122 @@ "email": "fabien@symfony.com" } ], - "description": "Symfony Console Component", + "description": "Symfony Finder Component", "homepage": "http://symfony.com", - "time": "2014-07-29 11:56:02" + "time": "2015-03-30 15:54:10" }, { - "name": "symfony/css-selector", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/CssSelector", + "name": "symfony/http-foundation", + "version": "v2.6.6", + "target-dir": "Symfony/Component/HttpFoundation", "source": { "type": "git", - "url": "https://github.com/symfony/CssSelector.git", - "reference": "e24b8215bf39a6a2ce0c262bc5b000724077afa9" + "url": "https://github.com/symfony/HttpFoundation.git", + "reference": "8a6337233f08f7520de97f4ffd6f00e947d892f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/CssSelector/zipball/e24b8215bf39a6a2ce0c262bc5b000724077afa9", - "reference": "e24b8215bf39a6a2ce0c262bc5b000724077afa9", + "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/8a6337233f08f7520de97f4ffd6f00e947d892f9", + "reference": "8a6337233f08f7520de97f4ffd6f00e947d892f9", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/expression-language": "~2.4", + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.6-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\CssSelector\\": "" - } + "Symfony\\Component\\HttpFoundation\\": "" + }, + "classmap": [ + "Symfony/Component/HttpFoundation/Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, { "name": "Symfony Community", "homepage": "http://symfony.com/contributors" }, { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "Symfony CssSelector Component", + "description": "Symfony HttpFoundation Component", "homepage": "http://symfony.com", - "time": "2014-07-09 09:05:48" + "time": "2015-04-01 16:50:12" }, { - "name": "symfony/debug", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/Debug", + "name": "symfony/http-kernel", + "version": "v2.6.6", + "target-dir": "Symfony/Component/HttpKernel", "source": { "type": "git", - "url": "https://github.com/symfony/Debug.git", - "reference": "189da713c1f8bb03f9184eb87b43ecbc732284ac" + "url": "https://github.com/symfony/HttpKernel.git", + "reference": "3829cacfe21eaf3f73604a62d79183d1f6e792c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Debug/zipball/189da713c1f8bb03f9184eb87b43ecbc732284ac", - "reference": "189da713c1f8bb03f9184eb87b43ecbc732284ac", + "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/3829cacfe21eaf3f73604a62d79183d1f6e792c4", + "reference": "3829cacfe21eaf3f73604a62d79183d1f6e792c4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.3", + "psr/log": "~1.0", + "symfony/debug": "~2.6,>=2.6.2", + "symfony/event-dispatcher": "~2.5.9|~2.6,>=2.6.2", + "symfony/http-foundation": "~2.5,>=2.5.4" }, "require-dev": { - "symfony/http-foundation": "~2.1", - "symfony/http-kernel": "~2.1" + "symfony/browser-kit": "~2.3", + "symfony/class-loader": "~2.1", + "symfony/config": "~2.0,>=2.0.5", + "symfony/console": "~2.3", + "symfony/css-selector": "~2.0,>=2.0.5", + "symfony/dependency-injection": "~2.2", + "symfony/dom-crawler": "~2.0,>=2.0.5", + "symfony/expression-language": "~2.4", + "symfony/finder": "~2.0,>=2.0.5", + "symfony/phpunit-bridge": "~2.7", + "symfony/process": "~2.0,>=2.0.5", + "symfony/routing": "~2.2", + "symfony/stopwatch": "~2.3", + "symfony/templating": "~2.2", + "symfony/translation": "~2.0,>=2.0.5", + "symfony/var-dumper": "~2.6" }, "suggest": { - "symfony/http-foundation": "", - "symfony/http-kernel": "" + "symfony/browser-kit": "", + "symfony/class-loader": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/finder": "", + "symfony/var-dumper": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.6-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\Debug\\": "" + "Symfony\\Component\\HttpKernel\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1314,54 +1553,49 @@ "MIT" ], "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, { "name": "Symfony Community", "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "Symfony Debug Component", + "description": "Symfony HttpKernel Component", "homepage": "http://symfony.com", - "time": "2014-07-09 09:05:48" + "time": "2015-04-01 16:55:26" }, { - "name": "symfony/dom-crawler", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/DomCrawler", + "name": "symfony/process", + "version": "v2.6.6", + "target-dir": "Symfony/Component/Process", "source": { "type": "git", - "url": "https://github.com/symfony/DomCrawler.git", - "reference": "b3d748f9d7ae77890d935bb97445c666b83dd59e" + "url": "https://github.com/symfony/Process.git", + "reference": "a8bebaec1a9dc6cde53e0250e32917579b0be552" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/b3d748f9d7ae77890d935bb97445c666b83dd59e", - "reference": "b3d748f9d7ae77890d935bb97445c666b83dd59e", + "url": "https://api.github.com/repos/symfony/Process/zipball/a8bebaec1a9dc6cde53e0250e32917579b0be552", + "reference": "a8bebaec1a9dc6cde53e0250e32917579b0be552", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "symfony/css-selector": "~2.0" - }, - "suggest": { - "symfony/css-selector": "" + "symfony/phpunit-bridge": "~2.7" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.6-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\DomCrawler\\": "" + "Symfony\\Component\\Process\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1369,48 +1603,52 @@ "MIT" ], "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, { "name": "Symfony Community", "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "Symfony DomCrawler Component", + "description": "Symfony Process Component", "homepage": "http://symfony.com", - "time": "2014-07-09 09:05:48" + "time": "2015-03-30 15:54:10" }, { - "name": "symfony/event-dispatcher", - "version": "dev-master", - "target-dir": "Symfony/Component/EventDispatcher", + "name": "symfony/routing", + "version": "v2.6.6", + "target-dir": "Symfony/Component/Routing", "source": { "type": "git", - "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "68ab3c3f50eae2b152075da722204d4de67f596f" + "url": "https://github.com/symfony/Routing.git", + "reference": "4e173a645b63ff60a124f3741b4f15feebd908fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/68ab3c3f50eae2b152075da722204d4de67f596f", - "reference": "68ab3c3f50eae2b152075da722204d4de67f596f", + "url": "https://api.github.com/repos/symfony/Routing/zipball/4e173a645b63ff60a124f3741b4f15feebd908fa", + "reference": "4e173a645b63ff60a124f3741b4f15feebd908fa", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/common": "~2.2", "psr/log": "~1.0", - "symfony/config": "~2.0", - "symfony/dependency-injection": "~2.0", - "symfony/stopwatch": "~2.2" + "symfony/config": "~2.2", + "symfony/expression-language": "~2.4", + "symfony/http-foundation": "~2.3", + "symfony/phpunit-bridge": "~2.7", + "symfony/yaml": "~2.0,>=2.0.5" }, "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/expression-language": "For using expression matching", + "symfony/yaml": "For using the YAML loader" }, "type": "library", "extra": { @@ -1420,7 +1658,7 @@ }, "autoload": { "psr-0": { - "Symfony\\Component\\EventDispatcher\\": "" + "Symfony\\Component\\Routing\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1437,28 +1675,51 @@ "email": "fabien@symfony.com" } ], - "description": "Symfony EventDispatcher Component", + "description": "Symfony Routing Component", "homepage": "http://symfony.com", - "time": "2014-07-28 13:20:53" + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "time": "2015-03-30 15:54:10" }, { - "name": "symfony/filesystem", - "version": "dev-master", - "target-dir": "Symfony/Component/Filesystem", + "name": "symfony/security-core", + "version": "v2.6.6", + "target-dir": "Symfony/Component/Security/Core", "source": { "type": "git", - "url": "https://github.com/symfony/Filesystem.git", - "reference": "0eb05b75932460ef615b926caac9f6086cc022f5" + "url": "https://github.com/symfony/security-core.git", + "reference": "d25c17db741f58c0f615e52006a47f6fb23cd9b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/0eb05b75932460ef615b926caac9f6086cc022f5", - "reference": "0eb05b75932460ef615b926caac9f6086cc022f5", + "url": "https://api.github.com/repos/symfony/security-core/zipball/d25c17db741f58c0f615e52006a47f6fb23cd9b3", + "reference": "d25c17db741f58c0f615e52006a47f6fb23cd9b3", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "ircmaxell/password-compat": "1.0.*", + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/expression-language": "~2.6", + "symfony/http-foundation": "~2.4", + "symfony/phpunit-bridge": "~2.7", + "symfony/translation": "~2.0,>=2.0.5", + "symfony/validator": "~2.5,>=2.5.5" + }, + "suggest": { + "ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5", + "symfony/event-dispatcher": "", + "symfony/expression-language": "For using the expression voter", + "symfony/http-foundation": "", + "symfony/validator": "For using the user password constraint" + }, "type": "library", "extra": { "branch-alias": { @@ -1467,7 +1728,7 @@ }, "autoload": { "psr-0": { - "Symfony\\Component\\Filesystem\\": "" + "Symfony\\Component\\Security\\Core\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1475,48 +1736,58 @@ "MIT" ], "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, { "name": "Symfony Community", "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "Symfony Filesystem Component", + "description": "Symfony Security Component - Core Library", "homepage": "http://symfony.com", - "time": "2014-07-09 14:44:54" + "time": "2015-03-30 15:54:10" }, { - "name": "symfony/finder", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/Finder", + "name": "symfony/translation", + "version": "v2.6.6", + "target-dir": "Symfony/Component/Translation", "source": { "type": "git", - "url": "https://github.com/symfony/Finder.git", - "reference": "090fe4eaff414d8f2171c7a4748ea868d530775f" + "url": "https://github.com/symfony/Translation.git", + "reference": "bd939f05cdaca128f4ddbae1b447d6f0203b60af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/090fe4eaff414d8f2171c7a4748ea868d530775f", - "reference": "090fe4eaff414d8f2171c7a4748ea868d530775f", + "url": "https://api.github.com/repos/symfony/Translation/zipball/bd939f05cdaca128f4ddbae1b447d6f0203b60af", + "reference": "bd939f05cdaca128f4ddbae1b447d6f0203b60af", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.3,>=2.3.12", + "symfony/intl": "~2.3", + "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.5-dev" + "dev-master": "2.6-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\Finder\\": "" + "Symfony\\Component\\Translation\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1533,44 +1804,47 @@ "email": "fabien@symfony.com" } ], - "description": "Symfony Finder Component", + "description": "Symfony Translation Component", "homepage": "http://symfony.com", - "time": "2014-07-28 13:20:46" + "time": "2015-03-30 15:54:10" }, { - "name": "symfony/http-foundation", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/HttpFoundation", + "name": "symfony/var-dumper", + "version": "v2.6.6", + "target-dir": "Symfony/Component/VarDumper", "source": { "type": "git", - "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "28940dacd5fc9cb96ee4a77e08d8a228136e1a4f" + "url": "https://github.com/symfony/var-dumper.git", + "reference": "aafae00236e147568832de3c65ccb94cfc836278" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/28940dacd5fc9cb96ee4a77e08d8a228136e1a4f", - "reference": "28940dacd5fc9cb96ee4a77e08d8a228136e1a4f", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/aafae00236e147568832de3c65ccb94cfc836278", + "reference": "aafae00236e147568832de3c65ccb94cfc836278", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "symfony/expression-language": "~2.4" + "symfony/phpunit-bridge": "~2.7" + }, + "suggest": { + "ext-symfony_debug": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.6-dev" } }, "autoload": { + "files": [ + "Resources/functions/dump.php" + ], "psr-0": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "classmap": [ - "Symfony/Component/HttpFoundation/Resources/stubs" - ] + "Symfony\\Component\\VarDumper\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1582,112 +1856,104 @@ "homepage": "http://symfony.com/contributors" }, { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" } ], - "description": "Symfony HttpFoundation Component", + "description": "Symfony mechanism for exploring and dumping PHP variables", "homepage": "http://symfony.com", - "time": "2014-07-24 10:44:07" + "keywords": [ + "debug", + "dump" + ], + "time": "2015-03-31 08:12:29" }, { - "name": "symfony/http-kernel", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/HttpKernel", + "name": "vlucas/phpdotenv", + "version": "v1.1.0", "source": { "type": "git", - "url": "https://github.com/symfony/HttpKernel.git", - "reference": "b92a20b7610b7d5403210afdb2519ff51ece2002" + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "732d2adb7d916c9593b9d58c3b0d9ebefead07aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/b92a20b7610b7d5403210afdb2519ff51ece2002", - "reference": "b92a20b7610b7d5403210afdb2519ff51ece2002", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/732d2adb7d916c9593b9d58c3b0d9ebefead07aa", + "reference": "732d2adb7d916c9593b9d58c3b0d9ebefead07aa", "shasum": "" }, "require": { - "php": ">=5.3.3", - "psr/log": "~1.0", - "symfony/debug": "~2.5", - "symfony/event-dispatcher": "~2.5", - "symfony/http-foundation": "~2.4" + "php": ">=5.3.2" }, "require-dev": { - "symfony/browser-kit": "~2.2", - "symfony/class-loader": "~2.1", - "symfony/config": "~2.0", - "symfony/console": "~2.2", - "symfony/dependency-injection": "~2.0", - "symfony/finder": "~2.0", - "symfony/process": "~2.0", - "symfony/routing": "~2.2", - "symfony/stopwatch": "~2.2", - "symfony/templating": "~2.2" - }, - "suggest": { - "symfony/browser-kit": "", - "symfony/class-loader": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "", - "symfony/finder": "" + "phpunit/phpunit": "~4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "1.0-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\HttpKernel\\": "" + "Dotenv": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD" ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "http://www.vancelucas.com" } ], - "description": "Symfony HttpKernel Component", - "homepage": "http://symfony.com", - "time": "2014-07-15 20:52:32" - }, + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "homepage": "http://github.com/vlucas/phpdotenv", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "time": "2014-12-05 15:19:21" + } + ], + "packages-dev": [ { - "name": "symfony/process", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/Process", + "name": "doctrine/instantiator", + "version": "1.0.4", "source": { "type": "git", - "url": "https://github.com/symfony/Process.git", - "reference": "06f4930c8667f5f7a7065e1faba5d62e8124a224" + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/06f4930c8667f5f7a7065e1faba5d62e8124a224", - "reference": "06f4930c8667f5f7a7065e1faba5d62e8124a224", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", "shasum": "" }, "require": { - "php": ">=5.3.3" + "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.*@ALPHA" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\Process\\": "" + "Doctrine\\Instantiator\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1696,58 +1962,54 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" } ], - "description": "Symfony Process Component", - "homepage": "http://symfony.com", - "time": "2014-07-28 13:20:46" + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2014-10-13 12:58:55" }, { - "name": "symfony/routing", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/Routing", + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/symfony/Routing.git", - "reference": "1c285e6fffaa026c8073a387f403b1052d61ed95" + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/1c285e6fffaa026c8073a387f403b1052d61ed95", - "reference": "1c285e6fffaa026c8073a387f403b1052d61ed95", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "doctrine/annotations": "~1.0", - "psr/log": "~1.0", - "symfony/config": "~2.2", - "symfony/expression-language": "~2.4", - "symfony/yaml": "~2.0" + "phpunit/phpunit": "~4.0" }, "suggest": { - "doctrine/annotations": "For using the annotation loader", - "symfony/config": "For using the all-in-one router or any loader", - "symfony/expression-language": "For using expression matching", - "symfony/yaml": "For using the YAML loader" + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\Routing\\": "" + "phpDocumentor": [ + "src/" + ] } }, "notification-url": "https://packagist.org/downloads/", @@ -1756,66 +2018,94 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" } ], - "description": "Symfony Routing Component", - "homepage": "http://symfony.com", - "keywords": [ - "router", - "routing", - "uri", - "url" + "time": "2015-02-03 12:10:50" + }, + { + "name": "phpspec/php-diff", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/phpspec/php-diff.git", + "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/php-diff/zipball/30e103d19519fe678ae64a60d77884ef3d71b28a", + "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Diff": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Chris Boulton", + "homepage": "http://github.com/chrisboulton", + "role": "Original developer" + } ], - "time": "2014-07-28 13:20:46" + "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).", + "time": "2013-11-01 13:02:21" }, { - "name": "symfony/security-core", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/Security/Core", + "name": "phpspec/phpspec", + "version": "2.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/security-core.git", - "reference": "dfc7d40b0a4d2f5ccc743eba08f840743f4ea984" + "url": "https://github.com/phpspec/phpspec.git", + "reference": "9727d75919a00455433e867565bc022f0b985a39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/dfc7d40b0a4d2f5ccc743eba08f840743f4ea984", - "reference": "dfc7d40b0a4d2f5ccc743eba08f840743f4ea984", + "url": "https://api.github.com/repos/phpspec/phpspec/zipball/9727d75919a00455433e867565bc022f0b985a39", + "reference": "9727d75919a00455433e867565bc022f0b985a39", "shasum": "" }, "require": { - "php": ">=5.3.3" + "doctrine/instantiator": "^1.0.1", + "php": ">=5.3.3", + "phpspec/php-diff": "~1.0.0", + "phpspec/prophecy": "~1.4", + "sebastian/exporter": "~1.0", + "symfony/console": "~2.3", + "symfony/event-dispatcher": "~2.1", + "symfony/finder": "~2.1", + "symfony/process": "~2.1", + "symfony/yaml": "~2.1" }, "require-dev": { - "ircmaxell/password-compat": "1.0.*", - "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1", - "symfony/expression-language": "~2.4", - "symfony/http-foundation": "~2.4", - "symfony/validator": "~2.2" + "behat/behat": "^3.0.11", + "bossa/phpspec2-expect": "~1.0", + "phpunit/phpunit": "~4.4", + "symfony/filesystem": "~2.1", + "symfony/process": "~2.1" }, "suggest": { - "ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5", - "symfony/event-dispatcher": "", - "symfony/expression-language": "For using the expression voter", - "symfony/http-foundation": "", - "symfony/validator": "For using the user password constraint" + "phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters" }, + "bin": [ + "bin/phpspec" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.2.x-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\Security\\Core\\": "" + "PhpSpec": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1824,55 +2114,59 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" }, { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Marcello Duarte", + "homepage": "http://marcelloduarte.net/" } ], - "description": "Symfony Security Component - Core Library", - "homepage": "http://symfony.com", - "time": "2014-06-23 07:34:27" + "description": "Specification-oriented BDD framework for PHP 5.3+", + "homepage": "http://phpspec.net/", + "keywords": [ + "BDD", + "SpecBDD", + "TDD", + "spec", + "specification", + "testing", + "tests" + ], + "time": "2015-04-18 16:22:51" }, { - "name": "symfony/translation", - "version": "2.5.x-dev", - "target-dir": "Symfony/Component/Translation", + "name": "phpspec/prophecy", + "version": "1.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/Translation.git", - "reference": "ae573e45b099b1e2d332930ac626cd4270e09539" + "url": "https://github.com/phpspec/prophecy.git", + "reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/ae573e45b099b1e2d332930ac626cd4270e09539", - "reference": "ae573e45b099b1e2d332930ac626cd4270e09539", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5", + "reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5", "shasum": "" }, "require": { - "php": ">=5.3.3" + "doctrine/instantiator": "^1.0.2", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1" }, "require-dev": { - "symfony/config": "~2.0", - "symfony/yaml": "~2.2" - }, - "suggest": { - "symfony/config": "", - "symfony/yaml": "" + "phpspec/phpspec": "~2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "1.4.x-dev" } }, "autoload": { "psr-0": { - "Symfony\\Component\\Translation\\": "" + "Prophecy\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1881,73 +2175,831 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" }, { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" } ], - "description": "Symfony Translation Component", - "homepage": "http://symfony.com", - "time": "2014-07-28 13:20:46" + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2015-03-27 19:31:25" }, { - "name": "vlucas/phpdotenv", - "version": "dev-master", + "name": "phpunit/php-code-coverage", + "version": "2.0.16", "source": { "type": "git", - "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "a6d7d9778975100460a24395f8b5175024e14a54" + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a6d7d9778975100460a24395f8b5175024e14a54", - "reference": "a6d7d9778975100460a24395f8b5175024e14a54", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/934fd03eb6840508231a7f73eb8940cf32c3b66c", + "reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c", "shasum": "" }, "require": { - "php": ">=5.3.2" + "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.0", + "sebastian/version": "~1.0" }, "require-dev": { - "phpunit/phpunit": "*" + "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.0.x-dev" + } + }, "autoload": { - "psr-0": { - "Dotenv": "src/" + "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-04-11 04:35:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a923bb15680d0089e2316f7a4af8f437046e96bb", + "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb", + "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" + "BSD-3-Clause" ], "authors": [ { - "name": "Vance Lucas", - "email": "vance@vancelucas.com", - "homepage": "http://www.vancelucas.com", - "role": "Developer" + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" } ], - "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", - "homepage": "http://github.com/vlucas/phpdotenv", + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ - "dotenv", - "env", - "environment" + "filesystem", + "iterator" + ], + "time": "2015-04-02 05:19:05" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2014-01-30 17:20:04" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "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": "2013-08-02 07:42:54" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "eab81d02569310739373308137284e0158424330" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/eab81d02569310739373308137284e0158424330", + "reference": "eab81d02569310739373308137284e0158424330", + "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-04-08 04:46:07" + }, + { + "name": "phpunit/phpunit", + "version": "4.6.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "163232991e652e6efed2f8470326fffa61e848e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/163232991e652e6efed2f8470326fffa61e848e2", + "reference": "163232991e652e6efed2f8470326fffa61e848e2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "~1.3,>=1.3.1", + "phpunit/php-code-coverage": "~2.0,>=2.0.11", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.2", + "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.6.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-04-11 05:23:21" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "74ffb87f527f24616f72460e54b595f508dccb5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/74ffb87f527f24616f72460e54b595f508dccb5c", + "reference": "74ffb87f527f24616f72460e54b595f508dccb5c", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~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-04-02 05:36:41" + }, + { + "name": "sebastian/comparator", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", + "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.1.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" + } ], - "time": "2014-04-04 15:06:45" + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-01-29 16:28:08" + }, + { + "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.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e", + "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e", + "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-01-01 10:01:08" + }, + { + "name": "sebastian/exporter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "84839970d05254c73cde183a721c7af13aede943" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", + "reference": "84839970d05254c73cde183a721c7af13aede943", + "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-01-27 07:23:06" + }, + { + "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.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252", + "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-01-24 09:48:32" + }, + { + "name": "sebastian/version", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", + "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", + "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-02-24 06:35:25" + }, + { + "name": "symfony/yaml", + "version": "v2.6.6", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "174f009ed36379a801109955fc5a71a49fe62dd4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/174f009ed36379a801109955fc5a71a49fe62dd4", + "reference": "174f009ed36379a801109955fc5a71a49fe62dd4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2015-03-30 15:54:10" } ], - "packages-dev": [], "aliases": [], - "minimum-stability": "dev", + "minimum-stability": "stable", "stability-flags": { - "vlucas/phpdotenv": 20 + "adoy/oauth2": 20, + "firebase/php-jwt": 20, + "auth0/login": 20 }, "prefer-stable": false, + "prefer-lowest": false, "platform": [], "platform-dev": [] } diff --git a/examples/laravel-api/app/config/app.php b/examples/laravel-api/config/app.php similarity index 58% rename from examples/laravel-api/app/config/app.php rename to examples/laravel-api/config/app.php index 8b05e4b0..7d0c6775 100644 --- a/examples/laravel-api/app/config/app.php +++ b/examples/laravel-api/config/app.php @@ -1,6 +1,6 @@ false, + 'debug' => env('APP_DEBUG', false), /* |-------------------------------------------------------------------------- @@ -78,10 +78,25 @@ | */ - 'key' => '2EFkq8tGTqNX9uizkLr62BbjxcYEm5v4', + 'key' => env('APP_KEY', 'SomeRandomString'), 'cipher' => MCRYPT_RIJNDAEL_128, + /* + |-------------------------------------------------------------------------- + | Logging Configuration + |-------------------------------------------------------------------------- + | + | Here you may configure the log settings for your application. Out of + | the box, Laravel uses the Monolog PHP logging library. This gives + | you a variety of powerful log handlers / formatters to utilize. + | + | Available Settings: "single", "daily", "syslog", "errorlog" + | + */ + + 'log' => 'daily', + /* |-------------------------------------------------------------------------- | Autoloaded Service Providers @@ -93,50 +108,46 @@ | */ - 'providers' => array( - 'Barryvdh\Cors\CorsServiceProvider', - 'Auth0\Login\LoginServiceProvider', + 'providers' => [ + + /* + * Laravel Framework Service Providers... + */ 'Illuminate\Foundation\Providers\ArtisanServiceProvider', 'Illuminate\Auth\AuthServiceProvider', + 'Illuminate\Bus\BusServiceProvider', 'Illuminate\Cache\CacheServiceProvider', - 'Illuminate\Session\CommandsServiceProvider', 'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider', 'Illuminate\Routing\ControllerServiceProvider', 'Illuminate\Cookie\CookieServiceProvider', 'Illuminate\Database\DatabaseServiceProvider', 'Illuminate\Encryption\EncryptionServiceProvider', 'Illuminate\Filesystem\FilesystemServiceProvider', + 'Illuminate\Foundation\Providers\FoundationServiceProvider', 'Illuminate\Hashing\HashServiceProvider', - 'Illuminate\Html\HtmlServiceProvider', - 'Illuminate\Log\LogServiceProvider', 'Illuminate\Mail\MailServiceProvider', - 'Illuminate\Database\MigrationServiceProvider', 'Illuminate\Pagination\PaginationServiceProvider', + 'Illuminate\Pipeline\PipelineServiceProvider', 'Illuminate\Queue\QueueServiceProvider', 'Illuminate\Redis\RedisServiceProvider', - 'Illuminate\Remote\RemoteServiceProvider', - 'Illuminate\Auth\Reminders\ReminderServiceProvider', - 'Illuminate\Database\SeedServiceProvider', + 'Illuminate\Auth\Passwords\PasswordResetServiceProvider', 'Illuminate\Session\SessionServiceProvider', 'Illuminate\Translation\TranslationServiceProvider', 'Illuminate\Validation\ValidationServiceProvider', 'Illuminate\View\ViewServiceProvider', - 'Illuminate\Workbench\WorkbenchServiceProvider', - ), + /* + * Application Service Providers... + */ + 'App\Providers\AppServiceProvider', + 'App\Providers\BusServiceProvider', + 'App\Providers\ConfigServiceProvider', + 'App\Providers\EventServiceProvider', + 'App\Providers\RouteServiceProvider', - /* - |-------------------------------------------------------------------------- - | Service Provider Manifest - |-------------------------------------------------------------------------- - | - | The service provider manifest is used by Laravel to lazy load service - | providers which are not needed for each request, as well to keep a - | list of all of the services. Here, you may set its storage spot. - | - */ + 'Auth0\Login\LoginServiceProvider', - 'manifest' => storage_path().'/meta', + ], /* |-------------------------------------------------------------------------- @@ -149,47 +160,43 @@ | */ - 'aliases' => array( - 'Auth0' => 'Auth0\Login\Facade\Auth0', - 'App' => 'Illuminate\Support\Facades\App', - 'Artisan' => 'Illuminate\Support\Facades\Artisan', - 'Auth' => 'Illuminate\Support\Facades\Auth', - 'Blade' => 'Illuminate\Support\Facades\Blade', - 'Cache' => 'Illuminate\Support\Facades\Cache', - 'ClassLoader' => 'Illuminate\Support\ClassLoader', - 'Config' => 'Illuminate\Support\Facades\Config', - 'Controller' => 'Illuminate\Routing\Controller', - 'Cookie' => 'Illuminate\Support\Facades\Cookie', - 'Crypt' => 'Illuminate\Support\Facades\Crypt', - 'DB' => 'Illuminate\Support\Facades\DB', - 'Eloquent' => 'Illuminate\Database\Eloquent\Model', - 'Event' => 'Illuminate\Support\Facades\Event', - 'File' => 'Illuminate\Support\Facades\File', - 'Form' => 'Illuminate\Support\Facades\Form', - 'Hash' => 'Illuminate\Support\Facades\Hash', - 'HTML' => 'Illuminate\Support\Facades\HTML', - 'Input' => 'Illuminate\Support\Facades\Input', - 'Lang' => 'Illuminate\Support\Facades\Lang', - 'Log' => 'Illuminate\Support\Facades\Log', - 'Mail' => 'Illuminate\Support\Facades\Mail', - 'Paginator' => 'Illuminate\Support\Facades\Paginator', - 'Password' => 'Illuminate\Support\Facades\Password', - 'Queue' => 'Illuminate\Support\Facades\Queue', - 'Redirect' => 'Illuminate\Support\Facades\Redirect', - 'Redis' => 'Illuminate\Support\Facades\Redis', - 'Request' => 'Illuminate\Support\Facades\Request', - 'Response' => 'Illuminate\Support\Facades\Response', - 'Route' => 'Illuminate\Support\Facades\Route', - 'Schema' => 'Illuminate\Support\Facades\Schema', - 'Seeder' => 'Illuminate\Database\Seeder', - 'Session' => 'Illuminate\Support\Facades\Session', - 'SoftDeletingTrait' => 'Illuminate\Database\Eloquent\SoftDeletingTrait', - 'SSH' => 'Illuminate\Support\Facades\SSH', - 'Str' => 'Illuminate\Support\Str', - 'URL' => 'Illuminate\Support\Facades\URL', - 'Validator' => 'Illuminate\Support\Facades\Validator', - 'View' => 'Illuminate\Support\Facades\View', - - ), - -); + 'aliases' => [ + + 'App' => 'Illuminate\Support\Facades\App', + 'Artisan' => 'Illuminate\Support\Facades\Artisan', + 'Auth' => 'Illuminate\Support\Facades\Auth', + 'Blade' => 'Illuminate\Support\Facades\Blade', + 'Bus' => 'Illuminate\Support\Facades\Bus', + 'Cache' => 'Illuminate\Support\Facades\Cache', + 'Config' => 'Illuminate\Support\Facades\Config', + 'Cookie' => 'Illuminate\Support\Facades\Cookie', + 'Crypt' => 'Illuminate\Support\Facades\Crypt', + 'DB' => 'Illuminate\Support\Facades\DB', + 'Eloquent' => 'Illuminate\Database\Eloquent\Model', + 'Event' => 'Illuminate\Support\Facades\Event', + 'File' => 'Illuminate\Support\Facades\File', + 'Hash' => 'Illuminate\Support\Facades\Hash', + 'Input' => 'Illuminate\Support\Facades\Input', + 'Inspiring' => 'Illuminate\Foundation\Inspiring', + 'Lang' => 'Illuminate\Support\Facades\Lang', + 'Log' => 'Illuminate\Support\Facades\Log', + 'Mail' => 'Illuminate\Support\Facades\Mail', + 'Password' => 'Illuminate\Support\Facades\Password', + 'Queue' => 'Illuminate\Support\Facades\Queue', + 'Redirect' => 'Illuminate\Support\Facades\Redirect', + 'Redis' => 'Illuminate\Support\Facades\Redis', + 'Request' => 'Illuminate\Support\Facades\Request', + 'Response' => 'Illuminate\Support\Facades\Response', + 'Route' => 'Illuminate\Support\Facades\Route', + 'Schema' => 'Illuminate\Support\Facades\Schema', + 'Session' => 'Illuminate\Support\Facades\Session', + 'Storage' => 'Illuminate\Support\Facades\Storage', + 'URL' => 'Illuminate\Support\Facades\URL', + 'Validator' => 'Illuminate\Support\Facades\Validator', + 'View' => 'Illuminate\Support\Facades\View', + + 'Auth0' => 'Auth0\Login\Facade\Auth0' + + ], + +]; diff --git a/examples/laravel-api/app/config/auth.php b/examples/laravel-api/config/auth.php similarity index 77% rename from examples/laravel-api/app/config/auth.php rename to examples/laravel-api/config/auth.php index eacbbfae..4031b7e8 100644 --- a/examples/laravel-api/app/config/auth.php +++ b/examples/laravel-api/config/auth.php @@ -1,6 +1,6 @@ 'eloquent', + 'driver' => 'auth0', /* |-------------------------------------------------------------------------- @@ -28,7 +28,7 @@ | */ - 'model' => 'User', + 'model' => 'App\User', /* |-------------------------------------------------------------------------- @@ -45,27 +45,23 @@ /* |-------------------------------------------------------------------------- - | Password Reminder Settings + | Password Reset Settings |-------------------------------------------------------------------------- | - | Here you may set the settings for password reminders, including a view - | that should be used as your password reminder e-mail. You will also - | be able to set the name of the table that holds the reset tokens. + | Here you may set the options for resetting passwords including the view + | that is your password reset e-mail. You can also set the name of the + | table that maintains all of the reset tokens for your application. | - | The "expire" time is the number of minutes that the reminder should be + | The expire time is the number of minutes that the reset token should be | considered valid. This security feature keeps tokens short-lived so | they have less time to be guessed. You may change this as needed. | */ - 'reminder' => array( - - 'email' => 'emails.auth.reminder', - - 'table' => 'password_reminders', - + 'password' => [ + 'email' => 'emails.password', + 'table' => 'password_resets', 'expire' => 60, + ], - ), - -); +]; diff --git a/examples/laravel-api/config/cache.php b/examples/laravel-api/config/cache.php new file mode 100644 index 00000000..9ddd5f33 --- /dev/null +++ b/examples/laravel-api/config/cache.php @@ -0,0 +1,79 @@ + env('CACHE_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + */ + + 'stores' => [ + + 'apc' => [ + 'driver' => 'apc' + ], + + 'array' => [ + 'driver' => 'array' + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'cache', + 'connection' => null, + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path().'/framework/cache', + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'servers' => [ + [ + 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100 + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing a RAM based store such as APC or Memcached, there might + | be other applications utilizing the same cache. So, we'll specify a + | value to get prefixed to all our keys so we can avoid collisions. + | + */ + + 'prefix' => 'laravel', + +]; diff --git a/examples/laravel-api/config/compile.php b/examples/laravel-api/config/compile.php new file mode 100644 index 00000000..3a002fca --- /dev/null +++ b/examples/laravel-api/config/compile.php @@ -0,0 +1,41 @@ + [ + + realpath(__DIR__.'/../app/Providers/AppServiceProvider.php'), + realpath(__DIR__.'/../app/Providers/BusServiceProvider.php'), + realpath(__DIR__.'/../app/Providers/ConfigServiceProvider.php'), + realpath(__DIR__.'/../app/Providers/EventServiceProvider.php'), + realpath(__DIR__.'/../app/Providers/RouteServiceProvider.php'), + + ], + + /* + |-------------------------------------------------------------------------- + | Compiled File Providers + |-------------------------------------------------------------------------- + | + | Here you may list service providers which define a "compiles" function + | that returns additional files that should be compiled, providing an + | easy way to get common files from any packages you are utilizing. + | + */ + + 'providers' => [ + // + ], + +]; diff --git a/examples/laravel-api/app/config/database.php b/examples/laravel-api/config/database.php similarity index 77% rename from examples/laravel-api/app/config/database.php rename to examples/laravel-api/config/database.php index 3498fa81..54c6db0f 100644 --- a/examples/laravel-api/app/config/database.php +++ b/examples/laravel-api/config/database.php @@ -1,6 +1,6 @@ array( + 'connections' => [ - 'sqlite' => array( + 'sqlite' => [ 'driver' => 'sqlite', - 'database' => __DIR__.'/../database/production.sqlite', + 'database' => storage_path().'/database.sqlite', 'prefix' => '', - ), + ], - 'mysql' => array( + 'mysql' => [ 'driver' => 'mysql', - 'host' => 'localhost', - 'database' => 'forge', - 'username' => 'forge', - 'password' => '', + 'host' => env('DB_HOST', 'localhost'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', - ), + 'strict' => false, + ], - 'pgsql' => array( + 'pgsql' => [ 'driver' => 'pgsql', - 'host' => 'localhost', - 'database' => 'forge', - 'username' => 'forge', - 'password' => '', + 'host' => env('DB_HOST', 'localhost'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', 'schema' => 'public', - ), + ], - 'sqlsrv' => array( + 'sqlsrv' => [ 'driver' => 'sqlsrv', - 'host' => 'localhost', - 'database' => 'database', - 'username' => 'root', - 'password' => '', + 'host' => env('DB_HOST', 'localhost'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), 'prefix' => '', - ), + ], - ), + ], /* |-------------------------------------------------------------------------- @@ -109,16 +110,16 @@ | */ - 'redis' => array( + 'redis' => [ 'cluster' => false, - 'default' => array( + 'default' => [ 'host' => '127.0.0.1', 'port' => 6379, 'database' => 0, - ), + ], - ), + ], -); +]; diff --git a/examples/laravel-api/config/filesystems.php b/examples/laravel-api/config/filesystems.php new file mode 100644 index 00000000..0221fa70 --- /dev/null +++ b/examples/laravel-api/config/filesystems.php @@ -0,0 +1,71 @@ + 'local', + + /* + |-------------------------------------------------------------------------- + | Default Cloud Filesystem Disk + |-------------------------------------------------------------------------- + | + | Many applications store files both locally and in the cloud. For this + | reason, you may specify a default "cloud" driver here. This driver + | will be bound as the Cloud disk implementation in the container. + | + */ + + 'cloud' => 's3', + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Here you may configure as many filesystem "disks" as you wish, and you + | may even configure multiple disks of the same driver. Defaults have + | been setup for each driver as an example of the required options. + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path().'/app', + ], + + 's3' => [ + 'driver' => 's3', + 'key' => 'your-key', + 'secret' => 'your-secret', + 'region' => 'your-region', + 'bucket' => 'your-bucket', + ], + + 'rackspace' => [ + 'driver' => 'rackspace', + 'username' => 'your-username', + 'key' => 'your-key', + 'container' => 'your-container', + 'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/', + 'region' => 'IAD', + 'url_type' => 'publicURL' + ], + + ], + +]; diff --git a/examples/laravel-api/app/config/packages/auth0/login/config.php b/examples/laravel-api/config/laravel-auth0.php similarity index 100% rename from examples/laravel-api/app/config/packages/auth0/login/config.php rename to examples/laravel-api/config/laravel-auth0.php diff --git a/examples/laravel-api/app/config/mail.php b/examples/laravel-api/config/mail.php similarity index 93% rename from examples/laravel-api/app/config/mail.php rename to examples/laravel-api/config/mail.php index 76fd9e4f..fc459436 100644 --- a/examples/laravel-api/app/config/mail.php +++ b/examples/laravel-api/config/mail.php @@ -1,6 +1,6 @@ 'smtp', + 'driver' => env('MAIL_DRIVER', 'smtp'), /* |-------------------------------------------------------------------------- @@ -28,7 +28,7 @@ | */ - 'host' => 'smtp.mailgun.org', + 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), /* |-------------------------------------------------------------------------- @@ -41,7 +41,7 @@ | */ - 'port' => 587, + 'port' => env('MAIL_PORT', 587), /* |-------------------------------------------------------------------------- @@ -54,7 +54,7 @@ | */ - 'from' => array('address' => null, 'name' => null), + 'from' => ['address' => null, 'name' => null], /* |-------------------------------------------------------------------------- @@ -80,7 +80,7 @@ | */ - 'username' => null, + 'username' => env('MAIL_USERNAME'), /* |-------------------------------------------------------------------------- @@ -93,7 +93,7 @@ | */ - 'password' => null, + 'password' => env('MAIL_PASSWORD'), /* |-------------------------------------------------------------------------- @@ -121,4 +121,4 @@ 'pretend' => false, -); +]; diff --git a/examples/laravel-api/app/config/queue.php b/examples/laravel-api/config/queue.php old mode 100755 new mode 100644 similarity index 80% rename from examples/laravel-api/app/config/queue.php rename to examples/laravel-api/config/queue.php index 940a4cdf..9c39a136 --- a/examples/laravel-api/app/config/queue.php +++ b/examples/laravel-api/config/queue.php @@ -1,6 +1,6 @@ 'sync', + 'default' => env('QUEUE_DRIVER', 'sync'), /* |-------------------------------------------------------------------------- @@ -28,42 +29,50 @@ | */ - 'connections' => array( + 'connections' => [ - 'sync' => array( + 'sync' => [ 'driver' => 'sync', - ), + ], - 'beanstalkd' => array( + 'database' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'default', + 'expire' => 60, + ], + + 'beanstalkd' => [ 'driver' => 'beanstalkd', 'host' => 'localhost', 'queue' => 'default', 'ttr' => 60, - ), + ], - 'sqs' => array( + 'sqs' => [ 'driver' => 'sqs', 'key' => 'your-public-key', 'secret' => 'your-secret-key', 'queue' => 'your-queue-url', 'region' => 'us-east-1', - ), + ], - 'iron' => array( + 'iron' => [ 'driver' => 'iron', 'host' => 'mq-aws-us-east-1.iron.io', 'token' => 'your-token', 'project' => 'your-project-id', 'queue' => 'your-queue-name', 'encrypt' => true, - ), + ], - 'redis' => array( + 'redis' => [ 'driver' => 'redis', 'queue' => 'default', - ), + 'expire' => 60, + ], - ), + ], /* |-------------------------------------------------------------------------- @@ -76,10 +85,8 @@ | */ - 'failed' => array( - + 'failed' => [ 'database' => 'mysql', 'table' => 'failed_jobs', + ], - ), - -); +]; diff --git a/examples/laravel-api/app/config/services.php b/examples/laravel-api/config/services.php similarity index 74% rename from examples/laravel-api/app/config/services.php rename to examples/laravel-api/config/services.php index c8aba2a6..45139694 100644 --- a/examples/laravel-api/app/config/services.php +++ b/examples/laravel-api/config/services.php @@ -1,6 +1,6 @@ array( + 'mailgun' => [ 'domain' => '', 'secret' => '', - ), + ], - 'mandrill' => array( + 'mandrill' => [ 'secret' => '', - ), + ], - 'stripe' => array( - 'model' => 'User', + 'ses' => [ + 'key' => '', 'secret' => '', - ), + 'region' => 'us-east-1', + ], -); + 'stripe' => [ + 'model' => 'App\User', + 'key' => '', + 'secret' => '', + ], + +]; diff --git a/examples/laravel-api/app/config/session.php b/examples/laravel-api/config/session.php similarity index 88% rename from examples/laravel-api/app/config/session.php rename to examples/laravel-api/config/session.php index ae343029..47470fab 100644 --- a/examples/laravel-api/app/config/session.php +++ b/examples/laravel-api/config/session.php @@ -1,6 +1,6 @@ 'file', + 'driver' => env('SESSION_DRIVER', 'file'), /* |-------------------------------------------------------------------------- @@ -33,6 +33,19 @@ 'expire_on_close' => false, + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + /* |-------------------------------------------------------------------------- | Session File Location @@ -44,7 +57,7 @@ | */ - 'files' => storage_path().'/sessions', + 'files' => storage_path().'/framework/sessions', /* |-------------------------------------------------------------------------- @@ -83,7 +96,7 @@ | */ - 'lottery' => array(2, 100), + 'lottery' => [2, 100], /* |-------------------------------------------------------------------------- @@ -137,4 +150,4 @@ 'secure' => false, -); +]; diff --git a/examples/laravel-api/app/config/view.php b/examples/laravel-api/config/view.php similarity index 61% rename from examples/laravel-api/app/config/view.php rename to examples/laravel-api/config/view.php index 34b8f387..88fc534a 100644 --- a/examples/laravel-api/app/config/view.php +++ b/examples/laravel-api/config/view.php @@ -1,6 +1,6 @@ array(__DIR__.'/../views'), + 'paths' => [ + realpath(base_path('resources/views')) + ], /* |-------------------------------------------------------------------------- - | Pagination View + | Compiled View Path |-------------------------------------------------------------------------- | - | This view will be used to render the pagination link output, and can - | be easily customized here to show any view you like. A clean view - | compatible with Twitter's Bootstrap is given to you by default. + | This option determines where all the compiled Blade templates will be + | stored for your application. Typically, this is within the storage + | directory. However, as usual, you are free to change this value. | */ - 'pagination' => 'pagination::slider-3', + 'compiled' => realpath(storage_path().'/framework/views'), -); +]; diff --git a/examples/laravel-api/database/.gitignore b/examples/laravel-api/database/.gitignore new file mode 100644 index 00000000..9b1dffd9 --- /dev/null +++ b/examples/laravel-api/database/.gitignore @@ -0,0 +1 @@ +*.sqlite diff --git a/examples/laravel-api/app/config/packages/barryvdh/laravel-cors/.gitkeep b/examples/laravel-api/database/migrations/.gitkeep similarity index 100% rename from examples/laravel-api/app/config/packages/barryvdh/laravel-cors/.gitkeep rename to examples/laravel-api/database/migrations/.gitkeep diff --git a/examples/laravel-api/database/migrations/2014_10_12_000000_create_users_table.php b/examples/laravel-api/database/migrations/2014_10_12_000000_create_users_table.php new file mode 100644 index 00000000..36a1db9b --- /dev/null +++ b/examples/laravel-api/database/migrations/2014_10_12_000000_create_users_table.php @@ -0,0 +1,36 @@ +increments('id'); + $table->string('name'); + $table->string('email')->unique(); + $table->string('password', 60); + $table->rememberToken(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('users'); + } + +} diff --git a/examples/laravel-api/database/migrations/2014_10_12_100000_create_password_resets_table.php b/examples/laravel-api/database/migrations/2014_10_12_100000_create_password_resets_table.php new file mode 100644 index 00000000..679df38f --- /dev/null +++ b/examples/laravel-api/database/migrations/2014_10_12_100000_create_password_resets_table.php @@ -0,0 +1,33 @@ +string('email')->index(); + $table->string('token')->index(); + $table->timestamp('created_at'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('password_resets'); + } + +} diff --git a/examples/laravel-api/app/controllers/.gitkeep b/examples/laravel-api/database/seeds/.gitkeep similarity index 100% rename from examples/laravel-api/app/controllers/.gitkeep rename to examples/laravel-api/database/seeds/.gitkeep diff --git a/examples/laravel-api/app/database/seeds/DatabaseSeeder.php b/examples/laravel-api/database/seeds/DatabaseSeeder.php similarity index 65% rename from examples/laravel-api/app/database/seeds/DatabaseSeeder.php rename to examples/laravel-api/database/seeds/DatabaseSeeder.php index 19892520..b3c69b56 100644 --- a/examples/laravel-api/app/database/seeds/DatabaseSeeder.php +++ b/examples/laravel-api/database/seeds/DatabaseSeeder.php @@ -1,5 +1,8 @@ call('UserTableSeeder'); } diff --git a/examples/laravel-api/gulpfile.js b/examples/laravel-api/gulpfile.js new file mode 100644 index 00000000..7cf62673 --- /dev/null +++ b/examples/laravel-api/gulpfile.js @@ -0,0 +1,16 @@ +var elixir = require('laravel-elixir'); + +/* + |-------------------------------------------------------------------------- + | Elixir Asset Management + |-------------------------------------------------------------------------- + | + | Elixir provides a clean, fluent API for defining some basic Gulp tasks + | for your Laravel application. By default, we are compiling the Less + | file for our application, as well as publishing vendor resources. + | + */ + +elixir(function(mix) { + mix.less('app.less'); +}); diff --git a/examples/laravel-api/package.json b/examples/laravel-api/package.json new file mode 100644 index 00000000..5595f071 --- /dev/null +++ b/examples/laravel-api/package.json @@ -0,0 +1,7 @@ +{ + "private": true, + "devDependencies": { + "gulp": "^3.8.8", + "laravel-elixir": "*" + } +} diff --git a/examples/laravel-api/phpspec.yml b/examples/laravel-api/phpspec.yml new file mode 100644 index 00000000..eb57939e --- /dev/null +++ b/examples/laravel-api/phpspec.yml @@ -0,0 +1,5 @@ +suites: + main: + namespace: App + psr4_prefix: App + src_path: app \ No newline at end of file diff --git a/examples/laravel-api/phpunit.xml b/examples/laravel-api/phpunit.xml index c3304205..d66acd01 100644 --- a/examples/laravel-api/phpunit.xml +++ b/examples/laravel-api/phpunit.xml @@ -8,11 +8,16 @@ convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" - syntaxCheck="false" -> + syntaxCheck="false"> - ./app/tests/ + ./tests/ + + + + + + diff --git a/examples/laravel-api/public/app/home/auth0_logo_final_blue_RGB.png b/examples/laravel-api/public/app/home/auth0_logo_final_blue_RGB.png new file mode 100644 index 0000000000000000000000000000000000000000..8b49dc1fd3fc51f1625653e5c162bacfae3bdf44 GIT binary patch literal 17757 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 KT-G@yGywqZg%0fi literal 0 HcmV?d00001 diff --git a/examples/laravel-api/public/app/home/home.css b/examples/laravel-api/public/app/home/home.css new file mode 100644 index 00000000..b352e546 --- /dev/null +++ b/examples/laravel-api/public/app/home/home.css @@ -0,0 +1,92 @@ +body { + font-family: "proxima-nova", sans-serif; + text-align: center; + font-size: 300%; + font-weight: 100; +} +input[type=checkbox], +input[type=radio] { + position: absolute; + opacity: 0; +} +input[type=checkbox] + label, +input[type=radio] + label { + display: inline-block; +} +input[type=checkbox] + label:before, +input[type=radio] + label:before { + content: ""; + display: inline-block; + vertical-align: -0.2em; + width: 1em; + height: 1em; + border: 0.15em solid #0074d9; + border-radius: 0.2em; + margin-right: 0.3em; + background-color: white; +} +input[type=radio] + label:before { + border-radius: 50%; +} +input[type=radio]:checked + label:before, +input[type=checkbox]:checked + label:before { + background-color: #0074d9; + box-shadow: inset 0 0 0 0.15em white; +} +input[type=radio]:focus + label:before, +input[type=checkbox]:focus + label:before { + outline: 0; +} +.btn { + font-size: 140%; + text-transform: uppercase; + letter-spacing: 1px; + border: 0; + background-color: #16214D; + color: white; +} +.btn:hover { + background-color: #44C7F4; +} +.btn:focus { + outline: none !important; +} +.btn.btn-lg { + padding: 20px 30px; +} +.btn:disabled { + background-color: #333; + color: #666; +} +h1, +h2, +h3 { + font-weight: 100; +} +#logo img { + width: 300px; + margin-bottom: 60px; +} +.home-description { + font-weight: 100; + margin: 100px 0; +} +h2.ng-binding { + margin-top: 30px; + margin-bottom: 40px; + font-size: 200%; +} +label.ng-binding { + font-size: 100%; + font-weight: 300; +} +.btn-next { + margin-top: 30px; +} +.answer { + width: 70%; + margin: auto; + text-align: left; + padding-left: 10%; + margin-bottom: 20px; +} diff --git a/examples/laravel-api/public/app/home/home.html b/examples/laravel-api/public/app/home/home.html new file mode 100644 index 00000000..c63cc2bc --- /dev/null +++ b/examples/laravel-api/public/app/home/home.html @@ -0,0 +1,6 @@ +
+

+

Welcome {{auth.profile.nickname}}

+
+ +
diff --git a/examples/laravel-api/public/app/home/home.js b/examples/laravel-api/public/app/home/home.js new file mode 100644 index 00000000..cc478832 --- /dev/null +++ b/examples/laravel-api/public/app/home/home.js @@ -0,0 +1,27 @@ +angular.module( 'sample.home', [ +'auth0' +]) +.controller( 'HomeCtrl', function HomeController( $scope, auth, $http, $location, store ) { + + $scope.auth = auth; + + $scope.callApi = function() { + // Just call the API as you'd do using $http + $http({ + url: 'http://laravel-5-auth0-sample.app/api/ping', + method: 'GET' + }).then(function(response) { + alert(response.data.status); + }, function() { + alert("Ups!"); + }); + } + + $scope.logout = function() { + auth.signout(); + store.remove('profile'); + store.remove('token'); + $location.path('/login'); + } + +}); diff --git a/examples/laravel-api/public/app/login/login.css b/examples/laravel-api/public/app/login/login.css new file mode 100644 index 00000000..a3dcd3a3 --- /dev/null +++ b/examples/laravel-api/public/app/login/login.css @@ -0,0 +1,3 @@ +.login-page .login-box { + padding: 100px 0; +} diff --git a/examples/laravel-api/public/app/login/login.html b/examples/laravel-api/public/app/login/login.html new file mode 100644 index 00000000..46b5cf42 --- /dev/null +++ b/examples/laravel-api/public/app/login/login.html @@ -0,0 +1,8 @@ + diff --git a/examples/laravel-api/public/app/login/login.js b/examples/laravel-api/public/app/login/login.js new file mode 100644 index 00000000..c4233c29 --- /dev/null +++ b/examples/laravel-api/public/app/login/login.js @@ -0,0 +1,16 @@ +angular.module( 'sample.login', [ + 'auth0' +]) +.controller( 'LoginCtrl', function HomeController( $scope, auth, $location, store ) { + + $scope.login = function() { + auth.signin({}, function(profile, token) { + store.set('profile', profile); + store.set('token', token); + $location.path("/"); + }, function(error) { + console.log("There was an error logging in", error); + }); + } + +}); diff --git a/examples/laravel-api/app/database/migrations/.gitkeep b/examples/laravel-api/public/css/app.css similarity index 100% rename from examples/laravel-api/app/database/migrations/.gitkeep rename to examples/laravel-api/public/css/app.css diff --git a/examples/laravel-api/public/fonts/glyphicons-halflings-regular.eot b/examples/laravel-api/public/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000000000000000000000000000000000..b93a4953fff68df523aa7656497ee339d6026d64 GIT binary patch literal 20127 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/laravel-api/public/fonts/glyphicons-halflings-regular.ttf b/examples/laravel-api/public/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1413fc609ab6f21774de0cb7e01360095584f65b GIT binary patch literal 45404 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 G`u_lkUM?>H literal 0 HcmV?d00001 diff --git a/examples/laravel-api/public/fonts/glyphicons-halflings-regular.woff2 b/examples/laravel-api/public/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..64539b54c3751a6d9adb44c8e3a45ba5a73b77f0 GIT binary patch literal 18028 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 literal 0 HcmV?d00001 diff --git a/examples/laravel-api/public/index.php b/examples/laravel-api/public/index.php index 863f239e..37f19c23 100644 --- a/examples/laravel-api/public/index.php +++ b/examples/laravel-api/public/index.php @@ -11,46 +11,47 @@ | Register The Auto Loader |-------------------------------------------------------------------------- | -| Composer provides a convenient, automatically generated class loader -| for our application. We just need to utilize it! We'll require it -| into the script here so that we do not have to worry about the -| loading of any our classes "manually". Feels great to relax. +| Composer provides a convenient, automatically generated class loader for +| our application. We just need to utilize it! We'll simply require it +| into the script here so that we don't have to worry about manual +| loading any of our classes later on. It feels nice to relax. | */ require __DIR__.'/../bootstrap/autoload.php'; -// Read .env -try { - Dotenv::load(__DIR__.'/../'); -} catch(InvalidArgumentException $ex) { - // Ignore if no dotenv -} - /* |-------------------------------------------------------------------------- | Turn On The Lights |-------------------------------------------------------------------------- | -| We need to illuminate PHP development, so let's turn on the lights. +| We need to illuminate PHP development, so let us turn on the lights. | This bootstraps the framework and gets it ready for use, then it | will load up this application so that we can run it and send -| the responses back to the browser and delight these users. +| the responses back to the browser and delight our users. | */ -$app = require_once __DIR__.'/../bootstrap/start.php'; +$app = require_once __DIR__.'/../bootstrap/app.php'; /* |-------------------------------------------------------------------------- | Run The Application |-------------------------------------------------------------------------- | -| Once we have the application, we can simply call the run method, -| which will execute the request and send the response back to +| Once we have the application, we can handle the incoming request +| through the kernel, and send the associated response back to | the client's browser allowing them to enjoy the creative -| and wonderful application we have whipped up for them. +| and wonderful application we have prepared for them. | */ -$app->run(); +$kernel = $app->make('Illuminate\Contracts\Http\Kernel'); + +$response = $kernel->handle( + $request = Illuminate\Http\Request::capture() +); + +$response->send(); + +$kernel->terminate($request, $response); diff --git a/examples/laravel-api/public/js/app.js b/examples/laravel-api/public/js/app.js new file mode 100644 index 00000000..1d46aa09 --- /dev/null +++ b/examples/laravel-api/public/js/app.js @@ -0,0 +1,63 @@ +angular.module( 'sample', [ + 'auth0', + 'ngRoute', + 'sample.home', + 'sample.login', + 'angular-storage', + 'angular-jwt' +]) +.config( function myAppConfig ( $routeProvider, authProvider, $httpProvider, $locationProvider, + jwtInterceptorProvider) { + $routeProvider + .when( '/', { + controller: 'HomeCtrl', + templateUrl: '/app/home/home.html', + pageTitle: 'Homepage', + requiresLogin: true + }) + .when( '/login', { + controller: 'LoginCtrl', + templateUrl: '/app/login/login.html', + pageTitle: 'Login' + }); + + + authProvider.init({ + domain: AUTH0_DOMAIN, + clientID: AUTH0_CLIENT_ID, + loginUrl: '/login' + }); + + jwtInterceptorProvider.tokenGetter = function(store) { + return store.get('token'); + } + + // Add a simple interceptor that will fetch all requests and add the jwt token to its authorization header. + // NOTE: in case you are calling APIs which expect a token signed with a different secret, you might + // want to check the delegation-token example + $httpProvider.interceptors.push('jwtInterceptor'); +}).run(function($rootScope, auth, store, jwtHelper, $location) { + $rootScope.$on('$locationChangeStart', function() { + if (!auth.isAuthenticated) { + var token = store.get('token'); + if (token) { + if (!jwtHelper.isTokenExpired(token)) { + auth.authenticate(store.get('profile'), token); + } else { + $location.path('/login'); + } + } + } + + }); +}) +.controller( 'AppCtrl', function AppCtrl ( $scope, $location ) { + $scope.$on('$routeChangeSuccess', function(e, nextRoute){ + if ( nextRoute.$$route && angular.isDefined( nextRoute.$$route.pageTitle ) ) { + $scope.pageTitle = nextRoute.$$route.pageTitle + ' | Auth0 Sample' ; + } + }); +}) + +; + diff --git a/examples/laravel-api/public/js/auth0-variables.js b/examples/laravel-api/public/js/auth0-variables.js new file mode 100644 index 00000000..34d5f018 --- /dev/null +++ b/examples/laravel-api/public/js/auth0-variables.js @@ -0,0 +1,3 @@ +var AUTH0_CLIENT_ID='KNuydwEqwGsPNpxdAhACmOWDUmBEZsLn'; +var AUTH0_DOMAIN='wptest.auth0.com'; +var AUTH0_CALLBACK_URL=location.href; \ No newline at end of file diff --git a/examples/laravel-api/public/packages/.gitkeep b/examples/laravel-api/public/packages/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/laravel-api/readme.md b/examples/laravel-api/readme.md index fc071ba7..a4d8d553 100644 --- a/examples/laravel-api/readme.md +++ b/examples/laravel-api/readme.md @@ -1,26 +1,23 @@ -# Auth0 + Laravel PHP API Seed -This is the seed project you need to use if you're going to create a PHP API. You'll mostly use this API either for a SPA or a Mobile app. If you just want to create a Regular PHP Laravel WebApp, please check [this other seed project]() +## Laravel PHP Framework -This example is deployed at Heroku at http://auth0-laravelphp-api-sample.herokuapp.com/ping +[![Build Status](https://travis-ci.org/laravel/framework.svg)](https://travis-ci.org/laravel/framework) +[![Total Downloads](https://poser.pugx.org/laravel/framework/downloads.svg)](https://packagist.org/packages/laravel/framework) +[![Latest Stable Version](https://poser.pugx.org/laravel/framework/v/stable.svg)](https://packagist.org/packages/laravel/framework) +[![Latest Unstable Version](https://poser.pugx.org/laravel/framework/v/unstable.svg)](https://packagist.org/packages/laravel/framework) +[![License](https://poser.pugx.org/laravel/framework/license.svg)](https://packagist.org/packages/laravel/framework) -#Running the example -In order to run the example you need to have `composer` and `php` installed. +Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as authentication, routing, sessions, queueing, and caching. -You also need to set the ClientSecret and ClientId for your Auth0 app as enviroment variables with the following names respectively: `AUTH0_CLIENT_SECRET` and `AUTH0_CLIENT_ID`. +Laravel is accessible, yet powerful, providing powerful tools needed for large, robust applications. A superb inversion of control container, expressive migration system, and tightly integrated unit testing support give you the tools you need to build any application with which you are tasked. -For that, if you just create a file named `.env` in the directory and set the values like the following, the app will just work: +## Official Documentation -````bash -# .env file -AUTH0_CLIENT_SECRET=myCoolSecret -AUTH0_CLIENT_ID=myCoolClientId -```` +Documentation for the framework can be found on the [Laravel website](http://laravel.com/docs). -Once you've set those 2 enviroment variables, just run the following to get the app started: +## Contributing -````bash -composer install -php artisan serve --port=3001 -```` +Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](http://laravel.com/docs/contributions). -Now, try calling [http://localhost:3001/ping](http://localhost:3001/ping) +### License + +The Laravel framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) diff --git a/examples/laravel-api/resources/assets/less/app.less b/examples/laravel-api/resources/assets/less/app.less new file mode 100644 index 00000000..99be0764 --- /dev/null +++ b/examples/laravel-api/resources/assets/less/app.less @@ -0,0 +1,8 @@ +@import "bootstrap/bootstrap"; + +@btn-font-weight: 300; +@font-family-sans-serif: "Roboto", Helvetica, Arial, sans-serif; + +body, label, .checkbox label { + font-weight: 300; +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/alerts.less b/examples/laravel-api/resources/assets/less/bootstrap/alerts.less new file mode 100644 index 00000000..df070b8a --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/alerts.less @@ -0,0 +1,68 @@ +// +// Alerts +// -------------------------------------------------- + + +// Base styles +// ------------------------- + +.alert { + padding: @alert-padding; + margin-bottom: @line-height-computed; + border: 1px solid transparent; + border-radius: @alert-border-radius; + + // Headings for larger alerts + h4 { + margin-top: 0; + // Specified for the h4 to prevent conflicts of changing @headings-color + color: inherit; + } + // Provide class for links that match alerts + .alert-link { + font-weight: @alert-link-font-weight; + } + + // Improve alignment and spacing of inner content + > p, + > ul { + margin-bottom: 0; + } + > p + p { + margin-top: 5px; + } +} + +// Dismissible alerts +// +// Expand the right padding and account for the close button's positioning. + +.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. +.alert-dismissible { + padding-right: (@alert-padding + 20); + + // Adjust close link position + .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; + } +} + +// Alternate styles +// +// Generate contextual modifier classes for colorizing the alert. + +.alert-success { + .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text); +} +.alert-info { + .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text); +} +.alert-warning { + .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text); +} +.alert-danger { + .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text); +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/badges.less b/examples/laravel-api/resources/assets/less/bootstrap/badges.less new file mode 100644 index 00000000..b27c405a --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/badges.less @@ -0,0 +1,61 @@ +// +// Badges +// -------------------------------------------------- + + +// Base class +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: @font-size-small; + font-weight: @badge-font-weight; + color: @badge-color; + line-height: @badge-line-height; + vertical-align: baseline; + white-space: nowrap; + text-align: center; + background-color: @badge-bg; + border-radius: @badge-border-radius; + + // Empty badges collapse automatically (not available in IE8) + &:empty { + display: none; + } + + // Quick fix for badges in buttons + .btn & { + position: relative; + top: -1px; + } + .btn-xs & { + top: 0; + padding: 1px 5px; + } + + // Hover state, but only for links + a& { + &:hover, + &:focus { + color: @badge-link-hover-color; + text-decoration: none; + cursor: pointer; + } + } + + // Account for badges in navs + .list-group-item.active > &, + .nav-pills > .active > a > & { + color: @badge-active-color; + background-color: @badge-active-bg; + } + .list-group-item > & { + float: right; + } + .list-group-item > & + & { + margin-right: 5px; + } + .nav-pills > li > a > & { + margin-left: 3px; + } +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/bootstrap.less b/examples/laravel-api/resources/assets/less/bootstrap/bootstrap.less new file mode 100644 index 00000000..61b77474 --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/bootstrap.less @@ -0,0 +1,50 @@ +// Core variables and mixins +@import "variables.less"; +@import "mixins.less"; + +// Reset and dependencies +@import "normalize.less"; +@import "print.less"; +@import "glyphicons.less"; + +// Core CSS +@import "scaffolding.less"; +@import "type.less"; +@import "code.less"; +@import "grid.less"; +@import "tables.less"; +@import "forms.less"; +@import "buttons.less"; + +// Components +@import "component-animations.less"; +@import "dropdowns.less"; +@import "button-groups.less"; +@import "input-groups.less"; +@import "navs.less"; +@import "navbar.less"; +@import "breadcrumbs.less"; +@import "pagination.less"; +@import "pager.less"; +@import "labels.less"; +@import "badges.less"; +@import "jumbotron.less"; +@import "thumbnails.less"; +@import "alerts.less"; +@import "progress-bars.less"; +@import "media.less"; +@import "list-group.less"; +@import "panels.less"; +@import "responsive-embed.less"; +@import "wells.less"; +@import "close.less"; + +// Components w/ JavaScript +@import "modals.less"; +@import "tooltip.less"; +@import "popovers.less"; +@import "carousel.less"; + +// Utility classes +@import "utilities.less"; +@import "responsive-utilities.less"; diff --git a/examples/laravel-api/resources/assets/less/bootstrap/breadcrumbs.less b/examples/laravel-api/resources/assets/less/bootstrap/breadcrumbs.less new file mode 100644 index 00000000..cb01d503 --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/breadcrumbs.less @@ -0,0 +1,26 @@ +// +// Breadcrumbs +// -------------------------------------------------- + + +.breadcrumb { + padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal; + margin-bottom: @line-height-computed; + list-style: none; + background-color: @breadcrumb-bg; + border-radius: @border-radius-base; + + > li { + display: inline-block; + + + li:before { + content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space + padding: 0 5px; + color: @breadcrumb-color; + } + } + + > .active { + color: @breadcrumb-active-color; + } +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/button-groups.less b/examples/laravel-api/resources/assets/less/bootstrap/button-groups.less new file mode 100644 index 00000000..f84febbd --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/button-groups.less @@ -0,0 +1,243 @@ +// +// Button groups +// -------------------------------------------------- + +// Make the div behave like a button +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; // match .btn alignment given font-size hack above + > .btn { + position: relative; + float: left; + // Bring the "active" button to the front + &:hover, + &:focus, + &:active, + &.active { + z-index: 2; + } + } +} + +// Prevent double borders when buttons are next to each other +.btn-group { + .btn + .btn, + .btn + .btn-group, + .btn-group + .btn, + .btn-group + .btn-group { + margin-left: -1px; + } +} + +// Optional: Group multiple button groups together for a toolbar +.btn-toolbar { + margin-left: -5px; // Offset the first child's margin + &:extend(.clearfix all); + + .btn-group, + .input-group { + float: left; + } + > .btn, + > .btn-group, + > .input-group { + margin-left: 5px; + } +} + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} + +// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match +.btn-group > .btn:first-child { + margin-left: 0; + &:not(:last-child):not(.dropdown-toggle) { + .border-right-radius(0); + } +} +// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + .border-left-radius(0); +} + +// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child { + > .btn:last-child, + > .dropdown-toggle { + .border-right-radius(0); + } +} +.btn-group > .btn-group:last-child > .btn:first-child { + .border-left-radius(0); +} + +// On active and open, don't show outline +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + + +// Sizing +// +// Remix the default button sizing classes into new ones for easier manipulation. + +.btn-group-xs > .btn { &:extend(.btn-xs); } +.btn-group-sm > .btn { &:extend(.btn-sm); } +.btn-group-lg > .btn { &:extend(.btn-lg); } + + +// Split button dropdowns +// ---------------------- + +// Give the line between buttons some depth +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} + +// The clickable button for toggling the menu +// Remove the gradient and set the same inset shadow as the :active state +.btn-group.open .dropdown-toggle { + .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); + + // Show no shadow for `.btn-link` since it has no other button styles. + &.btn-link { + .box-shadow(none); + } +} + + +// Reposition the caret +.btn .caret { + margin-left: 0; +} +// Carets in other button sizes +.btn-lg .caret { + border-width: @caret-width-large @caret-width-large 0; + border-bottom-width: 0; +} +// Upside down carets for .dropup +.dropup .btn-lg .caret { + border-width: 0 @caret-width-large @caret-width-large; +} + + +// Vertical button groups +// ---------------------- + +.btn-group-vertical { + > .btn, + > .btn-group, + > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; + } + + // Clear floats so dropdown menus can be properly placed + > .btn-group { + &:extend(.clearfix all); + > .btn { + float: none; + } + } + + > .btn + .btn, + > .btn + .btn-group, + > .btn-group + .btn, + > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; + } +} + +.btn-group-vertical > .btn { + &:not(:first-child):not(:last-child) { + border-radius: 0; + } + &:first-child:not(:last-child) { + border-top-right-radius: @border-radius-base; + .border-bottom-radius(0); + } + &:last-child:not(:first-child) { + border-bottom-left-radius: @border-radius-base; + .border-top-radius(0); + } +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + .border-bottom-radius(0); + } +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + .border-top-radius(0); +} + + +// Justified button groups +// ---------------------- + +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; + > .btn, + > .btn-group { + float: none; + display: table-cell; + width: 1%; + } + > .btn-group .btn { + width: 100%; + } + + > .btn-group .dropdown-menu { + left: auto; + } +} + + +// Checkbox and radio options +// +// In order to support the browser's form validation feedback, powered by the +// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use +// `display: none;` or `visibility: hidden;` as that also hides the popover. +// Simply visually hiding the inputs via `opacity` would leave them clickable in +// certain cases which is prevented by using `clip` and `pointer-events`. +// This way, we ensure a DOM element is visible to position the popover from. +// +// See https://github.com/twbs/bootstrap/pull/12794 and +// https://github.com/twbs/bootstrap/pull/14559 for more information. + +[data-toggle="buttons"] { + > .btn, + > .btn-group > .btn { + input[type="radio"], + input[type="checkbox"] { + position: absolute; + clip: rect(0,0,0,0); + pointer-events: none; + } + } +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/buttons.less b/examples/laravel-api/resources/assets/less/bootstrap/buttons.less new file mode 100644 index 00000000..40553c63 --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/buttons.less @@ -0,0 +1,160 @@ +// +// Buttons +// -------------------------------------------------- + + +// Base styles +// -------------------------------------------------- + +.btn { + display: inline-block; + margin-bottom: 0; // For input.btn + font-weight: @btn-font-weight; + text-align: center; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 + border: 1px solid transparent; + white-space: nowrap; + .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base); + .user-select(none); + + &, + &:active, + &.active { + &:focus, + &.focus { + .tab-focus(); + } + } + + &:hover, + &:focus, + &.focus { + color: @btn-default-color; + text-decoration: none; + } + + &:active, + &.active { + outline: 0; + background-image: none; + .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); + } + + &.disabled, + &[disabled], + fieldset[disabled] & { + cursor: @cursor-disabled; + pointer-events: none; // Future-proof disabling of clicks + .opacity(.65); + .box-shadow(none); + } +} + + +// Alternate buttons +// -------------------------------------------------- + +.btn-default { + .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border); +} +.btn-primary { + .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); +} +// Success appears as green +.btn-success { + .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border); +} +// Info appears as blue-green +.btn-info { + .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border); +} +// Warning appears as orange +.btn-warning { + .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border); +} +// Danger and error appear as red +.btn-danger { + .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border); +} + + +// Link buttons +// ------------------------- + +// Make a button look and behave like a link +.btn-link { + color: @link-color; + font-weight: normal; + border-radius: 0; + + &, + &:active, + &.active, + &[disabled], + fieldset[disabled] & { + background-color: transparent; + .box-shadow(none); + } + &, + &:hover, + &:focus, + &:active { + border-color: transparent; + } + &:hover, + &:focus { + color: @link-hover-color; + text-decoration: underline; + background-color: transparent; + } + &[disabled], + fieldset[disabled] & { + &:hover, + &:focus { + color: @btn-link-disabled-color; + text-decoration: none; + } + } +} + + +// Button Sizes +// -------------------------------------------------- + +.btn-lg { + // line-height: ensure even-numbered height of button next to large input + .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large); +} +.btn-sm { + // line-height: ensure proper height of button next to small input + .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small); +} +.btn-xs { + .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small); +} + + +// Block button +// -------------------------------------------------- + +.btn-block { + display: block; + width: 100%; +} + +// Vertically space out multiple block buttons +.btn-block + .btn-block { + margin-top: 5px; +} + +// Specificity overrides +input[type="submit"], +input[type="reset"], +input[type="button"] { + &.btn-block { + width: 100%; + } +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/carousel.less b/examples/laravel-api/resources/assets/less/bootstrap/carousel.less new file mode 100644 index 00000000..5724d8a5 --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/carousel.less @@ -0,0 +1,267 @@ +// +// Carousel +// -------------------------------------------------- + + +// Wrapper for the slide container and indicators +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; + + > .item { + display: none; + position: relative; + .transition(.6s ease-in-out left); + + // Account for jankitude on images + > img, + > a > img { + &:extend(.img-responsive); + line-height: 1; + } + + // WebKit CSS3 transforms for supported devices + @media all and (transform-3d), (-webkit-transform-3d) { + transition: transform .6s ease-in-out; + backface-visibility: hidden; + perspective: 1000; + + &.next, + &.active.right { + transform: translate3d(100%, 0, 0); + left: 0; + } + &.prev, + &.active.left { + transform: translate3d(-100%, 0, 0); + left: 0; + } + &.next.left, + &.prev.right, + &.active { + transform: translate3d(0, 0, 0); + left: 0; + } + } + } + + > .active, + > .next, + > .prev { + display: block; + } + + > .active { + left: 0; + } + + > .next, + > .prev { + position: absolute; + top: 0; + width: 100%; + } + + > .next { + left: 100%; + } + > .prev { + left: -100%; + } + > .next.left, + > .prev.right { + left: 0; + } + + > .active.left { + left: -100%; + } + > .active.right { + left: 100%; + } + +} + +// Left/right controls for nav +// --------------------------- + +.carousel-control { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: @carousel-control-width; + .opacity(@carousel-control-opacity); + font-size: @carousel-control-font-size; + color: @carousel-control-color; + text-align: center; + text-shadow: @carousel-text-shadow; + // We can't have this transition here because WebKit cancels the carousel + // animation if you trip this while in the middle of another animation. + + // Set gradients for backgrounds + &.left { + #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001)); + } + &.right { + left: auto; + right: 0; + #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5)); + } + + // Hover/focus state + &:hover, + &:focus { + outline: 0; + color: @carousel-control-color; + text-decoration: none; + .opacity(.9); + } + + // Toggles + .icon-prev, + .icon-next, + .glyphicon-chevron-left, + .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + } + .icon-prev, + .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; + } + .icon-next, + .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; + } + .icon-prev, + .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + font-family: serif; + } + + + .icon-prev { + &:before { + content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) + } + } + .icon-next { + &:before { + content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) + } + } +} + +// Optional indicator pips +// +// Add an unordered list with the following class and add a list item for each +// slide your carousel holds. + +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; + + li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid @carousel-indicator-border-color; + border-radius: 10px; + cursor: pointer; + + // IE8-9 hack for event handling + // + // Internet Explorer 8-9 does not support clicks on elements without a set + // `background-color`. We cannot use `filter` since that's not viewed as a + // background color by the browser. Thus, a hack is needed. + // + // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we + // set alpha transparency for the best results possible. + background-color: #000 \9; // IE8 + background-color: rgba(0,0,0,0); // IE9 + } + .active { + margin: 0; + width: 12px; + height: 12px; + background-color: @carousel-indicator-active-bg; + } +} + +// Optional captions +// ----------------------------- +// Hidden by default for smaller viewports +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: @carousel-caption-color; + text-align: center; + text-shadow: @carousel-text-shadow; + & .btn { + text-shadow: none; // No shadow for button elements in carousel-caption + } +} + + +// Scale up controls for tablets and up +@media screen and (min-width: @screen-sm-min) { + + // Scale up the controls a smidge + .carousel-control { + .glyphicon-chevron-left, + .glyphicon-chevron-right, + .icon-prev, + .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .glyphicon-chevron-left, + .icon-prev { + margin-left: -15px; + } + .glyphicon-chevron-right, + .icon-next { + margin-right: -15px; + } + } + + // Show and left align the captions + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + + // Move up the indicators + .carousel-indicators { + bottom: 20px; + } +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/close.less b/examples/laravel-api/resources/assets/less/bootstrap/close.less new file mode 100644 index 00000000..9b4e74f2 --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/close.less @@ -0,0 +1,33 @@ +// +// Close icons +// -------------------------------------------------- + + +.close { + float: right; + font-size: (@font-size-base * 1.5); + font-weight: @close-font-weight; + line-height: 1; + color: @close-color; + text-shadow: @close-text-shadow; + .opacity(.2); + + &:hover, + &:focus { + color: @close-color; + text-decoration: none; + cursor: pointer; + .opacity(.5); + } + + // Additional properties for button version + // iOS requires the button element instead of an anchor tag. + // If you want the anchor version, it requires `href="#"`. + button& { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; + } +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/code.less b/examples/laravel-api/resources/assets/less/bootstrap/code.less new file mode 100644 index 00000000..a08b4d48 --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/code.less @@ -0,0 +1,69 @@ +// +// Code (inline and block) +// -------------------------------------------------- + + +// Inline and block code styles +code, +kbd, +pre, +samp { + font-family: @font-family-monospace; +} + +// Inline code +code { + padding: 2px 4px; + font-size: 90%; + color: @code-color; + background-color: @code-bg; + border-radius: @border-radius-base; +} + +// User input typically entered via keyboard +kbd { + padding: 2px 4px; + font-size: 90%; + color: @kbd-color; + background-color: @kbd-bg; + border-radius: @border-radius-small; + box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); + + kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + box-shadow: none; + } +} + +// Blocks of code +pre { + display: block; + padding: ((@line-height-computed - 1) / 2); + margin: 0 0 (@line-height-computed / 2); + font-size: (@font-size-base - 1); // 14px to 13px + line-height: @line-height-base; + word-break: break-all; + word-wrap: break-word; + color: @pre-color; + background-color: @pre-bg; + border: 1px solid @pre-border-color; + border-radius: @border-radius-base; + + // Account for some code outputs that place code tags in pre tags + code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; + } +} + +// Enable scrollable blocks of code +.pre-scrollable { + max-height: @pre-scrollable-max-height; + overflow-y: scroll; +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/component-animations.less b/examples/laravel-api/resources/assets/less/bootstrap/component-animations.less new file mode 100644 index 00000000..967715d9 --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/component-animations.less @@ -0,0 +1,34 @@ +// +// Component animations +// -------------------------------------------------- + +// Heads up! +// +// We don't use the `.opacity()` mixin here since it causes a bug with text +// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. + +.fade { + opacity: 0; + .transition(opacity .15s linear); + &.in { + opacity: 1; + } +} + +.collapse { + display: none; + visibility: hidden; + + &.in { display: block; visibility: visible; } + tr&.in { display: table-row; } + tbody&.in { display: table-row-group; } +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + .transition-property(~"height, visibility"); + .transition-duration(.35s); + .transition-timing-function(ease); +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/dropdowns.less b/examples/laravel-api/resources/assets/less/bootstrap/dropdowns.less new file mode 100644 index 00000000..84a48c14 --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/dropdowns.less @@ -0,0 +1,213 @@ +// +// Dropdown menus +// -------------------------------------------------- + + +// Dropdown arrow/caret +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: @caret-width-base solid; + border-right: @caret-width-base solid transparent; + border-left: @caret-width-base solid transparent; +} + +// The dropdown wrapper (div) +.dropdown { + position: relative; +} + +// Prevent the focus on the dropdown toggle when closing dropdowns +.dropdown-toggle:focus { + outline: 0; +} + +// The dropdown menu (ul) +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: @zindex-dropdown; + display: none; // none by default, but block on "open" of the menu + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; // override default ul + list-style: none; + font-size: @font-size-base; + text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) + background-color: @dropdown-bg; + border: 1px solid @dropdown-fallback-border; // IE8 fallback + border: 1px solid @dropdown-border; + border-radius: @border-radius-base; + .box-shadow(0 6px 12px rgba(0,0,0,.175)); + background-clip: padding-box; + + // Aligns the dropdown menu to right + // + // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]` + &.pull-right { + right: 0; + left: auto; + } + + // Dividers (basically an hr) within the dropdown + .divider { + .nav-divider(@dropdown-divider-bg); + } + + // Links within the dropdown menu + > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: @line-height-base; + color: @dropdown-link-color; + white-space: nowrap; // prevent links from randomly breaking onto new lines + } +} + +// Hover/Focus state +.dropdown-menu > li > a { + &:hover, + &:focus { + text-decoration: none; + color: @dropdown-link-hover-color; + background-color: @dropdown-link-hover-bg; + } +} + +// Active state +.dropdown-menu > .active > a { + &, + &:hover, + &:focus { + color: @dropdown-link-active-color; + text-decoration: none; + outline: 0; + background-color: @dropdown-link-active-bg; + } +} + +// Disabled state +// +// Gray out text and ensure the hover/focus state remains gray + +.dropdown-menu > .disabled > a { + &, + &:hover, + &:focus { + color: @dropdown-link-disabled-color; + } + + // Nuke hover/focus effects + &:hover, + &:focus { + text-decoration: none; + background-color: transparent; + background-image: none; // Remove CSS gradient + .reset-filter(); + cursor: @cursor-disabled; + } +} + +// Open state for the dropdown +.open { + // Show the menu + > .dropdown-menu { + display: block; + } + + // Remove the outline when :focus is triggered + > a { + outline: 0; + } +} + +// Menu positioning +// +// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown +// menu with the parent. +.dropdown-menu-right { + left: auto; // Reset the default from `.dropdown-menu` + right: 0; +} +// With v3, we enabled auto-flipping if you have a dropdown within a right +// aligned nav component. To enable the undoing of that, we provide an override +// to restore the default dropdown menu alignment. +// +// This is only for left-aligning a dropdown menu within a `.navbar-right` or +// `.pull-right` nav component. +.dropdown-menu-left { + left: 0; + right: auto; +} + +// Dropdown section headers +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: @font-size-small; + line-height: @line-height-base; + color: @dropdown-header-color; + white-space: nowrap; // as with > li > a +} + +// Backdrop to catch body clicks on mobile, etc. +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: (@zindex-dropdown - 10); +} + +// Right aligned dropdowns +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +// Allow for dropdowns to go bottom up (aka, dropup-menu) +// +// Just add .dropup after the standard .dropdown class and you're set, bro. +// TODO: abstract this so that the navbar fixed styles are not placed here? + +.dropup, +.navbar-fixed-bottom .dropdown { + // Reverse the caret + .caret { + border-top: 0; + border-bottom: @caret-width-base solid; + content: ""; + } + // Different positioning for bottom up menu + .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; + } +} + + +// Component alignment +// +// Reiterate per navbar.less and the modified component alignment there. + +@media (min-width: @grid-float-breakpoint) { + .navbar-right { + .dropdown-menu { + .dropdown-menu-right(); + } + // Necessary for overrides of the default right aligned menu. + // Will remove come v4 in all likelihood. + .dropdown-menu-left { + .dropdown-menu-left(); + } + } +} diff --git a/examples/laravel-api/resources/assets/less/bootstrap/forms.less b/examples/laravel-api/resources/assets/less/bootstrap/forms.less new file mode 100644 index 00000000..1bcc2b6b --- /dev/null +++ b/examples/laravel-api/resources/assets/less/bootstrap/forms.less @@ -0,0 +1,546 @@ +// +// Forms +// -------------------------------------------------- + + +// Normalize non-controls +// +// Restyle and baseline non-control form elements. + +fieldset { + padding: 0; + margin: 0; + border: 0; + // Chrome and Firefox set a `min-width: min-content;` on fieldsets, + // so we reset that to ensure it behaves more like a standard block element. + // See https://github.com/twbs/bootstrap/issues/12359. + min-width: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: @line-height-computed; + font-size: (@font-size-base * 1.5); + line-height: inherit; + color: @legend-color; + border: 0; + border-bottom: 1px solid @legend-border-color; +} + +label { + display: inline-block; + max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141) + margin-bottom: 5px; + font-weight: bold; +} + + +// Normalize form controls +// +// While most of our form styles require extra classes, some basic normalization +// is required to ensure optimum display with or without those classes to better +// address browser inconsistencies. + +// Override content-box in Normalize (* isn't specific enough) +input[type="search"] { + .box-sizing(border-box); +} + +// Position radios and checkboxes better +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; // IE8-9 + line-height: normal; +} + +// Set the height of file controls to match text inputs +input[type="file"] { + display: block; +} + +// Make range inputs behave like textual form controls +input[type="range"] { + display: block; + width: 100%; +} + +// Make multiple select elements height not fixed +select[multiple], +select[size] { + height: auto; +} + +// Focus for file, radio, and checkbox +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + .tab-focus(); +} + +// Adjust output element +output { + display: block; + padding-top: (@padding-base-vertical + 1); + font-size: @font-size-base; + line-height: @line-height-base; + color: @input-color; +} + + +// Common form controls +// +// Shared size and type resets for form controls. Apply `.form-control` to any +// of the following form controls: +// +// select +// textarea +// input[type="text"] +// input[type="password"] +// input[type="datetime"] +// input[type="datetime-local"] +// input[type="date"] +// input[type="month"] +// input[type="time"] +// input[type="week"] +// input[type="number"] +// input[type="email"] +// input[type="url"] +// input[type="search"] +// input[type="tel"] +// input[type="color"] + +.form-control { + display: block; + width: 100%; + height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border) + padding: @padding-base-vertical @padding-base-horizontal; + font-size: @font-size-base; + line-height: @line-height-base; + color: @input-color; + background-color: @input-bg; + background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 + border: 1px solid @input-border; + border-radius: @input-border-radius; + .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); + .transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s"); + + // Customize the `:focus` state to imitate native WebKit styles. + .form-control-focus(); + + // Placeholder + .placeholder(); + + // Disabled and read-only inputs + // + // HTML5 says that controls under a fieldset > legend:first-child won't be + // disabled if the fieldset is disabled. Due to implementation difficulty, we + // don't honor that edge case; we style them as disabled anyway. + &[disabled], + &[readonly], + fieldset[disabled] & { + cursor: @cursor-disabled; + background-color: @input-bg-disabled; + opacity: 1; // iOS fix for unreadable disabled content + } + + // Reset height for `textarea`s + textarea& { + height: auto; + } +} + + +// Search inputs in iOS +// +// This overrides the extra rounded corners on search inputs in iOS so that our +// `.form-control` class can properly style them. Note that this cannot simply +// be added to `.form-control` as it's not specific enough. For details, see +// https://github.com/twbs/bootstrap/issues/11586. + +input[type="search"] { + -webkit-appearance: none; +} + + +// Special styles for iOS temporal inputs +// +// In Mobile Safari, setting `display: block` on temporal inputs causes the +// text within the input to become vertically misaligned. As a workaround, we +// set a pixel line-height that matches the given height of the input, but only +// for Safari. + +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"], + input[type="time"], + input[type="datetime-local"], + input[type="month"] { + line-height: @input-height-base; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm { + line-height: @input-height-small; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg { + line-height: @input-height-large; + } +} + + +// Form groups +// +// Designed to help with the organization and spacing of vertical forms. For +// horizontal forms, use the predefined grid classes. + +.form-group { + margin-bottom: 15px; +} + + +// Checkboxes and radios +// +// Indent the labels to position radios/checkboxes as hanging controls. + +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; + + label { + min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; + } +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; +} + +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing +} + +// Radios and checkboxes on same line +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; // space out consecutive inline controls +} + +// Apply same disabled cursor tweak as for inputs +// Some special care is needed because