update v 1.0.7.5

This commit is contained in:
Sujit Prasad
2016-06-13 20:41:55 +05:30
parent aa9786d829
commit 283d97e3ea
5078 changed files with 339851 additions and 175995 deletions

View File

@@ -1,3 +0,0 @@
# Laravel Contribution Guide
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](http://laravel.com/docs/contributions). Please review the entire guide before sending a pull request.

View File

@@ -15,35 +15,34 @@
}
],
"require": {
"php": ">=5.4.0",
"ext-openssl": "*",
"ext-mcrypt": "*",
"php": ">=5.5.9",
"ext-mbstring": "*",
"classpreloader/classpreloader": "~1.2",
"danielstjules/stringy": "~1.8",
"ext-openssl": "*",
"classpreloader/classpreloader": "~3.0",
"doctrine/inflector": "~1.0",
"ircmaxell/password-compat": "~1.0",
"jeremeamia/superclosure": "~2.0",
"jeremeamia/superclosure": "~2.2",
"league/flysystem": "~1.0",
"monolog/monolog": "~1.11",
"mtdowling/cron-expression": "~1.0",
"nesbot/carbon": "~1.0",
"psy/psysh": "0.4.*",
"nesbot/carbon": "~1.20",
"paragonie/random_compat": "~1.4",
"psy/psysh": "0.7.*",
"swiftmailer/swiftmailer": "~5.1",
"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"
"symfony/console": "2.8.*|3.0.*",
"symfony/debug": "2.8.*|3.0.*",
"symfony/finder": "2.8.*|3.0.*",
"symfony/http-foundation": "2.8.*|3.0.*",
"symfony/http-kernel": "2.8.*|3.0.*",
"symfony/polyfill-php56": "~1.0",
"symfony/process": "2.8.*|3.0.*",
"symfony/routing": "2.8.*|3.0.*",
"symfony/translation": "2.8.*|3.0.*",
"symfony/var-dumper": "2.8.*|3.0.*",
"vlucas/phpdotenv": "~2.2"
},
"replace": {
"illuminate/auth": "self.version",
"illuminate/broadcasting": "self.version",
"illuminate/bus": "self.version",
"illuminate/cache": "self.version",
"illuminate/config": "self.version",
@@ -56,7 +55,6 @@
"illuminate/events": "self.version",
"illuminate/exception": "self.version",
"illuminate/filesystem": "self.version",
"illuminate/foundation": "self.version",
"illuminate/hashing": "self.version",
"illuminate/http": "self.version",
"illuminate/log": "self.version",
@@ -73,12 +71,13 @@
"illuminate/view": "self.version"
},
"require-dev": {
"aws/aws-sdk-php": "~2.4",
"iron-io/iron_mq": "~1.5",
"aws/aws-sdk-php": "~3.0",
"mockery/mockery": "~0.9.4",
"pda/pheanstalk": "~3.0",
"phpunit/phpunit": "~4.1",
"predis/predis": "~1.0",
"mockery/mockery": "~0.9",
"phpunit/phpunit": "~4.0"
"symfony/css-selector": "2.8.*|3.0.*",
"symfony/dom-crawler": "2.8.*|3.0.*"
},
"autoload": {
"classmap": [
@@ -94,18 +93,22 @@
},
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
"dev-master": "5.2-dev"
}
},
"suggest": {
"aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~2.4).",
"aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).",
"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).",
"fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).",
"guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~5.3|~6.0).",
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).",
"league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).",
"pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).",
"predis/predis": "Required to use the redis cache and queue drivers (~1.0)."
"predis/predis": "Required to use the redis cache and queue drivers (~1.0).",
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0).",
"symfony/css-selector": "Required to use some of the crawler integration testing tools (2.8.*|3.0.*).",
"symfony/dom-crawler": "Required to use most of the crawler integration testing tools (2.8.*|3.0.*).",
"symfony/psr-http-message-bridge": "Required to psr7 bridging features (0.2.*)."
},
"minimum-stability": "dev"
}

View File

@@ -1,5 +1,6 @@
## Laravel Framework (Kernel)
# Laravel Framework (Kernel)
[![StyleCI](https://styleci.io/repos/7548986/shield?style=flat)](https://styleci.io/repos/7548986)
[![Build Status](https://travis-ci.org/laravel/framework.svg)](https://travis-ci.org/laravel/framework)
[![Total Downloads](https://poser.pugx.org/laravel/framework/d/total.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)
@@ -26,6 +27,6 @@ Thank you for considering contributing to the Laravel framework! The contributio
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed.
### License
## License
The Laravel framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).

View File

@@ -0,0 +1,10 @@
<?php
namespace Illuminate\Auth\Access;
use Exception;
class AuthorizationException extends Exception
{
//
}

View File

@@ -0,0 +1,453 @@
<?php
namespace Illuminate\Auth\Access;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
class Gate implements GateContract
{
use HandlesAuthorization;
/**
* The container instance.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* The user resolver callable.
*
* @var callable
*/
protected $userResolver;
/**
* All of the defined abilities.
*
* @var array
*/
protected $abilities = [];
/**
* All of the defined policies.
*
* @var array
*/
protected $policies = [];
/**
* All of the registered before callbacks.
*
* @var array
*/
protected $beforeCallbacks = [];
/**
* All of the registered after callbacks.
*
* @var array
*/
protected $afterCallbacks = [];
/**
* Create a new gate instance.
*
* @param \Illuminate\Contracts\Container\Container $container
* @param callable $userResolver
* @param array $abilities
* @param array $policies
* @param array $beforeCallbacks
* @param array $afterCallbacks
* @return void
*/
public function __construct(Container $container, callable $userResolver, array $abilities = [], array $policies = [], array $beforeCallbacks = [], array $afterCallbacks = [])
{
$this->policies = $policies;
$this->container = $container;
$this->abilities = $abilities;
$this->userResolver = $userResolver;
$this->afterCallbacks = $afterCallbacks;
$this->beforeCallbacks = $beforeCallbacks;
}
/**
* Determine if a given ability has been defined.
*
* @param string $ability
* @return bool
*/
public function has($ability)
{
return isset($this->abilities[$ability]);
}
/**
* Define a new ability.
*
* @param string $ability
* @param callable|string $callback
* @return $this
*
* @throws \InvalidArgumentException
*/
public function define($ability, $callback)
{
if (is_callable($callback)) {
$this->abilities[$ability] = $callback;
} elseif (is_string($callback) && Str::contains($callback, '@')) {
$this->abilities[$ability] = $this->buildAbilityCallback($callback);
} else {
throw new InvalidArgumentException("Callback must be a callable or a 'Class@method' string.");
}
return $this;
}
/**
* Create the ability callback for a callback string.
*
* @param string $callback
* @return \Closure
*/
protected function buildAbilityCallback($callback)
{
return function () use ($callback) {
list($class, $method) = explode('@', $callback);
return call_user_func_array([$this->resolvePolicy($class), $method], func_get_args());
};
}
/**
* Define a policy class for a given class type.
*
* @param string $class
* @param string $policy
* @return $this
*/
public function policy($class, $policy)
{
$this->policies[$class] = $policy;
return $this;
}
/**
* Register a callback to run before all Gate checks.
*
* @param callable $callback
* @return $this
*/
public function before(callable $callback)
{
$this->beforeCallbacks[] = $callback;
return $this;
}
/**
* Register a callback to run after all Gate checks.
*
* @param callable $callback
* @return $this
*/
public function after(callable $callback)
{
$this->afterCallbacks[] = $callback;
return $this;
}
/**
* Determine if the given ability should be granted for the current user.
*
* @param string $ability
* @param array|mixed $arguments
* @return bool
*/
public function allows($ability, $arguments = [])
{
return $this->check($ability, $arguments);
}
/**
* Determine if the given ability should be denied for the current user.
*
* @param string $ability
* @param array|mixed $arguments
* @return bool
*/
public function denies($ability, $arguments = [])
{
return ! $this->allows($ability, $arguments);
}
/**
* Determine if the given ability should be granted for the current user.
*
* @param string $ability
* @param array|mixed $arguments
* @return bool
*/
public function check($ability, $arguments = [])
{
try {
$result = $this->raw($ability, $arguments);
} catch (AuthorizationException $e) {
return false;
}
return (bool) $result;
}
/**
* Determine if the given ability should be granted for the current user.
*
* @param string $ability
* @param array|mixed $arguments
* @return \Illuminate\Auth\Access\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function authorize($ability, $arguments = [])
{
$result = $this->raw($ability, $arguments);
if ($result instanceof Response) {
return $result;
}
return $result ? $this->allow() : $this->deny();
}
/**
* Get the raw result for the given ability for the current user.
*
* @param string $ability
* @param array|mixed $arguments
* @return mixed
*/
protected function raw($ability, $arguments = [])
{
if (! $user = $this->resolveUser()) {
return false;
}
$arguments = is_array($arguments) ? $arguments : [$arguments];
if (is_null($result = $this->callBeforeCallbacks($user, $ability, $arguments))) {
$result = $this->callAuthCallback($user, $ability, $arguments);
}
$this->callAfterCallbacks(
$user, $ability, $arguments, $result
);
return $result;
}
/**
* Resolve and call the appropriate authorization callback.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $ability
* @param array $arguments
* @return bool
*/
protected function callAuthCallback($user, $ability, array $arguments)
{
$callback = $this->resolveAuthCallback(
$user, $ability, $arguments
);
return call_user_func_array(
$callback, array_merge([$user], $arguments)
);
}
/**
* Call all of the before callbacks and return if a result is given.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $ability
* @param array $arguments
* @return bool|null
*/
protected function callBeforeCallbacks($user, $ability, array $arguments)
{
$arguments = array_merge([$user, $ability], [$arguments]);
foreach ($this->beforeCallbacks as $before) {
if (! is_null($result = call_user_func_array($before, $arguments))) {
return $result;
}
}
}
/**
* Call all of the after callbacks with check result.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $ability
* @param array $arguments
* @param bool $result
* @return void
*/
protected function callAfterCallbacks($user, $ability, array $arguments, $result)
{
$arguments = array_merge([$user, $ability, $result], [$arguments]);
foreach ($this->afterCallbacks as $after) {
call_user_func_array($after, $arguments);
}
}
/**
* Resolve the callable for the given ability and arguments.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $ability
* @param array $arguments
* @return callable
*/
protected function resolveAuthCallback($user, $ability, array $arguments)
{
if ($this->firstArgumentCorrespondsToPolicy($arguments)) {
return $this->resolvePolicyCallback($user, $ability, $arguments);
} elseif (isset($this->abilities[$ability])) {
return $this->abilities[$ability];
} else {
return function () {
return false;
};
}
}
/**
* Determine if the first argument in the array corresponds to a policy.
*
* @param array $arguments
* @return bool
*/
protected function firstArgumentCorrespondsToPolicy(array $arguments)
{
if (! isset($arguments[0])) {
return false;
}
if (is_object($arguments[0])) {
return isset($this->policies[get_class($arguments[0])]);
}
return is_string($arguments[0]) && isset($this->policies[$arguments[0]]);
}
/**
* Resolve the callback for a policy check.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $ability
* @param array $arguments
* @return callable
*/
protected function resolvePolicyCallback($user, $ability, array $arguments)
{
return function () use ($user, $ability, $arguments) {
$instance = $this->getPolicyFor($arguments[0]);
if (method_exists($instance, 'before')) {
// We will prepend the user and ability onto the arguments so that the before
// callback can determine which ability is being called. Then we will call
// into the policy before methods with the arguments and get the result.
$beforeArguments = array_merge([$user, $ability], $arguments);
$result = call_user_func_array(
[$instance, 'before'], $beforeArguments
);
// If we received a non-null result from the before method, we will return it
// as the result of a check. This allows developers to override the checks
// in the policy and return a result for all rules defined in the class.
if (! is_null($result)) {
return $result;
}
}
if (strpos($ability, '-') !== false) {
$ability = Str::camel($ability);
}
if (! is_callable([$instance, $ability])) {
return false;
}
return call_user_func_array(
[$instance, $ability], array_merge([$user], $arguments)
);
};
}
/**
* Get a policy instance for a given class.
*
* @param object|string $class
* @return mixed
*
* @throws \InvalidArgumentException
*/
public function getPolicyFor($class)
{
if (is_object($class)) {
$class = get_class($class);
}
if (! isset($this->policies[$class])) {
throw new InvalidArgumentException("Policy not defined for [{$class}].");
}
return $this->resolvePolicy($this->policies[$class]);
}
/**
* Build a policy class instance of the given type.
*
* @param object|string $class
* @return mixed
*/
public function resolvePolicy($class)
{
return $this->container->make($class);
}
/**
* Get a guard instance for the given user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable|mixed $user
* @return static
*/
public function forUser($user)
{
$callback = function () use ($user) {
return $user;
};
return new static(
$this->container, $callback, $this->abilities,
$this->policies, $this->beforeCallbacks, $this->afterCallbacks
);
}
/**
* Resolve the user from the user resolver.
*
* @return mixed
*/
protected function resolveUser()
{
return call_user_func($this->userResolver);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Illuminate\Auth\Access;
trait HandlesAuthorization
{
/**
* Create a new access response.
*
* @param string|null $message
* @return \Illuminate\Auth\Access\Response
*/
protected function allow($message = null)
{
return new Response($message);
}
/**
* Throws an unauthorized exception.
*
* @param string $message
* @return void
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
protected function deny($message = 'This action is unauthorized.')
{
throw new AuthorizationException($message);
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Illuminate\Auth\Access;
class Response
{
/**
* The response message.
*
* @var string|null
*/
protected $message;
/**
* Create a new response.
*
* @param string|null $message
*/
public function __construct($message = null)
{
$this->message = $message;
}
/**
* Get the response message.
*
* @return string|null
*/
public function message()
{
return $this->message;
}
/**
* Get the string representation of the message.
*
* @return string
*/
public function __toString()
{
return $this->message();
}
}

View File

@@ -1,119 +1,294 @@
<?php namespace Illuminate\Auth;
<?php
use Illuminate\Support\Manager;
namespace Illuminate\Auth;
class AuthManager extends Manager {
use Closure;
use InvalidArgumentException;
use Illuminate\Contracts\Auth\Factory as FactoryContract;
/**
* Create a new driver instance.
*
* @param string $driver
* @return mixed
*/
protected function createDriver($driver)
{
$guard = parent::createDriver($driver);
class AuthManager implements FactoryContract
{
use CreatesUserProviders;
// When using the remember me functionality of the authentication services we
// will need to be set the encryption instance of the guard, which allows
// secure, encrypted cookie values to get generated for those cookies.
$guard->setCookieJar($this->app['cookie']);
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;
$guard->setDispatcher($this->app['events']);
/**
* The registered custom driver creators.
*
* @var array
*/
protected $customCreators = [];
return $guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));
}
/**
* The array of created "drivers".
*
* @var array
*/
protected $guards = [];
/**
* Call a custom driver creator.
*
* @param string $driver
* @return \Illuminate\Auth\Guard
*/
protected function callCustomCreator($driver)
{
$custom = parent::callCustomCreator($driver);
/**
* The user resolver shared by various services.
*
* Determines the default user for Gate, Request, and the Authenticatable contract.
*
* @var \Closure
*/
protected $userResolver;
if ($custom instanceof Guard)
{
return $custom;
}
/**
* Create a new Auth manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
return new Guard($custom, $this->app['session.store']);
}
$this->userResolver = function ($guard = null) {
return $this->guard($guard)->user();
};
}
/**
* Create an instance of the database driver.
*
* @return \Illuminate\Auth\Guard
*/
public function createDatabaseDriver()
{
$provider = $this->createDatabaseProvider();
/**
* Attempt to get the guard from the local cache.
*
* @param string $name
* @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
*/
public function guard($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return new Guard($provider, $this->app['session.store']);
}
return isset($this->guards[$name])
? $this->guards[$name]
: $this->guards[$name] = $this->resolve($name);
}
/**
* Create an instance of the database user provider.
*
* @return \Illuminate\Auth\DatabaseUserProvider
*/
protected function createDatabaseProvider()
{
$connection = $this->app['db']->connection();
/**
* Resolve the given guard.
*
* @param string $name
* @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
*
* @throws \InvalidArgumentException
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
// When using the basic database user provider, we need to inject the table we
// want to use, since this is not an Eloquent model we will have no way to
// know without telling the provider, so we'll inject the config value.
$table = $this->app['config']['auth.table'];
if (is_null($config)) {
throw new InvalidArgumentException("Auth guard [{$name}] is not defined.");
}
return new DatabaseUserProvider($connection, $this->app['hash'], $table);
}
if (isset($this->customCreators[$config['driver']])) {
return $this->callCustomCreator($name, $config);
} else {
$driverMethod = 'create'.ucfirst($config['driver']).'Driver';
/**
* Create an instance of the Eloquent driver.
*
* @return \Illuminate\Auth\Guard
*/
public function createEloquentDriver()
{
$provider = $this->createEloquentProvider();
if (method_exists($this, $driverMethod)) {
return $this->{$driverMethod}($name, $config);
} else {
throw new InvalidArgumentException("Auth guard driver [{$name}] is not defined.");
}
}
}
return new Guard($provider, $this->app['session.store']);
}
/**
* Call a custom driver creator.
*
* @param string $name
* @param array $config
* @return mixed
*/
protected function callCustomCreator($name, array $config)
{
return $this->customCreators[$config['driver']]($this->app, $name, $config);
}
/**
* Create an instance of the Eloquent user provider.
*
* @return \Illuminate\Auth\EloquentUserProvider
*/
protected function createEloquentProvider()
{
$model = $this->app['config']['auth.model'];
/**
* Create a session based authentication guard.
*
* @param string $name
* @param array $config
* @return \Illuminate\Auth\SessionGuard
*/
public function createSessionDriver($name, $config)
{
$provider = $this->createUserProvider($config['provider']);
return new EloquentUserProvider($this->app['hash'], $model);
}
$guard = new SessionGuard($name, $provider, $this->app['session.store']);
/**
* Get the default authentication driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['auth.driver'];
}
// When using the remember me functionality of the authentication services we
// will need to be set the encryption instance of the guard, which allows
// secure, encrypted cookie values to get generated for those cookies.
if (method_exists($guard, 'setCookieJar')) {
$guard->setCookieJar($this->app['cookie']);
}
/**
* Set the default authentication driver name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['auth.driver'] = $name;
}
if (method_exists($guard, 'setDispatcher')) {
$guard->setDispatcher($this->app['events']);
}
if (method_exists($guard, 'setRequest')) {
$guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));
}
return $guard;
}
/**
* Create a token based authentication guard.
*
* @param string $name
* @param array $config
* @return \Illuminate\Auth\TokenGuard
*/
public function createTokenDriver($name, $config)
{
// The token guard implements a basic API token based guard implementation
// that takes an API token field from the request and matches it to the
// user in the database or another persistence layer where users are.
$guard = new TokenGuard(
$this->createUserProvider($config['provider']),
$this->app['request']
);
$this->app->refresh('request', $guard, 'setRequest');
return $guard;
}
/**
* Get the guard configuration.
*
* @param string $name
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']["auth.guards.{$name}"];
}
/**
* Get the default authentication driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['auth.defaults.guard'];
}
/**
* Set the default guard driver the factory should serve.
*
* @param string $name
* @return void
*/
public function shouldUse($name)
{
$this->setDefaultDriver($name);
$this->userResolver = function ($name = null) {
return $this->guard($name)->user();
};
}
/**
* Set the default authentication driver name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['auth.defaults.guard'] = $name;
}
/**
* Register a new callback based request guard.
*
* @param string $driver
* @param callable $callback
* @return $this
*/
public function viaRequest($driver, callable $callback)
{
return $this->extend($driver, function () use ($callback) {
$guard = new RequestGuard($callback, $this->app['request']);
$this->app->refresh('request', $guard, 'setRequest');
return $guard;
});
}
/**
* Get the user resolver callback.
*
* @return \Closure
*/
public function userResolver()
{
return $this->userResolver;
}
/**
* Set the callback to be used to resolve users.
*
* @param \Closure $userResolver
* @return $this
*/
public function resolveUsersUsing(Closure $userResolver)
{
$this->userResolver = $userResolver;
return $this;
}
/**
* Register a custom driver creator Closure.
*
* @param string $driver
* @param \Closure $callback
* @return $this
*/
public function extend($driver, Closure $callback)
{
$this->customCreators[$driver] = $callback;
return $this;
}
/**
* Register a custom provider creator Closure.
*
* @param string $name
* @param \Closure $callback
* @return $this
*/
public function provider($name, Closure $callback)
{
$this->customProviderCreators[$name] = $callback;
return $this;
}
/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return call_user_func_array([$this->guard(), $method], $parameters);
}
}

View File

@@ -1,73 +1,90 @@
<?php namespace Illuminate\Auth;
<?php
namespace Illuminate\Auth;
use Illuminate\Auth\Access\Gate;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
class AuthServiceProvider extends ServiceProvider {
class AuthServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerAuthenticator();
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerAuthenticator();
$this->registerUserResolver();
$this->registerUserResolver();
$this->registerAccessGate();
$this->registerRequestRebindHandler();
}
$this->registerRequestRebindHandler();
}
/**
* Register the authenticator services.
*
* @return void
*/
protected function registerAuthenticator()
{
$this->app->singleton('auth', function($app)
{
// Once the authentication service has actually been requested by the developer
// we will set a variable in the application indicating such. This helps us
// know that we need to set any queued cookies in the after event later.
$app['auth.loaded'] = true;
/**
* Register the authenticator services.
*
* @return void
*/
protected function registerAuthenticator()
{
$this->app->singleton('auth', function ($app) {
// Once the authentication service has actually been requested by the developer
// we will set a variable in the application indicating such. This helps us
// know that we need to set any queued cookies in the after event later.
$app['auth.loaded'] = true;
return new AuthManager($app);
});
return new AuthManager($app);
});
$this->app->singleton('auth.driver', function($app)
{
return $app['auth']->driver();
});
}
$this->app->singleton('auth.driver', function ($app) {
return $app['auth']->guard();
});
}
/**
* Register a resolver for the authenticated user.
*
* @return void
*/
protected function registerUserResolver()
{
$this->app->bind('Illuminate\Contracts\Auth\Authenticatable', function($app)
{
return $app['auth']->user();
});
}
/**
* Register a resolver for the authenticated user.
*
* @return void
*/
protected function registerUserResolver()
{
$this->app->bind(
AuthenticatableContract::class, function ($app) {
return call_user_func($app['auth']->userResolver());
}
);
}
/**
* Register a resolver for the authenticated user.
*
* @return void
*/
protected function registerRequestRebindHandler()
{
$this->app->rebinding('request', function($app, $request)
{
$request->setUserResolver(function() use ($app)
{
return $app['auth']->user();
});
});
}
/**
* Register the access gate service.
*
* @return void
*/
protected function registerAccessGate()
{
$this->app->singleton(GateContract::class, function ($app) {
return new Gate($app, function () use ($app) {
return call_user_func($app['auth']->userResolver());
});
});
}
/**
* Register a resolver for the authenticated user.
*
* @return void
*/
protected function registerRequestRebindHandler()
{
$this->app->rebinding('request', function ($app, $request) {
$request->setUserResolver(function ($guard = null) use ($app) {
return call_user_func($app['auth']->userResolver(), $guard);
});
});
}
}

View File

@@ -1,56 +1,67 @@
<?php namespace Illuminate\Auth;
<?php
trait Authenticatable {
namespace Illuminate\Auth;
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
trait Authenticatable
{
/**
* Get the name of the unique identifier for the user.
*
* @return string
*/
public function getAuthIdentifierName()
{
return $this->getKeyName();
}
/**
* Get the password for the user.
*
* @return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the token value for the "remember me" session.
*
* @return string
*/
public function getRememberToken()
{
return $this->{$this->getRememberTokenName()};
}
/**
* Get the password for the user.
*
* @return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Set the token value for the "remember me" session.
*
* @param string $value
* @return void
*/
public function setRememberToken($value)
{
$this->{$this->getRememberTokenName()} = $value;
}
/**
* Get the token value for the "remember me" session.
*
* @return string
*/
public function getRememberToken()
{
return $this->{$this->getRememberTokenName()};
}
/**
* Get the column name for the "remember me" token.
*
* @return string
*/
public function getRememberTokenName()
{
return 'remember_token';
}
/**
* Set the token value for the "remember me" session.
*
* @param string $value
* @return void
*/
public function setRememberToken($value)
{
$this->{$this->getRememberTokenName()} = $value;
}
/**
* Get the column name for the "remember me" token.
*
* @return string
*/
public function getRememberTokenName()
{
return 'remember_token';
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Illuminate\Auth;
use Exception;
class AuthenticationException extends Exception
{
/**
* The guard instance.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $guard;
/**
* Create a new authentication exception.
*
* @param \Illuminate\Contracts\Auth\Guard|null $guard
*/
public function __construct($guard = null)
{
$this->guard = $guard;
parent::__construct('Unauthenticated.');
}
/**
* Get the guard instance.
*
* @return \Illuminate\Contracts\Auth\Guard|null
*/
public function guard()
{
return $this->guard;
}
}

View File

@@ -1,33 +1,34 @@
<?php namespace Illuminate\Auth\Console;
<?php
namespace Illuminate\Auth\Console;
use Illuminate\Console\Command;
class ClearResetsCommand extends Command {
class ClearResetsCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'auth:clear-resets {name? : The name of the password broker}';
/**
* The console command name.
*
* @var string
*/
protected $name = 'auth:clear-resets';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Flush expired password reset tokens';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Flush expired password reset tokens';
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->laravel['auth.password.tokens']->deleteExpired();
$this->info('Expired reset tokens cleared!');
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->laravel['auth.password']->broker($this->argument('name'))->getRepository()->deleteExpired();
$this->info('Expired reset tokens cleared!');
}
}

View File

@@ -0,0 +1,122 @@
<?php
namespace Illuminate\Auth\Console;
use Illuminate\Console\Command;
use Illuminate\Console\AppNamespaceDetectorTrait;
class MakeAuthCommand extends Command
{
use AppNamespaceDetectorTrait;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'make:auth {--views : Only scaffold the authentication views}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Scaffold basic login and registration views and routes';
/**
* The views that need to be exported.
*
* @var array
*/
protected $views = [
'auth/login.stub' => 'auth/login.blade.php',
'auth/register.stub' => 'auth/register.blade.php',
'auth/passwords/email.stub' => 'auth/passwords/email.blade.php',
'auth/passwords/reset.stub' => 'auth/passwords/reset.blade.php',
'auth/emails/password.stub' => 'auth/emails/password.blade.php',
'layouts/app.stub' => 'layouts/app.blade.php',
'home.stub' => 'home.blade.php',
'welcome.stub' => 'welcome.blade.php',
];
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->createDirectories();
$this->exportViews();
if (! $this->option('views')) {
$this->info('Installed HomeController.');
file_put_contents(
app_path('Http/Controllers/HomeController.php'),
$this->compileControllerStub()
);
$this->info('Updated Routes File.');
file_put_contents(
app_path('Http/routes.php'),
file_get_contents(__DIR__.'/stubs/make/routes.stub'),
FILE_APPEND
);
}
$this->comment('Authentication scaffolding generated successfully!');
}
/**
* Create the directories for the files.
*
* @return void
*/
protected function createDirectories()
{
if (! is_dir(base_path('resources/views/layouts'))) {
mkdir(base_path('resources/views/layouts'), 0755, true);
}
if (! is_dir(base_path('resources/views/auth/passwords'))) {
mkdir(base_path('resources/views/auth/passwords'), 0755, true);
}
if (! is_dir(base_path('resources/views/auth/emails'))) {
mkdir(base_path('resources/views/auth/emails'), 0755, true);
}
}
/**
* Export the authentication views.
*
* @return void
*/
protected function exportViews()
{
foreach ($this->views as $key => $value) {
$path = base_path('resources/views/'.$value);
$this->line('<info>Created View:</info> '.$path);
copy(__DIR__.'/stubs/make/views/'.$key, $path);
}
}
/**
* Compiles the HomeController stub.
*
* @return string
*/
protected function compileControllerStub()
{
return str_replace(
'{{namespace}}',
$this->getAppNamespace(),
file_get_contents(__DIR__.'/stubs/make/controllers/HomeController.stub')
);
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace {{namespace}}Http\Controllers;
use {{namespace}}Http\Requests;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view('home');
}
}

View File

@@ -0,0 +1,4 @@
Route::auth();
Route::get('/home', 'HomeController@index');

View File

@@ -0,0 +1 @@
Click here to reset your password: <a href="{{ $link = url('password/reset', $token).'?email='.urlencode($user->getEmailForPasswordReset()) }}"> {{ $link }} </a>

View File

@@ -0,0 +1,66 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Login</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/login') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}">
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password">
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
<i class="fa fa-btn fa-sign-in"></i> Login
</button>
<a class="btn btn-link" href="{{ url('/password/reset') }}">Forgot Your Password?</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,47 @@
@extends('layouts.app')
<!-- Main Content -->
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Reset Password</div>
<div class="panel-body">
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<form class="form-horizontal" role="form" method="POST" action="{{ url('/password/email') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}">
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
<i class="fa fa-btn fa-envelope"></i> Send Password Reset Link
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,70 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Reset Password</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/password/reset') }}">
{{ csrf_field() }}
<input type="hidden" name="token" value="{{ $token }}">
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ $email or old('email') }}">
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password">
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
<label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation">
@if ($errors->has('password_confirmation'))
<span class="help-block">
<strong>{{ $errors->first('password_confirmation') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
<i class="fa fa-btn fa-refresh"></i> Reset Password
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,82 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Register</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/register') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<label for="name" class="col-md-4 control-label">Name</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}">
@if ($errors->has('name'))
<span class="help-block">
<strong>{{ $errors->first('name') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}">
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password">
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
<label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation">
@if ($errors->has('password_confirmation'))
<span class="help-block">
<strong>{{ $errors->first('password_confirmation') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
<i class="fa fa-btn fa-user"></i> Register
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,17 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">Dashboard</div>
<div class="panel-body">
You are logged in!
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css" integrity="sha384-XdYbMnZ/QjLh6iI4ogqCTaIjrFk87ip+ekIjefZch0Y+PvJ8CDYtEs1ipDmPorQ+" crossorigin="anonymous">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700">
<!-- Styles -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
{{-- <link href="{{ elixir('css/app.css') }}" rel="stylesheet"> --}}
<style>
body {
font-family: 'Lato';
}
.fa-btn {
margin-right: 6px;
}
</style>
</head>
<body id="app-layout">
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<!-- Collapsed Hamburger -->
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- Branding Image -->
<a class="navbar-brand" href="{{ url('/') }}">
Laravel
</a>
</div>
<div class="collapse navbar-collapse" id="app-navbar-collapse">
<!-- Left Side Of Navbar -->
<ul class="nav navbar-nav">
<li><a href="{{ url('/home') }}">Home</a></li>
</ul>
<!-- Right Side Of Navbar -->
<ul class="nav navbar-nav navbar-right">
<!-- Authentication Links -->
@if (Auth::guest())
<li><a href="{{ url('/login') }}">Login</a></li>
<li><a href="{{ url('/register') }}">Register</a></li>
@else
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
{{ Auth::user()->name }} <span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li><a href="{{ url('/logout') }}"><i class="fa fa-btn fa-sign-out"></i>Logout</a></li>
</ul>
</li>
@endif
</ul>
</div>
</div>
</nav>
@yield('content')
<!-- JavaScripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js" integrity="sha384-I6F5OKECLVtK/BL+8iSLDEHowSAfUo76ZL9+kGAgTRdiByINKJaqTPH/QVNS1VDb" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
{{-- <script src="{{ elixir('js/app.js') }}"></script> --}}
</body>
</html>

View File

@@ -0,0 +1,17 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">Welcome</div>
<div class="panel-body">
Your Application's Landing Page.
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,67 @@
<?php
namespace Illuminate\Auth;
use InvalidArgumentException;
trait CreatesUserProviders
{
/**
* The registered custom provider creators.
*
* @var array
*/
protected $customProviderCreators = [];
/**
* Create the user provider implementation for the driver.
*
* @param string $provider
* @return \Illuminate\Contracts\Auth\UserProvider
*
* @throws \InvalidArgumentException
*/
public function createUserProvider($provider)
{
$config = $this->app['config']['auth.providers.'.$provider];
if (isset($this->customProviderCreators[$config['driver']])) {
return call_user_func(
$this->customProviderCreators[$config['driver']], $this->app, $config
);
}
switch ($config['driver']) {
case 'database':
return $this->createDatabaseProvider($config);
case 'eloquent':
return $this->createEloquentProvider($config);
default:
throw new InvalidArgumentException("Authentication user provider [{$config['driver']}] is not defined.");
}
}
/**
* Create an instance of the database user provider.
*
* @param array $config
* @return \Illuminate\Auth\DatabaseUserProvider
*/
protected function createDatabaseProvider($config)
{
$connection = $this->app['db']->connection();
return new DatabaseUserProvider($connection, $this->app['hash'], $config['table']);
}
/**
* Create an instance of the Eloquent user provider.
*
* @param array $config
* @return \Illuminate\Auth\EloquentUserProvider
*/
protected function createEloquentProvider($config)
{
return new EloquentUserProvider($this->app['hash'], $config['model']);
}
}

View File

@@ -1,147 +1,146 @@
<?php namespace Illuminate\Auth;
<?php
namespace Illuminate\Auth;
use Illuminate\Support\Str;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
class DatabaseUserProvider implements UserProvider {
class DatabaseUserProvider implements UserProvider
{
/**
* The active database connection.
*
* @var \Illuminate\Database\ConnectionInterface
*/
protected $conn;
/**
* The active database connection.
*
* @var \Illuminate\Database\ConnectionInterface
*/
protected $conn;
/**
* The hasher implementation.
*
* @var \Illuminate\Contracts\Hashing\Hasher
*/
protected $hasher;
/**
* The hasher implementation.
*
* @var \Illuminate\Contracts\Hashing\Hasher
*/
protected $hasher;
/**
* The table containing the users.
*
* @var string
*/
protected $table;
/**
* The table containing the users.
*
* @var string
*/
protected $table;
/**
* Create a new database user provider.
*
* @param \Illuminate\Database\ConnectionInterface $conn
* @param \Illuminate\Contracts\Hashing\Hasher $hasher
* @param string $table
* @return void
*/
public function __construct(ConnectionInterface $conn, HasherContract $hasher, $table)
{
$this->conn = $conn;
$this->table = $table;
$this->hasher = $hasher;
}
/**
* Create a new database user provider.
*
* @param \Illuminate\Database\ConnectionInterface $conn
* @param \Illuminate\Contracts\Hashing\Hasher $hasher
* @param string $table
* @return void
*/
public function __construct(ConnectionInterface $conn, HasherContract $hasher, $table)
{
$this->conn = $conn;
$this->table = $table;
$this->hasher = $hasher;
}
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
$user = $this->conn->table($this->table)->find($identifier);
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
$user = $this->conn->table($this->table)->find($identifier);
return $this->getGenericUser($user);
}
return $this->getGenericUser($user);
}
/**
* Retrieve a user by their unique identifier and "remember me" token.
*
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
$user = $this->conn->table($this->table)
->where('id', $identifier)
->where('remember_token', $token)
->first();
/**
* Retrieve a user by their unique identifier and "remember me" token.
*
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
$user = $this->conn->table($this->table)
->where('id', $identifier)
->where('remember_token', $token)
->first();
return $this->getGenericUser($user);
}
return $this->getGenericUser($user);
}
/**
* Update the "remember me" token for the given user in storage.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $token
* @return void
*/
public function updateRememberToken(UserContract $user, $token)
{
$this->conn->table($this->table)
->where('id', $user->getAuthIdentifier())
->update(['remember_token' => $token]);
}
/**
* Update the "remember me" token for the given user in storage.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $token
* @return void
*/
public function updateRememberToken(UserContract $user, $token)
{
$this->conn->table($this->table)
->where('id', $user->getAuthIdentifier())
->update(['remember_token' => $token]);
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// generic "user" object that will be utilized by the Guard instances.
$query = $this->conn->table($this->table);
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// generic "user" object that will be utilized by the Guard instances.
$query = $this->conn->table($this->table);
foreach ($credentials as $key => $value) {
if (! Str::contains($key, 'password')) {
$query->where($key, $value);
}
}
foreach ($credentials as $key => $value)
{
if ( ! str_contains($key, 'password'))
{
$query->where($key, $value);
}
}
// Now we are ready to execute the query to see if we have an user matching
// the given credentials. If not, we will just return nulls and indicate
// that there are no matching users for these given credential arrays.
$user = $query->first();
// Now we are ready to execute the query to see if we have an user matching
// the given credentials. If not, we will just return nulls and indicate
// that there are no matching users for these given credential arrays.
$user = $query->first();
return $this->getGenericUser($user);
}
return $this->getGenericUser($user);
}
/**
* Get the generic user.
*
* @param mixed $user
* @return \Illuminate\Auth\GenericUser|null
*/
protected function getGenericUser($user)
{
if ($user !== null) {
return new GenericUser((array) $user);
}
}
/**
* Get the generic user.
*
* @param mixed $user
* @return \Illuminate\Auth\GenericUser|null
*/
protected function getGenericUser($user)
{
if ($user !== null)
{
return new GenericUser((array) $user);
}
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(UserContract $user, array $credentials)
{
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(UserContract $user, array $credentials)
{
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
}

View File

@@ -1,128 +1,178 @@
<?php namespace Illuminate\Auth;
<?php
namespace Illuminate\Auth;
use Illuminate\Support\Str;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
class EloquentUserProvider implements UserProvider {
class EloquentUserProvider implements UserProvider
{
/**
* The hasher implementation.
*
* @var \Illuminate\Contracts\Hashing\Hasher
*/
protected $hasher;
/**
* The hasher implementation.
*
* @var \Illuminate\Contracts\Hashing\Hasher
*/
protected $hasher;
/**
* The Eloquent user model.
*
* @var string
*/
protected $model;
/**
* The Eloquent user model.
*
* @var string
*/
protected $model;
/**
* Create a new database user provider.
*
* @param \Illuminate\Contracts\Hashing\Hasher $hasher
* @param string $model
* @return void
*/
public function __construct(HasherContract $hasher, $model)
{
$this->model = $model;
$this->hasher = $hasher;
}
/**
* Create a new database user provider.
*
* @param \Illuminate\Contracts\Hashing\Hasher $hasher
* @param string $model
* @return void
*/
public function __construct(HasherContract $hasher, $model)
{
$this->model = $model;
$this->hasher = $hasher;
}
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
return $this->createModel()->newQuery()->find($identifier);
}
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
return $this->createModel()->newQuery()->find($identifier);
}
/**
* Retrieve a user by their unique identifier and "remember me" token.
*
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
$model = $this->createModel();
/**
* Retrieve a user by their unique identifier and "remember me" token.
*
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
$model = $this->createModel();
return $model->newQuery()
->where($model->getAuthIdentifierName(), $identifier)
->where($model->getRememberTokenName(), $token)
->first();
}
return $model->newQuery()
->where($model->getKeyName(), $identifier)
->where($model->getRememberTokenName(), $token)
->first();
}
/**
* Update the "remember me" token for the given user in storage.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $token
* @return void
*/
public function updateRememberToken(UserContract $user, $token)
{
$user->setRememberToken($token);
/**
* Update the "remember me" token for the given user in storage.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $token
* @return void
*/
public function updateRememberToken(UserContract $user, $token)
{
$user->setRememberToken($token);
$user->save();
}
$user->save();
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
if (empty($credentials)) {
return;
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$query = $this->createModel()->newQuery();
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$query = $this->createModel()->newQuery();
foreach ($credentials as $key => $value)
{
if ( ! str_contains($key, 'password'))
{
$query->where($key, $value);
}
}
foreach ($credentials as $key => $value) {
if (! Str::contains($key, 'password')) {
$query->where($key, $value);
}
}
return $query->first();
}
return $query->first();
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(UserContract $user, array $credentials)
{
$plain = $credentials['password'];
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(UserContract $user, array $credentials)
{
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
return $this->hasher->check($plain, $user->getAuthPassword());
}
/**
* Create a new instance of the model.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function createModel()
{
$class = '\\'.ltrim($this->model, '\\');
/**
* Create a new instance of the model.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function createModel()
{
$class = '\\'.ltrim($this->model, '\\');
return new $class;
}
return new $class;
}
/**
* Gets the hasher implementation.
*
* @return \Illuminate\Contracts\Hashing\Hasher
*/
public function getHasher()
{
return $this->hasher;
}
/**
* Sets the hasher implementation.
*
* @param \Illuminate\Contracts\Hashing\Hasher $hasher
* @return $this
*/
public function setHasher(HasherContract $hasher)
{
$this->hasher = $hasher;
return $this;
}
/**
* Gets the name of the Eloquent user model.
*
* @return string
*/
public function getModel()
{
return $this->model;
}
/**
* Sets the name of the Eloquent user model.
*
* @param string $model
* @return $this
*/
public function setModel($model)
{
$this->model = $model;
return $this;
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Illuminate\Auth\Events;
class Attempting
{
/**
* The credentials for the user.
*
* @var array
*/
public $credentials;
/**
* Indicates if the user should be "remembered".
*
* @var bool
*/
public $remember;
/**
* Indicates if the user should be authenticated if successful.
*
* @var bool
*/
public $login;
/**
* Create a new event instance.
*
* @param array $credentials
* @param bool $remember
* @param bool $login
*/
public function __construct($credentials, $remember, $login)
{
$this->login = $login;
$this->remember = $remember;
$this->credentials = $credentials;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Illuminate\Auth\Events;
class Failed
{
/**
* The user the attempter was trying to authenticate as.
*
* @var \Illuminate\Contracts\Auth\Authenticatable|null
*/
public $user;
/**
* The credentials provided by the attempter.
*
* @var array
*/
public $credentials;
/**
* Create a new event instance.
*
* @param \Illuminate\Contracts\Auth\Authenticatable|null $user
* @param array $credentials
*/
public function __construct($user, $credentials)
{
$this->user = $user;
$this->credentials = $credentials;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Illuminate\Auth\Events;
use Illuminate\Http\Request;
class Lockout
{
/**
* The throttled request.
*
* @var \Illuminate\Http\Request
*/
public $request;
/**
* Create a new event instance.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
public function __construct(Request $request)
{
$this->request = $request;
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Illuminate\Auth\Events;
use Illuminate\Queue\SerializesModels;
class Login
{
use SerializesModels;
/**
* The authenticated user.
*
* @var \Illuminate\Contracts\Auth\Authenticatable
*/
public $user;
/**
* Indicates if the user should be "remembered".
*
* @var bool
*/
public $remember;
/**
* Create a new event instance.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param bool $remember
* @return void
*/
public function __construct($user, $remember)
{
$this->user = $user;
$this->remember = $remember;
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Illuminate\Auth\Events;
use Illuminate\Queue\SerializesModels;
class Logout
{
use SerializesModels;
/**
* The authenticated user.
*
* @var \Illuminate\Contracts\Auth\Authenticatable
*/
public $user;
/**
* Create a new event instance.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return void
*/
public function __construct($user)
{
$this->user = $user;
}
}

View File

@@ -1,66 +0,0 @@
<?php namespace Illuminate\Auth;
use Illuminate\Support\ServiceProvider;
use Illuminate\Auth\Console\ClearResetsCommand;
class GeneratorServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* The commands to be registered.
*
* @var array
*/
protected $commands = [
'ClearResets',
];
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
foreach ($this->commands as $command)
{
$this->{"register{$command}Command"}();
}
$this->commands(
'command.auth.resets.clear'
);
}
/**
* Register the command.
*
* @return void
*/
protected function registerClearResetsCommand()
{
$this->app->singleton('command.auth.resets.clear', function()
{
return new ClearResetsCommand;
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'command.auth.resets.clear',
];
}
}

View File

@@ -1,121 +1,134 @@
<?php namespace Illuminate\Auth;
<?php
namespace Illuminate\Auth;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
class GenericUser implements UserContract {
class GenericUser implements UserContract
{
/**
* All of the user's attributes.
*
* @var array
*/
protected $attributes;
/**
* All of the user's attributes.
*
* @var array
*/
protected $attributes;
/**
* Create a new generic User object.
*
* @param array $attributes
* @return void
*/
public function __construct(array $attributes)
{
$this->attributes = $attributes;
}
/**
* Create a new generic User object.
*
* @param array $attributes
* @return void
*/
public function __construct(array $attributes)
{
$this->attributes = $attributes;
}
/**
* Get the name of the unique identifier for the user.
*
* @return string
*/
public function getAuthIdentifierName()
{
return 'id';
}
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->attributes['id'];
}
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier()
{
$name = $this->getAuthIdentifierName();
/**
* Get the password for the user.
*
* @return string
*/
public function getAuthPassword()
{
return $this->attributes['password'];
}
return $this->attributes[$name];
}
/**
* Get the "remember me" token value.
*
* @return string
*/
public function getRememberToken()
{
return $this->attributes[$this->getRememberTokenName()];
}
/**
* Get the password for the user.
*
* @return string
*/
public function getAuthPassword()
{
return $this->attributes['password'];
}
/**
* Set the "remember me" token value.
*
* @param string $value
* @return void
*/
public function setRememberToken($value)
{
$this->attributes[$this->getRememberTokenName()] = $value;
}
/**
* Get the "remember me" token value.
*
* @return string
*/
public function getRememberToken()
{
return $this->attributes[$this->getRememberTokenName()];
}
/**
* Get the column name for the "remember me" token.
*
* @return string
*/
public function getRememberTokenName()
{
return 'remember_token';
}
/**
* Set the "remember me" token value.
*
* @param string $value
* @return void
*/
public function setRememberToken($value)
{
$this->attributes[$this->getRememberTokenName()] = $value;
}
/**
* Dynamically access the user's attributes.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
return $this->attributes[$key];
}
/**
* Get the column name for the "remember me" token.
*
* @return string
*/
public function getRememberTokenName()
{
return 'remember_token';
}
/**
* Dynamically set an attribute on the user.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function __set($key, $value)
{
$this->attributes[$key] = $value;
}
/**
* Dynamically access the user's attributes.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
return $this->attributes[$key];
}
/**
* Dynamically check if a value is set on the user.
*
* @param string $key
* @return bool
*/
public function __isset($key)
{
return isset($this->attributes[$key]);
}
/**
* Dynamically set an attribute on the user.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function __set($key, $value)
{
$this->attributes[$key] = $value;
}
/**
* Dynamically unset a value on the user.
*
* @param string $key
* @return void
*/
public function __unset($key)
{
unset($this->attributes[$key]);
}
/**
* Dynamically check if a value is set on the user.
*
* @param string $key
* @return bool
*/
public function __isset($key)
{
return isset($this->attributes[$key]);
}
/**
* Dynamically unset a value on the user.
*
* @param string $key
* @return void
*/
public function __unset($key)
{
unset($this->attributes[$key]);
}
}

View File

@@ -1,788 +0,0 @@
<?php namespace Illuminate\Auth;
use RuntimeException;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Auth\UserProvider;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Contracts\Auth\Guard as GuardContract;
use Illuminate\Contracts\Cookie\QueueingFactory as CookieJar;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class Guard implements GuardContract {
/**
* The currently authenticated user.
*
* @var \Illuminate\Contracts\Auth\Authenticatable
*/
protected $user;
/**
* The user we last attempted to retrieve.
*
* @var \Illuminate\Contracts\Auth\Authenticatable
*/
protected $lastAttempted;
/**
* Indicates if the user was authenticated via a recaller cookie.
*
* @var bool
*/
protected $viaRemember = false;
/**
* The user provider implementation.
*
* @var \Illuminate\Contracts\Auth\UserProvider
*/
protected $provider;
/**
* The session used by the guard.
*
* @var \Symfony\Component\HttpFoundation\Session\SessionInterface
*/
protected $session;
/**
* The Illuminate cookie creator service.
*
* @var \Illuminate\Contracts\Cookie\QueueingFactory
*/
protected $cookie;
/**
* The request instance.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* The event dispatcher instance.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;
/**
* Indicates if the logout method has been called.
*
* @var bool
*/
protected $loggedOut = false;
/**
* Indicates if a token user retrieval has been attempted.
*
* @var bool
*/
protected $tokenRetrievalAttempted = false;
/**
* Create a new authentication guard.
*
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session
* @param \Symfony\Component\HttpFoundation\Request $request
* @return void
*/
public function __construct(UserProvider $provider,
SessionInterface $session,
Request $request = null)
{
$this->session = $session;
$this->request = $request;
$this->provider = $provider;
}
/**
* Determine if the current user is authenticated.
*
* @return bool
*/
public function check()
{
return ! is_null($this->user());
}
/**
* Determine if the current user is a guest.
*
* @return bool
*/
public function guest()
{
return ! $this->check();
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
if ($this->loggedOut) return;
// If we have already retrieved the user for the current request we can just
// return it back immediately. We do not want to pull the user data every
// request into the method because that would tremendously slow an app.
if ( ! is_null($this->user))
{
return $this->user;
}
$id = $this->session->get($this->getName());
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null;
if ( ! is_null($id))
{
$user = $this->provider->retrieveById($id);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();
if (is_null($user) && ! is_null($recaller))
{
$user = $this->getUserByRecaller($recaller);
if ($user)
{
$this->updateSession($user->getAuthIdentifier());
$this->fireLoginEvent($user, true);
}
}
return $this->user = $user;
}
/**
* Get the ID for the currently authenticated user.
*
* @return int|null
*/
public function id()
{
if ($this->loggedOut)
{
return;
}
$id = $this->session->get($this->getName(), $this->getRecallerId());
if (is_null($id) && $this->user())
{
$id = $this->user()->getAuthIdentifier();
}
return $id;
}
/**
* Pull a user from the repository by its recaller ID.
*
* @param string $recaller
* @return mixed
*/
protected function getUserByRecaller($recaller)
{
if ($this->validRecaller($recaller) && ! $this->tokenRetrievalAttempted)
{
$this->tokenRetrievalAttempted = true;
list($id, $token) = explode('|', $recaller, 2);
$this->viaRemember = ! is_null($user = $this->provider->retrieveByToken($id, $token));
return $user;
}
}
/**
* Get the decrypted recaller cookie for the request.
*
* @return string|null
*/
protected function getRecaller()
{
return $this->request->cookies->get($this->getRecallerName());
}
/**
* Get the user ID from the recaller cookie.
*
* @return string
*/
protected function getRecallerId()
{
if ($this->validRecaller($recaller = $this->getRecaller()))
{
return head(explode('|', $recaller));
}
}
/**
* Determine if the recaller cookie is in a valid format.
*
* @param string $recaller
* @return bool
*/
protected function validRecaller($recaller)
{
if ( ! is_string($recaller) || ! str_contains($recaller, '|')) return false;
$segments = explode('|', $recaller);
return count($segments) == 2 && trim($segments[0]) !== '' && trim($segments[1]) !== '';
}
/**
* Log a user into the application without sessions or cookies.
*
* @param array $credentials
* @return bool
*/
public function once(array $credentials = [])
{
if ($this->validate($credentials))
{
$this->setUser($this->lastAttempted);
return true;
}
return false;
}
/**
* Validate a user's credentials.
*
* @param array $credentials
* @return bool
*/
public function validate(array $credentials = [])
{
return $this->attempt($credentials, false, false);
}
/**
* Attempt to authenticate using HTTP Basic Auth.
*
* @param string $field
* @return \Symfony\Component\HttpFoundation\Response|null
*/
public function basic($field = 'email')
{
if ($this->check())
{
return;
}
// If a username is set on the HTTP basic request, we will return out without
// interrupting the request lifecycle. Otherwise, we'll need to generate a
// request indicating that the given credentials were invalid for login.
if ($this->attemptBasic($this->getRequest(), $field))
{
return;
}
return $this->getBasicResponse();
}
/**
* Perform a stateless HTTP Basic login attempt.
*
* @param string $field
* @return \Symfony\Component\HttpFoundation\Response|null
*/
public function onceBasic($field = 'email')
{
if ( ! $this->once($this->getBasicCredentials($this->getRequest(), $field)))
{
return $this->getBasicResponse();
}
}
/**
* Attempt to authenticate using basic authentication.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param string $field
* @return bool
*/
protected function attemptBasic(Request $request, $field)
{
if ( ! $request->getUser())
{
return false;
}
return $this->attempt($this->getBasicCredentials($request, $field));
}
/**
* Get the credential array for a HTTP Basic request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param string $field
* @return array
*/
protected function getBasicCredentials(Request $request, $field)
{
return [$field => $request->getUser(), 'password' => $request->getPassword()];
}
/**
* Get the response for basic authentication.
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function getBasicResponse()
{
$headers = ['WWW-Authenticate' => 'Basic'];
return new Response('Invalid credentials.', 401, $headers);
}
/**
* Attempt to authenticate a user using the given credentials.
*
* @param array $credentials
* @param bool $remember
* @param bool $login
* @return bool
*/
public function attempt(array $credentials = [], $remember = false, $login = true)
{
$this->fireAttemptEvent($credentials, $remember, $login);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials))
{
if ($login) $this->login($user, $remember);
{
return true;
}
}
return false;
}
/**
* Determine if the user matches the credentials.
*
* @param mixed $user
* @param array $credentials
* @return bool
*/
protected function hasValidCredentials($user, $credentials)
{
return ! is_null($user) && $this->provider->validateCredentials($user, $credentials);
}
/**
* Fire the attempt event with the arguments.
*
* @param array $credentials
* @param bool $remember
* @param bool $login
* @return void
*/
protected function fireAttemptEvent(array $credentials, $remember, $login)
{
if ($this->events)
{
$payload = [$credentials, $remember, $login];
$this->events->fire('auth.attempt', $payload);
}
}
/**
* Register an authentication attempt event listener.
*
* @param mixed $callback
* @return void
*/
public function attempting($callback)
{
if ($this->events)
{
$this->events->listen('auth.attempt', $callback);
}
}
/**
* Log a user into the application.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param bool $remember
* @return void
*/
public function login(UserContract $user, $remember = false)
{
$this->updateSession($user->getAuthIdentifier());
// If the user should be permanently "remembered" by the application we will
// queue a permanent cookie that contains the encrypted copy of the user
// identifier. We will then decrypt this later to retrieve the users.
if ($remember)
{
$this->createRememberTokenIfDoesntExist($user);
$this->queueRecallerCookie($user);
}
// If we have an event dispatcher instance set we will fire an event so that
// any listeners will hook into the authentication events and run actions
// based on the login and logout events fired from the guard instances.
$this->fireLoginEvent($user, $remember);
$this->setUser($user);
}
/**
* Fire the login event if the dispatcher is set.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param bool $remember
* @return void
*/
protected function fireLoginEvent($user, $remember = false)
{
if (isset($this->events))
{
$this->events->fire('auth.login', [$user, $remember]);
}
}
/**
* Update the session with the given ID.
*
* @param string $id
* @return void
*/
protected function updateSession($id)
{
$this->session->set($this->getName(), $id);
$this->session->migrate(true);
}
/**
* Log the given user ID into the application.
*
* @param mixed $id
* @param bool $remember
* @return \Illuminate\Contracts\Auth\Authenticatable
*/
public function loginUsingId($id, $remember = false)
{
$this->session->set($this->getName(), $id);
$this->login($user = $this->provider->retrieveById($id), $remember);
return $user;
}
/**
* Log the given user ID into the application without sessions or cookies.
*
* @param mixed $id
* @return bool
*/
public function onceUsingId($id)
{
if ( ! is_null($user = $this->provider->retrieveById($id)))
{
$this->setUser($user);
return true;
}
return false;
}
/**
* Queue the recaller cookie into the cookie jar.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return void
*/
protected function queueRecallerCookie(UserContract $user)
{
$value = $user->getAuthIdentifier().'|'.$user->getRememberToken();
$this->getCookieJar()->queue($this->createRecaller($value));
}
/**
* Create a "remember me" cookie for a given ID.
*
* @param string $value
* @return \Symfony\Component\HttpFoundation\Cookie
*/
protected function createRecaller($value)
{
return $this->getCookieJar()->forever($this->getRecallerName(), $value);
}
/**
* Log the user out of the application.
*
* @return void
*/
public function logout()
{
$user = $this->user();
// If we have an event dispatcher instance, we can fire off the logout event
// so any further processing can be done. This allows the developer to be
// listening for anytime a user signs out of this application manually.
$this->clearUserDataFromStorage();
if ( ! is_null($this->user))
{
$this->refreshRememberToken($user);
}
if (isset($this->events))
{
$this->events->fire('auth.logout', [$user]);
}
// Once we have fired the logout event we will clear the users out of memory
// so they are no longer available as the user is no longer considered as
// being signed into this application and should not be available here.
$this->user = null;
$this->loggedOut = true;
}
/**
* Remove the user data from the session and cookies.
*
* @return void
*/
protected function clearUserDataFromStorage()
{
$this->session->remove($this->getName());
$recaller = $this->getRecallerName();
$this->getCookieJar()->queue($this->getCookieJar()->forget($recaller));
}
/**
* Refresh the "remember me" token for the user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return void
*/
protected function refreshRememberToken(UserContract $user)
{
$user->setRememberToken($token = str_random(60));
$this->provider->updateRememberToken($user, $token);
}
/**
* Create a new "remember me" token for the user if one doesn't already exist.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return void
*/
protected function createRememberTokenIfDoesntExist(UserContract $user)
{
$rememberToken = $user->getRememberToken();
if (empty($rememberToken))
{
$this->refreshRememberToken($user);
}
}
/**
* Get the cookie creator instance used by the guard.
*
* @return \Illuminate\Contracts\Cookie\QueueingFactory
*
* @throws \RuntimeException
*/
public function getCookieJar()
{
if ( ! isset($this->cookie))
{
throw new RuntimeException("Cookie jar has not been set.");
}
return $this->cookie;
}
/**
* Set the cookie creator instance used by the guard.
*
* @param \Illuminate\Contracts\Cookie\QueueingFactory $cookie
* @return void
*/
public function setCookieJar(CookieJar $cookie)
{
$this->cookie = $cookie;
}
/**
* Get the event dispatcher instance.
*
* @return \Illuminate\Contracts\Events\Dispatcher
*/
public function getDispatcher()
{
return $this->events;
}
/**
* Set the event dispatcher instance.
*
* @param \Illuminate\Contracts\Events\Dispatcher
* @return void
*/
public function setDispatcher(Dispatcher $events)
{
$this->events = $events;
}
/**
* Get the session store used by the guard.
*
* @return \Illuminate\Session\Store
*/
public function getSession()
{
return $this->session;
}
/**
* Get the user provider used by the guard.
*
* @return \Illuminate\Contracts\Auth\UserProvider
*/
public function getProvider()
{
return $this->provider;
}
/**
* Set the user provider used by the guard.
*
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @return void
*/
public function setProvider(UserProvider $provider)
{
$this->provider = $provider;
}
/**
* Return the currently cached user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function getUser()
{
return $this->user;
}
/**
* Set the current user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return void
*/
public function setUser(UserContract $user)
{
$this->user = $user;
$this->loggedOut = false;
}
/**
* Get the current request instance.
*
* @return \Symfony\Component\HttpFoundation\Request
*/
public function getRequest()
{
return $this->request ?: Request::createFromGlobals();
}
/**
* Set the current request instance.
*
* @param \Symfony\Component\HttpFoundation\Request
* @return $this
*/
public function setRequest(Request $request)
{
$this->request = $request;
return $this;
}
/**
* Get the last user we attempted to authenticate.
*
* @return \Illuminate\Contracts\Auth\Authenticatable
*/
public function getLastAttempted()
{
return $this->lastAttempted;
}
/**
* Get a unique identifier for the auth session value.
*
* @return string
*/
public function getName()
{
return 'login_'.md5(get_class($this));
}
/**
* Get the name of the cookie used to store the "recaller".
*
* @return string
*/
public function getRecallerName()
{
return 'remember_'.md5(get_class($this));
}
/**
* Determine if the user was authenticated via "remember me" cookie.
*
* @return bool
*/
public function viaRemember()
{
return $this->viaRemember;
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Illuminate\Auth;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
/**
* These methods are typically the same across all guards.
*/
trait GuardHelpers
{
/**
* The currently authenticated user.
*
* @var \Illuminate\Contracts\Auth\Authenticatable
*/
protected $user;
/**
* The user provider implementation.
*
* @var \Illuminate\Contracts\Auth\UserProvider
*/
protected $provider;
/**
* Determine if the current user is authenticated.
*
* @return \Illuminate\Contracts\Auth\Authenticatable
*
* @throws \Illuminate\Auth\AuthenticationException
*/
public function authenticate()
{
if (! is_null($user = $this->user())) {
return $user;
}
throw new AuthenticationException($this);
}
/**
* Determine if the current user is authenticated.
*
* @return bool
*/
public function check()
{
return ! is_null($this->user());
}
/**
* Determine if the current user is a guest.
*
* @return bool
*/
public function guest()
{
return ! $this->check();
}
/**
* Get the ID for the currently authenticated user.
*
* @return int|null
*/
public function id()
{
if ($this->user()) {
return $this->user()->getAuthIdentifier();
}
}
/**
* Set the current user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return $this
*/
public function setUser(AuthenticatableContract $user)
{
$this->user = $user;
return $this;
}
}

View File

@@ -1,39 +1,40 @@
<?php namespace Illuminate\Auth\Middleware;
<?php
namespace Illuminate\Auth\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Routing\Middleware;
use Illuminate\Contracts\Auth\Factory as AuthFactory;
class AuthenticateWithBasicAuth implements Middleware {
class AuthenticateWithBasicAuth
{
/**
* The guard factory instance.
*
* @var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* The Guard implementation.
*
* @var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* @param Guard $auth
* @return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $this->auth->basic() ?: $next($request);
}
/**
* Create a new middleware instance.
*
* @param \Illuminate\Contracts\Auth\Factory $auth
* @return void
*/
public function __construct(AuthFactory $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
return $this->auth->guard($guard)->basic() ?: $next($request);
}
}

View File

@@ -1,15 +1,16 @@
<?php namespace Illuminate\Auth\Passwords;
<?php
trait CanResetPassword {
/**
* Get the e-mail address where password reset links are sent.
*
* @return string
*/
public function getEmailForPasswordReset()
{
return $this->email;
}
namespace Illuminate\Auth\Passwords;
trait CanResetPassword
{
/**
* Get the e-mail address where password reset links are sent.
*
* @return string
*/
public function getEmailForPasswordReset()
{
return $this->email;
}
}

View File

@@ -1,192 +1,183 @@
<?php namespace Illuminate\Auth\Passwords;
<?php
namespace Illuminate\Auth\Passwords;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class DatabaseTokenRepository implements TokenRepositoryInterface {
class DatabaseTokenRepository implements TokenRepositoryInterface
{
/**
* The database connection instance.
*
* @var \Illuminate\Database\ConnectionInterface
*/
protected $connection;
/**
* The database connection instance.
*
* @var \Illuminate\Database\ConnectionInterface
*/
protected $connection;
/**
* The token database table.
*
* @var string
*/
protected $table;
/**
* The token database table.
*
* @var string
*/
protected $table;
/**
* The hashing key.
*
* @var string
*/
protected $hashKey;
/**
* The hashing key.
*
* @var string
*/
protected $hashKey;
/**
* The number of seconds a token should last.
*
* @var int
*/
protected $expires;
/**
* The number of seconds a token should last.
*
* @var int
*/
protected $expires;
/**
* Create a new token repository instance.
*
* @param \Illuminate\Database\ConnectionInterface $connection
* @param string $table
* @param string $hashKey
* @param int $expires
* @return void
*/
public function __construct(ConnectionInterface $connection, $table, $hashKey, $expires = 60)
{
$this->table = $table;
$this->hashKey = $hashKey;
$this->expires = $expires * 60;
$this->connection = $connection;
}
/**
* Create a new token repository instance.
*
* @param \Illuminate\Database\ConnectionInterface $connection
* @param string $table
* @param string $hashKey
* @param int $expires
* @return void
*/
public function __construct(ConnectionInterface $connection, $table, $hashKey, $expires = 60)
{
$this->table = $table;
$this->hashKey = $hashKey;
$this->expires = $expires * 60;
$this->connection = $connection;
}
/**
* Create a new token record.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @return string
*/
public function create(CanResetPasswordContract $user)
{
$email = $user->getEmailForPasswordReset();
/**
* Create a new token record.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @return string
*/
public function create(CanResetPasswordContract $user)
{
$email = $user->getEmailForPasswordReset();
$this->deleteExisting($user);
$this->deleteExisting($user);
// We will create a new, random token for the user so that we can e-mail them
// a safe link to the password reset form. Then we will insert a record in
// the database so that we can verify the token within the actual reset.
$token = $this->createNewToken();
// We will create a new, random token for the user so that we can e-mail them
// a safe link to the password reset form. Then we will insert a record in
// the database so that we can verify the token within the actual reset.
$token = $this->createNewToken($user);
$this->getTable()->insert($this->getPayload($email, $token));
$this->getTable()->insert($this->getPayload($email, $token));
return $token;
}
return $token;
}
/**
* Delete all existing reset tokens from the database.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @return int
*/
protected function deleteExisting(CanResetPasswordContract $user)
{
return $this->getTable()->where('email', $user->getEmailForPasswordReset())->delete();
}
/**
* Delete all existing reset tokens from the database.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @return int
*/
protected function deleteExisting(CanResetPasswordContract $user)
{
return $this->getTable()->where('email', $user->getEmailForPasswordReset())->delete();
}
/**
* Build the record payload for the table.
*
* @param string $email
* @param string $token
* @return array
*/
protected function getPayload($email, $token)
{
return ['email' => $email, 'token' => $token, 'created_at' => new Carbon];
}
/**
* Build the record payload for the table.
*
* @param string $email
* @param string $token
* @return array
*/
protected function getPayload($email, $token)
{
return ['email' => $email, 'token' => $token, 'created_at' => new Carbon];
}
/**
* Determine if a token record exists and is valid.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $token
* @return bool
*/
public function exists(CanResetPasswordContract $user, $token)
{
$email = $user->getEmailForPasswordReset();
/**
* Determine if a token record exists and is valid.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $token
* @return bool
*/
public function exists(CanResetPasswordContract $user, $token)
{
$email = $user->getEmailForPasswordReset();
$token = (array) $this->getTable()->where('email', $email)->where('token', $token)->first();
$token = (array) $this->getTable()->where('email', $email)->where('token', $token)->first();
return $token && ! $this->tokenExpired($token);
}
return $token && ! $this->tokenExpired($token);
}
/**
* Determine if the token has expired.
*
* @param array $token
* @return bool
*/
protected function tokenExpired($token)
{
$expiresAt = Carbon::parse($token['created_at'])->addSeconds($this->expires);
/**
* Determine if the token has expired.
*
* @param array $token
* @return bool
*/
protected function tokenExpired($token)
{
$expirationTime = strtotime($token['created_at']) + $this->expires;
return $expiresAt->isPast();
}
return $expirationTime < $this->getCurrentTime();
}
/**
* Delete a token record by token.
*
* @param string $token
* @return void
*/
public function delete($token)
{
$this->getTable()->where('token', $token)->delete();
}
/**
* Get the current UNIX timestamp.
*
* @return int
*/
protected function getCurrentTime()
{
return time();
}
/**
* Delete expired tokens.
*
* @return void
*/
public function deleteExpired()
{
$expiredAt = Carbon::now()->subSeconds($this->expires);
/**
* Delete a token record by token.
*
* @param string $token
* @return void
*/
public function delete($token)
{
$this->getTable()->where('token', $token)->delete();
}
$this->getTable()->where('created_at', '<', $expiredAt)->delete();
}
/**
* Delete expired tokens.
*
* @return void
*/
public function deleteExpired()
{
$expiredAt = Carbon::now()->subSeconds($this->expires);
/**
* Create a new token for the user.
*
* @return string
*/
public function createNewToken()
{
return hash_hmac('sha256', Str::random(40), $this->hashKey);
}
$this->getTable()->where('created_at', '<', $expiredAt)->delete();
}
/**
* Create a new token for the user.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @return string
*/
public function createNewToken(CanResetPasswordContract $user)
{
return hash_hmac('sha256', str_random(40), $this->hashKey);
}
/**
* Begin a new database query against the table.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function getTable()
{
return $this->connection->table($this->table);
}
/**
* Get the database connection instance.
*
* @return \Illuminate\Database\ConnectionInterface
*/
public function getConnection()
{
return $this->connection;
}
/**
* Begin a new database query against the table.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function getTable()
{
return $this->connection->table($this->table);
}
/**
* Get the database connection instance.
*
* @return \Illuminate\Database\ConnectionInterface
*/
public function getConnection()
{
return $this->connection;
}
}

View File

@@ -1,260 +1,287 @@
<?php namespace Illuminate\Auth\Passwords;
<?php
namespace Illuminate\Auth\Passwords;
use Closure;
use Illuminate\Support\Arr;
use UnexpectedValueException;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Contracts\Auth\PasswordBroker as PasswordBrokerContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class PasswordBroker implements PasswordBrokerContract {
class PasswordBroker implements PasswordBrokerContract
{
/**
* The password token repository.
*
* @var \Illuminate\Auth\Passwords\TokenRepositoryInterface
*/
protected $tokens;
/**
* The password token repository.
*
* @var \Illuminate\Auth\Passwords\TokenRepositoryInterface
*/
protected $tokens;
/**
* The user provider implementation.
*
* @var \Illuminate\Contracts\Auth\UserProvider
*/
protected $users;
/**
* The user provider implementation.
*
* @var \Illuminate\Contracts\Auth\UserProvider
*/
protected $users;
/**
* The mailer instance.
*
* @var \Illuminate\Contracts\Mail\Mailer
*/
protected $mailer;
/**
* The mailer instance.
*
* @var \Illuminate\Contracts\Mail\Mailer
*/
protected $mailer;
/**
* The view of the password reset link e-mail.
*
* @var string
*/
protected $emailView;
/**
* The view of the password reset link e-mail.
*
* @var string
*/
protected $emailView;
/**
* The custom password validator callback.
*
* @var \Closure
*/
protected $passwordValidator;
/**
* The custom password validator callback.
*
* @var \Closure
*/
protected $passwordValidator;
/**
* Create a new password broker instance.
*
* @param \Illuminate\Auth\Passwords\TokenRepositoryInterface $tokens
* @param \Illuminate\Contracts\Auth\UserProvider $users
* @param \Illuminate\Contracts\Mail\Mailer $mailer
* @param string $emailView
* @return void
*/
public function __construct(TokenRepositoryInterface $tokens,
/**
* Create a new password broker instance.
*
* @param \Illuminate\Auth\Passwords\TokenRepositoryInterface $tokens
* @param \Illuminate\Contracts\Auth\UserProvider $users
* @param \Illuminate\Contracts\Mail\Mailer $mailer
* @param string $emailView
* @return void
*/
public function __construct(TokenRepositoryInterface $tokens,
UserProvider $users,
MailerContract $mailer,
$emailView)
{
$this->users = $users;
$this->mailer = $mailer;
$this->tokens = $tokens;
$this->emailView = $emailView;
}
{
$this->users = $users;
$this->mailer = $mailer;
$this->tokens = $tokens;
$this->emailView = $emailView;
}
/**
* Send a password reset link to a user.
*
* @param array $credentials
* @param \Closure|null $callback
* @return string
*/
public function sendResetLink(array $credentials, Closure $callback = null)
{
// First we will check to see if we found a user at the given credentials and
// if we did not we will redirect back to this current URI with a piece of
// "flash" data in the session to indicate to the developers the errors.
$user = $this->getUser($credentials);
/**
* Send a password reset link to a user.
*
* @param array $credentials
* @param \Closure|null $callback
* @return string
*/
public function sendResetLink(array $credentials, Closure $callback = null)
{
// First we will check to see if we found a user at the given credentials and
// if we did not we will redirect back to this current URI with a piece of
// "flash" data in the session to indicate to the developers the errors.
$user = $this->getUser($credentials);
if (is_null($user))
{
return PasswordBrokerContract::INVALID_USER;
}
if (is_null($user)) {
return PasswordBrokerContract::INVALID_USER;
}
// Once we have the reset token, we are ready to send the message out to this
// user with a link to reset their password. We will then redirect back to
// the current URI having nothing set in the session to indicate errors.
$token = $this->tokens->create($user);
// Once we have the reset token, we are ready to send the message out to this
// user with a link to reset their password. We will then redirect back to
// the current URI having nothing set in the session to indicate errors.
$token = $this->tokens->create($user);
$this->emailResetLink($user, $token, $callback);
$this->emailResetLink($user, $token, $callback);
return PasswordBrokerContract::RESET_LINK_SENT;
}
return PasswordBrokerContract::RESET_LINK_SENT;
}
/**
* Send the password reset link via e-mail.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $token
* @param \Closure|null $callback
* @return int
*/
public function emailResetLink(CanResetPasswordContract $user, $token, Closure $callback = null)
{
// We will use the reminder view that was given to the broker to display the
// password reminder e-mail. We'll pass a "token" variable into the views
// so that it may be displayed for an user to click for password reset.
$view = $this->emailView;
/**
* Send the password reset link via e-mail.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $token
* @param \Closure|null $callback
* @return int
*/
public function emailResetLink(CanResetPasswordContract $user, $token, Closure $callback = null)
{
// We will use the reminder view that was given to the broker to display the
// password reminder e-mail. We'll pass a "token" variable into the views
// so that it may be displayed for an user to click for password reset.
$view = $this->emailView;
return $this->mailer->send($view, compact('token', 'user'), function($m) use ($user, $token, $callback)
{
$m->to($user->getEmailForPasswordReset());
return $this->mailer->send($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
$m->to($user->getEmailForPasswordReset());
if ( ! is_null($callback))
{
call_user_func($callback, $m, $user, $token);
}
});
}
if (! is_null($callback)) {
call_user_func($callback, $m, $user, $token);
}
});
}
/**
* Reset the password for the given token.
*
* @param array $credentials
* @param \Closure $callback
* @return mixed
*/
public function reset(array $credentials, Closure $callback)
{
// If the responses from the validate method is not a user instance, we will
// assume that it is a redirect and simply return it from this method and
// the user is properly redirected having an error message on the post.
$user = $this->validateReset($credentials);
/**
* Reset the password for the given token.
*
* @param array $credentials
* @param \Closure $callback
* @return mixed
*/
public function reset(array $credentials, Closure $callback)
{
// If the responses from the validate method is not a user instance, we will
// assume that it is a redirect and simply return it from this method and
// the user is properly redirected having an error message on the post.
$user = $this->validateReset($credentials);
if ( ! $user instanceof CanResetPasswordContract)
{
return $user;
}
if (! $user instanceof CanResetPasswordContract) {
return $user;
}
$pass = $credentials['password'];
$pass = $credentials['password'];
// Once we have called this callback, we will remove this token row from the
// table and return the response from this callback so the user gets sent
// to the destination given by the developers from the callback return.
call_user_func($callback, $user, $pass);
// Once we have called this callback, we will remove this token row from the
// table and return the response from this callback so the user gets sent
// to the destination given by the developers from the callback return.
call_user_func($callback, $user, $pass);
$this->tokens->delete($credentials['token']);
$this->tokens->delete($credentials['token']);
return PasswordBrokerContract::PASSWORD_RESET;
}
return PasswordBrokerContract::PASSWORD_RESET;
}
/**
* Validate a password reset for the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\CanResetPassword
*/
protected function validateReset(array $credentials)
{
if (is_null($user = $this->getUser($credentials)))
{
return PasswordBrokerContract::INVALID_USER;
}
/**
* Validate a password reset for the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\CanResetPassword
*/
protected function validateReset(array $credentials)
{
if (is_null($user = $this->getUser($credentials))) {
return PasswordBrokerContract::INVALID_USER;
}
if ( ! $this->validateNewPassword($credentials))
{
return PasswordBrokerContract::INVALID_PASSWORD;
}
if (! $this->validateNewPassword($credentials)) {
return PasswordBrokerContract::INVALID_PASSWORD;
}
if ( ! $this->tokens->exists($user, $credentials['token']))
{
return PasswordBrokerContract::INVALID_TOKEN;
}
if (! $this->tokens->exists($user, $credentials['token'])) {
return PasswordBrokerContract::INVALID_TOKEN;
}
return $user;
}
return $user;
}
/**
* Set a custom password validator.
*
* @param \Closure $callback
* @return void
*/
public function validator(Closure $callback)
{
$this->passwordValidator = $callback;
}
/**
* Set a custom password validator.
*
* @param \Closure $callback
* @return void
*/
public function validator(Closure $callback)
{
$this->passwordValidator = $callback;
}
/**
* Determine if the passwords match for the request.
*
* @param array $credentials
* @return bool
*/
public function validateNewPassword(array $credentials)
{
list($password, $confirm) = [
$credentials['password'],
$credentials['password_confirmation'],
];
/**
* Determine if the passwords match for the request.
*
* @param array $credentials
* @return bool
*/
public function validateNewPassword(array $credentials)
{
list($password, $confirm) = [
$credentials['password'],
$credentials['password_confirmation'],
];
if (isset($this->passwordValidator))
{
return call_user_func(
$this->passwordValidator, $credentials) && $password === $confirm;
}
if (isset($this->passwordValidator)) {
return call_user_func(
$this->passwordValidator, $credentials) && $password === $confirm;
}
return $this->validatePasswordWithDefaults($credentials);
}
return $this->validatePasswordWithDefaults($credentials);
}
/**
* Determine if the passwords are valid for the request.
*
* @param array $credentials
* @return bool
*/
protected function validatePasswordWithDefaults(array $credentials)
{
list($password, $confirm) = [
$credentials['password'],
$credentials['password_confirmation'],
];
/**
* Determine if the passwords are valid for the request.
*
* @param array $credentials
* @return bool
*/
protected function validatePasswordWithDefaults(array $credentials)
{
list($password, $confirm) = [
$credentials['password'],
$credentials['password_confirmation'],
];
return $password === $confirm && mb_strlen($password) >= 6;
}
return $password === $confirm && mb_strlen($password) >= 6;
}
/**
* Get the user for the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\CanResetPassword
*
* @throws \UnexpectedValueException
*/
public function getUser(array $credentials)
{
$credentials = array_except($credentials, ['token']);
/**
* Get the user for the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\CanResetPassword
*
* @throws \UnexpectedValueException
*/
public function getUser(array $credentials)
{
$credentials = Arr::except($credentials, ['token']);
$user = $this->users->retrieveByCredentials($credentials);
$user = $this->users->retrieveByCredentials($credentials);
if ($user && ! $user instanceof CanResetPasswordContract)
{
throw new UnexpectedValueException("User must implement CanResetPassword interface.");
}
if ($user && ! $user instanceof CanResetPasswordContract) {
throw new UnexpectedValueException('User must implement CanResetPassword interface.');
}
return $user;
}
return $user;
}
/**
* Get the password reset token repository implementation.
*
* @return \Illuminate\Auth\Passwords\TokenRepositoryInterface
*/
protected function getRepository()
{
return $this->tokens;
}
/**
* Create a new password reset token for the given user.
*
* @param CanResetPasswordContract $user
* @return string
*/
public function createToken(CanResetPasswordContract $user)
{
return $this->tokens->create($user);
}
/**
* Delete the given password reset token.
*
* @param string $token
* @return void
*/
public function deleteToken($token)
{
$this->tokens->delete($token);
}
/**
* Validate the given password reset token.
*
* @param CanResetPasswordContract $user
* @param string $token
* @return bool
*/
public function tokenExists(CanResetPasswordContract $user, $token)
{
return $this->tokens->exists($user, $token);
}
/**
* Get the password reset token repository implementation.
*
* @return \Illuminate\Auth\Passwords\TokenRepositoryInterface
*/
public function getRepository()
{
return $this->tokens;
}
}

View File

@@ -0,0 +1,145 @@
<?php
namespace Illuminate\Auth\Passwords;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Illuminate\Contracts\Auth\PasswordBrokerFactory as FactoryContract;
class PasswordBrokerManager implements FactoryContract
{
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;
/**
* The array of created "drivers".
*
* @var array
*/
protected $brokers = [];
/**
* Create a new PasswordBroker manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Attempt to get the broker from the local cache.
*
* @param string $name
* @return \Illuminate\Contracts\Auth\PasswordBroker
*/
public function broker($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return isset($this->brokers[$name])
? $this->brokers[$name]
: $this->brokers[$name] = $this->resolve($name);
}
/**
* Resolve the given broker.
*
* @param string $name
* @return \Illuminate\Contracts\Auth\PasswordBroker
*
* @throws \InvalidArgumentException
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
if (is_null($config)) {
throw new InvalidArgumentException("Password resetter [{$name}] is not defined.");
}
// The password broker uses a token repository to validate tokens and send user
// password e-mails, as well as validating that password reset process as an
// aggregate service of sorts providing a convenient interface for resets.
return new PasswordBroker(
$this->createTokenRepository($config),
$this->app['auth']->createUserProvider($config['provider']),
$this->app['mailer'],
$config['email']
);
}
/**
* Create a token repository instance based on the given configuration.
*
* @param array $config
* @return \Illuminate\Auth\Passwords\TokenRepositoryInterface
*/
protected function createTokenRepository(array $config)
{
$key = $this->app['config']['app.key'];
if (Str::startsWith($key, 'base64:')) {
$key = base64_decode(substr($key, 7));
}
$connection = isset($config['connection']) ? $config['connection'] : null;
return new DatabaseTokenRepository(
$this->app['db']->connection($connection),
$config['table'],
$key,
$config['expire']
);
}
/**
* Get the password broker configuration.
*
* @param string $name
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']["auth.passwords.{$name}"];
}
/**
* Get the default password broker name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['auth.defaults.passwords'];
}
/**
* Set the default password broker name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['auth.defaults.passwords'] = $name;
}
/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return call_user_func_array([$this->broker(), $method], $parameters);
}
}

View File

@@ -1,88 +1,51 @@
<?php namespace Illuminate\Auth\Passwords;
<?php
namespace Illuminate\Auth\Passwords;
use Illuminate\Support\ServiceProvider;
use Illuminate\Auth\Passwords\DatabaseTokenRepository as DbRepository;
class PasswordResetServiceProvider extends ServiceProvider {
class PasswordResetServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerPasswordBroker();
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerPasswordBroker();
/**
* Register the password broker instance.
*
* @return void
*/
protected function registerPasswordBroker()
{
$this->app->singleton('auth.password', function ($app) {
return new PasswordBrokerManager($app);
});
$this->registerTokenRepository();
}
/**
* Register the password broker instance.
*
* @return void
*/
protected function registerPasswordBroker()
{
$this->app->singleton('auth.password', function($app)
{
// The password token repository is responsible for storing the email addresses
// and password reset tokens. It will be used to verify the tokens are valid
// for the given e-mail addresses. We will resolve an implementation here.
$tokens = $app['auth.password.tokens'];
$users = $app['auth']->driver()->getProvider();
$view = $app['config']['auth.password.email'];
// The password broker uses a token repository to validate tokens and send user
// password e-mails, as well as validating that password reset process as an
// aggregate service of sorts providing a convenient interface for resets.
return new PasswordBroker(
$tokens, $users, $app['mailer'], $view
);
});
}
/**
* Register the token repository implementation.
*
* @return void
*/
protected function registerTokenRepository()
{
$this->app->singleton('auth.password.tokens', function($app)
{
$connection = $app['db']->connection();
// The database token repository is an implementation of the token repository
// interface, and is responsible for the actual storing of auth tokens and
// their e-mail addresses. We will inject this table and hash key to it.
$table = $app['config']['auth.password.table'];
$key = $app['config']['app.key'];
$expire = $app['config']->get('auth.password.expire', 60);
return new DbRepository($connection, $table, $key, $expire);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['auth.password', 'auth.password.tokens'];
}
$this->app->bind('auth.password.broker', function ($app) {
return $app->make('auth.password')->broker();
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['auth.password', 'auth.password.broker'];
}
}

View File

@@ -1,39 +1,40 @@
<?php namespace Illuminate\Auth\Passwords;
<?php
namespace Illuminate\Auth\Passwords;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
interface TokenRepositoryInterface {
interface TokenRepositoryInterface
{
/**
* Create a new token.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @return string
*/
public function create(CanResetPasswordContract $user);
/**
* Create a new token.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @return string
*/
public function create(CanResetPasswordContract $user);
/**
* Determine if a token record exists and is valid.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $token
* @return bool
*/
public function exists(CanResetPasswordContract $user, $token);
/**
* Determine if a token record exists and is valid.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $token
* @return bool
*/
public function exists(CanResetPasswordContract $user, $token);
/**
* Delete a token record.
*
* @param string $token
* @return void
*/
public function delete($token);
/**
* Delete expired tokens.
*
* @return void
*/
public function deleteExpired();
/**
* Delete a token record.
*
* @param string $token
* @return void
*/
public function delete($token);
/**
* Delete expired tokens.
*
* @return void
*/
public function deleteExpired();
}

View File

@@ -0,0 +1,82 @@
<?php
namespace Illuminate\Auth;
use Illuminate\Http\Request;
use Illuminate\Contracts\Auth\Guard;
class RequestGuard implements Guard
{
use GuardHelpers;
/**
* The guard callback.
*
* @var callable
*/
protected $callback;
/**
* The request instance.
*
* @var \Illuminate\Http\Request
*/
protected $request;
/**
* Create a new authentication guard.
*
* @param callable $callback
* @param \Symfony\Component\HttpFoundation\Request $request
* @return void
*/
public function __construct(callable $callback,
Request $request)
{
$this->request = $request;
$this->callback = $callback;
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
// If we've already retrieved the user for the current request we can just
// return it back immediately. We do not want to fetch the user data on
// every call to this method because that would be tremendously slow.
if (! is_null($this->user)) {
return $this->user;
}
return $this->user = call_user_func($this->callback, $this->request);
}
/**
* Validate a user's credentials.
*
* @param array $credentials
* @return bool
*/
public function validate(array $credentials = [])
{
return ! is_null((new static(
$this->callback, $credentials['request']
))->user());
}
/**
* Set the current request instance.
*
* @param \Illuminate\Http\Request $request
* @return $this
*/
public function setRequest(Request $request)
{
$this->request = $request;
return $this;
}
}

View File

@@ -0,0 +1,788 @@
<?php
namespace Illuminate\Auth;
use RuntimeException;
use Illuminate\Support\Str;
use Illuminate\Http\Response;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Auth\StatefulGuard;
use Symfony\Component\HttpFoundation\Request;
use Illuminate\Contracts\Auth\SupportsBasicAuth;
use Illuminate\Contracts\Cookie\QueueingFactory as CookieJar;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
class SessionGuard implements StatefulGuard, SupportsBasicAuth
{
use GuardHelpers;
/**
* The name of the Guard. Typically "session".
*
* Corresponds to driver name in authentication configuration.
*
* @var string
*/
protected $name;
/**
* The user we last attempted to retrieve.
*
* @var \Illuminate\Contracts\Auth\Authenticatable
*/
protected $lastAttempted;
/**
* Indicates if the user was authenticated via a recaller cookie.
*
* @var bool
*/
protected $viaRemember = false;
/**
* The session used by the guard.
*
* @var \Symfony\Component\HttpFoundation\Session\SessionInterface
*/
protected $session;
/**
* The Illuminate cookie creator service.
*
* @var \Illuminate\Contracts\Cookie\QueueingFactory
*/
protected $cookie;
/**
* The request instance.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* The event dispatcher instance.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;
/**
* Indicates if the logout method has been called.
*
* @var bool
*/
protected $loggedOut = false;
/**
* Indicates if a token user retrieval has been attempted.
*
* @var bool
*/
protected $tokenRetrievalAttempted = false;
/**
* Create a new authentication guard.
*
* @param string $name
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session
* @param \Symfony\Component\HttpFoundation\Request $request
* @return void
*/
public function __construct($name,
UserProvider $provider,
SessionInterface $session,
Request $request = null)
{
$this->name = $name;
$this->session = $session;
$this->request = $request;
$this->provider = $provider;
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
if ($this->loggedOut) {
return;
}
// If we've already retrieved the user for the current request we can just
// return it back immediately. We do not want to fetch the user data on
// every call to this method because that would be tremendously slow.
if (! is_null($this->user)) {
return $this->user;
}
$id = $this->session->get($this->getName());
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null;
if (! is_null($id)) {
$user = $this->provider->retrieveById($id);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();
if (is_null($user) && ! is_null($recaller)) {
$user = $this->getUserByRecaller($recaller);
if ($user) {
$this->updateSession($user->getAuthIdentifier());
$this->fireLoginEvent($user, true);
}
}
return $this->user = $user;
}
/**
* Get the ID for the currently authenticated user.
*
* @return int|null
*/
public function id()
{
if ($this->loggedOut) {
return;
}
$id = $this->session->get($this->getName());
if (is_null($id) && $this->user()) {
$id = $this->user()->getAuthIdentifier();
}
return $id;
}
/**
* Pull a user from the repository by its recaller ID.
*
* @param string $recaller
* @return mixed
*/
protected function getUserByRecaller($recaller)
{
if ($this->validRecaller($recaller) && ! $this->tokenRetrievalAttempted) {
$this->tokenRetrievalAttempted = true;
list($id, $token) = explode('|', $recaller, 2);
$this->viaRemember = ! is_null($user = $this->provider->retrieveByToken($id, $token));
return $user;
}
}
/**
* Get the decrypted recaller cookie for the request.
*
* @return string|null
*/
protected function getRecaller()
{
return $this->request->cookies->get($this->getRecallerName());
}
/**
* Get the user ID from the recaller cookie.
*
* @return string|null
*/
protected function getRecallerId()
{
if ($this->validRecaller($recaller = $this->getRecaller())) {
return head(explode('|', $recaller));
}
}
/**
* Determine if the recaller cookie is in a valid format.
*
* @param mixed $recaller
* @return bool
*/
protected function validRecaller($recaller)
{
if (! is_string($recaller) || ! Str::contains($recaller, '|')) {
return false;
}
$segments = explode('|', $recaller);
return count($segments) == 2 && trim($segments[0]) !== '' && trim($segments[1]) !== '';
}
/**
* Log a user into the application without sessions or cookies.
*
* @param array $credentials
* @return bool
*/
public function once(array $credentials = [])
{
if ($this->validate($credentials)) {
$this->setUser($this->lastAttempted);
return true;
}
return false;
}
/**
* Validate a user's credentials.
*
* @param array $credentials
* @return bool
*/
public function validate(array $credentials = [])
{
return $this->attempt($credentials, false, false);
}
/**
* Attempt to authenticate using HTTP Basic Auth.
*
* @param string $field
* @param array $extraConditions
* @return \Symfony\Component\HttpFoundation\Response|null
*/
public function basic($field = 'email', $extraConditions = [])
{
if ($this->check()) {
return;
}
// If a username is set on the HTTP basic request, we will return out without
// interrupting the request lifecycle. Otherwise, we'll need to generate a
// request indicating that the given credentials were invalid for login.
if ($this->attemptBasic($this->getRequest(), $field, $extraConditions)) {
return;
}
return $this->getBasicResponse();
}
/**
* Perform a stateless HTTP Basic login attempt.
*
* @param string $field
* @param array $extraConditions
* @return \Symfony\Component\HttpFoundation\Response|null
*/
public function onceBasic($field = 'email', $extraConditions = [])
{
$credentials = $this->getBasicCredentials($this->getRequest(), $field);
if (! $this->once(array_merge($credentials, $extraConditions))) {
return $this->getBasicResponse();
}
}
/**
* Attempt to authenticate using basic authentication.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param string $field
* @param array $extraConditions
* @return bool
*/
protected function attemptBasic(Request $request, $field, $extraConditions = [])
{
if (! $request->getUser()) {
return false;
}
$credentials = $this->getBasicCredentials($request, $field);
return $this->attempt(array_merge($credentials, $extraConditions));
}
/**
* Get the credential array for a HTTP Basic request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param string $field
* @return array
*/
protected function getBasicCredentials(Request $request, $field)
{
return [$field => $request->getUser(), 'password' => $request->getPassword()];
}
/**
* Get the response for basic authentication.
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function getBasicResponse()
{
$headers = ['WWW-Authenticate' => 'Basic'];
return new Response('Invalid credentials.', 401, $headers);
}
/**
* Attempt to authenticate a user using the given credentials.
*
* @param array $credentials
* @param bool $remember
* @param bool $login
* @return bool
*/
public function attempt(array $credentials = [], $remember = false, $login = true)
{
$this->fireAttemptEvent($credentials, $remember, $login);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials)) {
if ($login) {
$this->login($user, $remember);
}
return true;
}
// If the authentication attempt fails we will fire an event so that the user
// may be notified of any suspicious attempts to access their account from
// an unrecognized user. A developer may listen to this event as needed.
if ($login) {
$this->fireFailedEvent($user, $credentials);
}
return false;
}
/**
* Determine if the user matches the credentials.
*
* @param mixed $user
* @param array $credentials
* @return bool
*/
protected function hasValidCredentials($user, $credentials)
{
return ! is_null($user) && $this->provider->validateCredentials($user, $credentials);
}
/**
* Fire the attempt event with the arguments.
*
* @param array $credentials
* @param bool $remember
* @param bool $login
* @return void
*/
protected function fireAttemptEvent(array $credentials, $remember, $login)
{
if (isset($this->events)) {
$this->events->fire(new Events\Attempting(
$credentials, $remember, $login
));
}
}
/**
* Fire the failed authentication attempt event with the given arguments.
*
* @param \Illuminate\Contracts\Auth\Authenticatable|null $user
* @param array $credentials
* @return void
*/
protected function fireFailedEvent($user, array $credentials)
{
if (isset($this->events)) {
$this->events->fire(new Events\Failed($user, $credentials));
}
}
/**
* Register an authentication attempt event listener.
*
* @param mixed $callback
* @return void
*/
public function attempting($callback)
{
if (isset($this->events)) {
$this->events->listen(Events\Attempting::class, $callback);
}
}
/**
* Log a user into the application.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param bool $remember
* @return void
*/
public function login(AuthenticatableContract $user, $remember = false)
{
$this->updateSession($user->getAuthIdentifier());
// If the user should be permanently "remembered" by the application we will
// queue a permanent cookie that contains the encrypted copy of the user
// identifier. We will then decrypt this later to retrieve the users.
if ($remember) {
$this->createRememberTokenIfDoesntExist($user);
$this->queueRecallerCookie($user);
}
// If we have an event dispatcher instance set we will fire an event so that
// any listeners will hook into the authentication events and run actions
// based on the login and logout events fired from the guard instances.
$this->fireLoginEvent($user, $remember);
$this->setUser($user);
}
/**
* Fire the login event if the dispatcher is set.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param bool $remember
* @return void
*/
protected function fireLoginEvent($user, $remember = false)
{
if (isset($this->events)) {
$this->events->fire(new Events\Login($user, $remember));
}
}
/**
* Update the session with the given ID.
*
* @param string $id
* @return void
*/
protected function updateSession($id)
{
$this->session->set($this->getName(), $id);
$this->session->migrate(true);
}
/**
* Log the given user ID into the application.
*
* @param mixed $id
* @param bool $remember
* @return \Illuminate\Contracts\Auth\Authenticatable
*/
public function loginUsingId($id, $remember = false)
{
$user = $this->provider->retrieveById($id);
if (! is_null($user)) {
$this->login($user, $remember);
return $user;
}
return false;
}
/**
* Log the given user ID into the application without sessions or cookies.
*
* @param mixed $id
* @return bool
*/
public function onceUsingId($id)
{
$user = $this->provider->retrieveById($id);
if (! is_null($user)) {
$this->setUser($user);
return true;
}
return false;
}
/**
* Queue the recaller cookie into the cookie jar.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return void
*/
protected function queueRecallerCookie(AuthenticatableContract $user)
{
$value = $user->getAuthIdentifier().'|'.$user->getRememberToken();
$this->getCookieJar()->queue($this->createRecaller($value));
}
/**
* Create a "remember me" cookie for a given ID.
*
* @param string $value
* @return \Symfony\Component\HttpFoundation\Cookie
*/
protected function createRecaller($value)
{
return $this->getCookieJar()->forever($this->getRecallerName(), $value);
}
/**
* Log the user out of the application.
*
* @return void
*/
public function logout()
{
$user = $this->user();
// If we have an event dispatcher instance, we can fire off the logout event
// so any further processing can be done. This allows the developer to be
// listening for anytime a user signs out of this application manually.
$this->clearUserDataFromStorage();
if (! is_null($this->user)) {
$this->refreshRememberToken($user);
}
if (isset($this->events)) {
$this->events->fire(new Events\Logout($user));
}
// Once we have fired the logout event we will clear the users out of memory
// so they are no longer available as the user is no longer considered as
// being signed into this application and should not be available here.
$this->user = null;
$this->loggedOut = true;
}
/**
* Remove the user data from the session and cookies.
*
* @return void
*/
protected function clearUserDataFromStorage()
{
$this->session->remove($this->getName());
if (! is_null($this->getRecaller())) {
$recaller = $this->getRecallerName();
$this->getCookieJar()->queue($this->getCookieJar()->forget($recaller));
}
}
/**
* Refresh the "remember me" token for the user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return void
*/
protected function refreshRememberToken(AuthenticatableContract $user)
{
$user->setRememberToken($token = Str::random(60));
$this->provider->updateRememberToken($user, $token);
}
/**
* Create a new "remember me" token for the user if one doesn't already exist.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return void
*/
protected function createRememberTokenIfDoesntExist(AuthenticatableContract $user)
{
if (empty($user->getRememberToken())) {
$this->refreshRememberToken($user);
}
}
/**
* Get the cookie creator instance used by the guard.
*
* @return \Illuminate\Contracts\Cookie\QueueingFactory
*
* @throws \RuntimeException
*/
public function getCookieJar()
{
if (! isset($this->cookie)) {
throw new RuntimeException('Cookie jar has not been set.');
}
return $this->cookie;
}
/**
* Set the cookie creator instance used by the guard.
*
* @param \Illuminate\Contracts\Cookie\QueueingFactory $cookie
* @return void
*/
public function setCookieJar(CookieJar $cookie)
{
$this->cookie = $cookie;
}
/**
* Get the event dispatcher instance.
*
* @return \Illuminate\Contracts\Events\Dispatcher
*/
public function getDispatcher()
{
return $this->events;
}
/**
* Set the event dispatcher instance.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function setDispatcher(Dispatcher $events)
{
$this->events = $events;
}
/**
* Get the session store used by the guard.
*
* @return \Illuminate\Session\Store
*/
public function getSession()
{
return $this->session;
}
/**
* Get the user provider used by the guard.
*
* @return \Illuminate\Contracts\Auth\UserProvider
*/
public function getProvider()
{
return $this->provider;
}
/**
* Set the user provider used by the guard.
*
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @return void
*/
public function setProvider(UserProvider $provider)
{
$this->provider = $provider;
}
/**
* Return the currently cached user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function getUser()
{
return $this->user;
}
/**
* Set the current user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return $this
*/
public function setUser(AuthenticatableContract $user)
{
$this->user = $user;
$this->loggedOut = false;
return $this;
}
/**
* Get the current request instance.
*
* @return \Symfony\Component\HttpFoundation\Request
*/
public function getRequest()
{
return $this->request ?: Request::createFromGlobals();
}
/**
* Set the current request instance.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @return $this
*/
public function setRequest(Request $request)
{
$this->request = $request;
return $this;
}
/**
* Get the last user we attempted to authenticate.
*
* @return \Illuminate\Contracts\Auth\Authenticatable
*/
public function getLastAttempted()
{
return $this->lastAttempted;
}
/**
* Get a unique identifier for the auth session value.
*
* @return string
*/
public function getName()
{
return 'login_'.$this->name.'_'.sha1(static::class);
}
/**
* Get the name of the cookie used to store the "recaller".
*
* @return string
*/
public function getRecallerName()
{
return 'remember_'.$this->name.'_'.sha1(static::class);
}
/**
* Determine if the user was authenticated via "remember me" cookie.
*
* @return bool
*/
public function viaRemember()
{
return $this->viaRemember;
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace Illuminate\Auth;
use Illuminate\Http\Request;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
class TokenGuard implements Guard
{
use GuardHelpers;
/**
* The request instance.
*
* @var \Illuminate\Http\Request
*/
protected $request;
/**
* The name of the field on the request containing the API token.
*
* @var string
*/
protected $inputKey;
/**
* The name of the token "column" in persistent storage.
*
* @var string
*/
protected $storageKey;
/**
* Create a new authentication guard.
*
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @param \Illuminate\Http\Request $request
* @return void
*/
public function __construct(UserProvider $provider, Request $request)
{
$this->request = $request;
$this->provider = $provider;
$this->inputKey = 'api_token';
$this->storageKey = 'api_token';
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
// If we've already retrieved the user for the current request we can just
// return it back immediately. We do not want to fetch the user data on
// every call to this method because that would be tremendously slow.
if (! is_null($this->user)) {
return $this->user;
}
$user = null;
$token = $this->getTokenForRequest();
if (! empty($token)) {
$user = $this->provider->retrieveByCredentials(
[$this->storageKey => $token]
);
}
return $this->user = $user;
}
/**
* Get the token for the current request.
*
* @return string
*/
protected function getTokenForRequest()
{
$token = $this->request->input($this->inputKey);
if (empty($token)) {
$token = $this->request->bearerToken();
}
if (empty($token)) {
$token = $this->request->getPassword();
}
return $token;
}
/**
* Validate a user's credentials.
*
* @param array $credentials
* @return bool
*/
public function validate(array $credentials = [])
{
$credentials = [$this->storageKey => $credentials[$this->inputKey]];
if ($this->provider->retrieveByCredentials($credentials)) {
return true;
}
return false;
}
/**
* Set the current request instance.
*
* @param \Illuminate\Http\Request $request
* @return $this
*/
public function setRequest(Request $request)
{
$this->request = $request;
return $this;
}
}

View File

@@ -14,12 +14,11 @@
}
],
"require": {
"php": ">=5.4.0",
"illuminate/contracts": "5.0.*",
"illuminate/http": "5.0.*",
"illuminate/session": "5.0.*",
"illuminate/support": "5.0.*",
"nesbot/carbon": "~1.0"
"php": ">=5.5.9",
"illuminate/contracts": "5.2.*",
"illuminate/http": "5.2.*",
"illuminate/support": "5.2.*",
"nesbot/carbon": "~1.20"
},
"autoload": {
"psr-4": {
@@ -28,11 +27,13 @@
},
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
"dev-master": "5.2-dev"
}
},
"suggest": {
"illuminate/console": "Required to use the auth:clear-resets command (5.0.*)."
"illuminate/console": "Required to use the auth:clear-resets command (5.2.*).",
"illuminate/queue": "Required to fire login / logout events (5.2.*).",
"illuminate/session": "Required to use the session based guard (5.2.*)."
},
"minimum-stability": "dev"
}

View File

@@ -0,0 +1,87 @@
<?php
namespace Illuminate\Broadcasting;
use ReflectionClass;
use ReflectionProperty;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Broadcasting\Broadcaster;
class BroadcastEvent
{
/**
* The broadcaster implementation.
*
* @var \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected $broadcaster;
/**
* Create a new job handler instance.
*
* @param \Illuminate\Contracts\Broadcasting\Broadcaster $broadcaster
* @return void
*/
public function __construct(Broadcaster $broadcaster)
{
$this->broadcaster = $broadcaster;
}
/**
* Handle the queued job.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param array $data
* @return void
*/
public function fire(Job $job, array $data)
{
$event = unserialize($data['event']);
$name = method_exists($event, 'broadcastAs')
? $event->broadcastAs() : get_class($event);
$this->broadcaster->broadcast(
$event->broadcastOn(), $name, $this->getPayloadFromEvent($event)
);
$job->delete();
}
/**
* Get the payload for the given event.
*
* @param mixed $event
* @return array
*/
protected function getPayloadFromEvent($event)
{
if (method_exists($event, 'broadcastWith')) {
return $event->broadcastWith();
}
$payload = [];
foreach ((new ReflectionClass($event))->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
$payload[$property->getName()] = $this->formatProperty($property->getValue($event));
}
return $payload;
}
/**
* Format the given value for a property.
*
* @param mixed $value
* @return mixed
*/
protected function formatProperty($value)
{
if ($value instanceof Arrayable) {
return $value->toArray();
}
return $value;
}
}

View File

@@ -0,0 +1,219 @@
<?php
namespace Illuminate\Broadcasting;
use Pusher;
use Closure;
use Illuminate\Support\Arr;
use InvalidArgumentException;
use Illuminate\Broadcasting\Broadcasters\LogBroadcaster;
use Illuminate\Broadcasting\Broadcasters\RedisBroadcaster;
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
use Illuminate\Contracts\Broadcasting\Factory as FactoryContract;
class BroadcastManager implements FactoryContract
{
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;
/**
* The array of resolved broadcast drivers.
*
* @var array
*/
protected $drivers = [];
/**
* The registered custom driver creators.
*
* @var array
*/
protected $customCreators = [];
/**
* Create a new manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Get a driver instance.
*
* @param string $driver
* @return mixed
*/
public function connection($driver = null)
{
return $this->driver($driver);
}
/**
* Get a driver instance.
*
* @param string $name
* @return mixed
*/
public function driver($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return $this->drivers[$name] = $this->get($name);
}
/**
* Attempt to get the connection from the local cache.
*
* @param string $name
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function get($name)
{
return isset($this->drivers[$name]) ? $this->drivers[$name] : $this->resolve($name);
}
/**
* Resolve the given store.
*
* @param string $name
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*
* @throws \InvalidArgumentException
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
if (is_null($config)) {
throw new InvalidArgumentException("Broadcaster [{$name}] is not defined.");
}
if (isset($this->customCreators[$config['driver']])) {
return $this->callCustomCreator($config);
} else {
$driverMethod = 'create'.ucfirst($config['driver']).'Driver';
if (method_exists($this, $driverMethod)) {
return $this->{$driverMethod}($config);
} else {
throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
}
}
}
/**
* Call a custom driver creator.
*
* @param array $config
* @return mixed
*/
protected function callCustomCreator(array $config)
{
return $this->customCreators[$config['driver']]($this->app, $config);
}
/**
* Create an instance of the driver.
*
* @param array $config
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function createPusherDriver(array $config)
{
return new PusherBroadcaster(
new Pusher($config['key'], $config['secret'], $config['app_id'], Arr::get($config, 'options', []))
);
}
/**
* Create an instance of the driver.
*
* @param array $config
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function createRedisDriver(array $config)
{
return new RedisBroadcaster(
$this->app->make('redis'), Arr::get($config, 'connection')
);
}
/**
* Create an instance of the driver.
*
* @param array $config
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function createLogDriver(array $config)
{
return new LogBroadcaster(
$this->app->make('Psr\Log\LoggerInterface')
);
}
/**
* Get the connection configuration.
*
* @param string $name
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']["broadcasting.connections.{$name}"];
}
/**
* Get the default driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['broadcasting.default'];
}
/**
* Set the default driver name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['broadcasting.default'] = $name;
}
/**
* Register a custom driver creator Closure.
*
* @param string $driver
* @param \Closure $callback
* @return $this
*/
public function extend($driver, Closure $callback)
{
$this->customCreators[$driver] = $callback;
return $this;
}
/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return call_user_func_array([$this->driver(), $method], $parameters);
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Illuminate\Broadcasting;
use Illuminate\Support\ServiceProvider;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('Illuminate\Broadcasting\BroadcastManager', function ($app) {
return new BroadcastManager($app);
});
$this->app->singleton('Illuminate\Contracts\Broadcasting\Broadcaster', function ($app) {
return $app->make('Illuminate\Broadcasting\BroadcastManager')->connection();
});
$this->app->alias(
'Illuminate\Broadcasting\BroadcastManager', 'Illuminate\Contracts\Broadcasting\Factory'
);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'Illuminate\Broadcasting\BroadcastManager',
'Illuminate\Contracts\Broadcasting\Factory',
'Illuminate\Contracts\Broadcasting\Broadcaster',
];
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Illuminate\Broadcasting\Broadcasters;
use Psr\Log\LoggerInterface;
use Illuminate\Contracts\Broadcasting\Broadcaster;
class LogBroadcaster implements Broadcaster
{
/**
* The logger implementation.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* Create a new broadcaster instance.
*
* @param \Psr\Log\LoggerInterface $logger
* @return void
*/
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
public function broadcast(array $channels, $event, array $payload = [])
{
$channels = implode(', ', $channels);
$payload = json_encode($payload, JSON_PRETTY_PRINT);
$this->logger->info('Broadcasting ['.$event.'] on channels ['.$channels.'] with payload:'.PHP_EOL.$payload);
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Illuminate\Broadcasting\Broadcasters;
use Pusher;
use Illuminate\Contracts\Broadcasting\Broadcaster;
class PusherBroadcaster implements Broadcaster
{
/**
* The Pusher SDK instance.
*
* @var \Pusher
*/
protected $pusher;
/**
* Create a new broadcaster instance.
*
* @param \Pusher $pusher
* @return void
*/
public function __construct(Pusher $pusher)
{
$this->pusher = $pusher;
}
/**
* {@inheritdoc}
*/
public function broadcast(array $channels, $event, array $payload = [])
{
$this->pusher->trigger($channels, $event, $payload);
}
/**
* Get the Pusher SDK instance.
*
* @return \Pusher
*/
public function getPusher()
{
return $this->pusher;
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Illuminate\Broadcasting\Broadcasters;
use Illuminate\Contracts\Broadcasting\Broadcaster;
use Illuminate\Contracts\Redis\Database as RedisDatabase;
class RedisBroadcaster implements Broadcaster
{
/**
* The Redis instance.
*
* @var \Illuminate\Contracts\Redis\Database
*/
protected $redis;
/**
* The Redis connection to use for broadcasting.
*
* @var string
*/
protected $connection;
/**
* Create a new broadcaster instance.
*
* @param \Illuminate\Contracts\Redis\Database $redis
* @param string $connection
* @return void
*/
public function __construct(RedisDatabase $redis, $connection = null)
{
$this->redis = $redis;
$this->connection = $connection;
}
/**
* {@inheritdoc}
*/
public function broadcast(array $channels, $event, array $payload = [])
{
$connection = $this->redis->connection($this->connection);
$payload = json_encode(['event' => $event, 'data' => $payload]);
foreach ($channels as $channel) {
$connection->publish($channel, $payload);
}
}
}

View File

@@ -0,0 +1,35 @@
{
"name": "illuminate/broadcasting",
"description": "The Illuminate Broadcasting package.",
"license": "MIT",
"homepage": "http://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"authors": [
{
"name": "Taylor Otwell",
"email": "taylorotwell@gmail.com"
}
],
"require": {
"php": ">=5.5.9",
"illuminate/contracts": "5.2.*",
"illuminate/support": "5.2.*"
},
"autoload": {
"psr-4": {
"Illuminate\\Broadcasting\\": ""
}
},
"extra": {
"branch-alias": {
"dev-master": "5.2-dev"
}
},
"suggest": {
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0)."
},
"minimum-stability": "dev"
}

View File

@@ -1,52 +1,51 @@
<?php namespace Illuminate\Bus;
<?php
namespace Illuminate\Bus;
use Illuminate\Support\ServiceProvider;
class BusServiceProvider extends ServiceProvider {
class BusServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('Illuminate\Bus\Dispatcher', function ($app) {
return new Dispatcher($app, function ($connection = null) use ($app) {
return $app['Illuminate\Contracts\Queue\Factory']->connection($connection);
});
});
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('Illuminate\Bus\Dispatcher', function($app)
{
return new Dispatcher($app, function() use ($app)
{
return $app['Illuminate\Contracts\Queue\Queue'];
});
});
$this->app->alias(
'Illuminate\Bus\Dispatcher', 'Illuminate\Contracts\Bus\Dispatcher'
);
$this->app->alias(
'Illuminate\Bus\Dispatcher', 'Illuminate\Contracts\Bus\Dispatcher'
);
$this->app->alias(
'Illuminate\Bus\Dispatcher', 'Illuminate\Contracts\Bus\QueueingDispatcher'
);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'Illuminate\Bus\Dispatcher',
'Illuminate\Contracts\Bus\Dispatcher',
'Illuminate\Contracts\Bus\QueueingDispatcher',
];
}
$this->app->alias(
'Illuminate\Bus\Dispatcher', 'Illuminate\Contracts\Bus\QueueingDispatcher'
);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'Illuminate\Bus\Dispatcher',
'Illuminate\Contracts\Bus\Dispatcher',
'Illuminate\Contracts\Bus\QueueingDispatcher',
];
}
}

View File

@@ -1,409 +1,158 @@
<?php namespace Illuminate\Bus;
<?php
namespace Illuminate\Bus;
use Closure;
use ArrayAccess;
use ReflectionClass;
use RuntimeException;
use ReflectionParameter;
use InvalidArgumentException;
use Illuminate\Pipeline\Pipeline;
use Illuminate\Support\Collection;
use Illuminate\Contracts\Queue\Queue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Bus\HandlerResolver;
use Illuminate\Contracts\Queue\ShouldBeQueued;
use Illuminate\Contracts\Bus\QueueingDispatcher;
use Illuminate\Contracts\Bus\Dispatcher as DispatcherContract;
class Dispatcher implements DispatcherContract, QueueingDispatcher, HandlerResolver {
class Dispatcher implements DispatcherContract, QueueingDispatcher
{
/**
* The container implementation.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* The container implementation.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* The pipeline instance for the bus.
*
* @var \Illuminate\Pipeline\Pipeline
*/
protected $pipeline;
/**
* The pipeline instance for the bus.
*
* @var \Illuminate\Pipeline\Pipeline
*/
protected $pipeline;
/**
* The pipes to send commands through before dispatching.
*
* @var array
*/
protected $pipes = [];
/**
* The pipes to send commands through before dispatching.
*
* @var array
*/
protected $pipes = [];
/**
* The queue resolver callback.
*
* @var \Closure|null
*/
protected $queueResolver;
/**
* The queue resolver callback.
*
* @var \Closure|null
*/
protected $queueResolver;
/**
* Create a new command dispatcher instance.
*
* @param \Illuminate\Contracts\Container\Container $container
* @param \Closure|null $queueResolver
* @return void
*/
public function __construct(Container $container, Closure $queueResolver = null)
{
$this->container = $container;
$this->queueResolver = $queueResolver;
$this->pipeline = new Pipeline($container);
}
/**
* All of the command-to-handler mappings.
*
* @var array
*/
protected $mappings = [];
/**
* Dispatch a command to its appropriate handler.
*
* @param mixed $command
* @return mixed
*/
public function dispatch($command)
{
if ($this->queueResolver && $this->commandShouldBeQueued($command)) {
return $this->dispatchToQueue($command);
} else {
return $this->dispatchNow($command);
}
}
/**
* The fallback mapping Closure.
*
* @var \Closure
*/
protected $mapper;
/**
* Dispatch a command to its appropriate handler in the current process.
*
* @param mixed $command
* @return mixed
*/
public function dispatchNow($command)
{
return $this->pipeline->send($command)->through($this->pipes)->then(function ($command) {
return $this->container->call([$command, 'handle']);
});
}
/**
* Create a new command dispatcher instance.
*
* @param \Illuminate\Contracts\Container\Container $container
* @param \Closure|null $queueResolver
* @return void
*/
public function __construct(Container $container, Closure $queueResolver = null)
{
$this->container = $container;
$this->queueResolver = $queueResolver;
$this->pipeline = new Pipeline($container);
}
/**
* Determine if the given command should be queued.
*
* @param mixed $command
* @return bool
*/
protected function commandShouldBeQueued($command)
{
return $command instanceof ShouldQueue;
}
/**
* Marshal a command and dispatch it to its appropriate handler.
*
* @param mixed $command
* @param array $array
* @return mixed
*/
public function dispatchFromArray($command, array $array)
{
return $this->dispatch($this->marshalFromArray($command, $array));
}
/**
* Dispatch a command to its appropriate handler behind a queue.
*
* @param mixed $command
* @return mixed
*
* @throws \RuntimeException
*/
public function dispatchToQueue($command)
{
$connection = isset($command->connection) ? $command->connection : null;
/**
* Marshal a command and dispatch it to its appropriate handler.
*
* @param mixed $command
* @param \ArrayAccess $source
* @param array $extras
* @return mixed
*/
public function dispatchFrom($command, ArrayAccess $source, array $extras = [])
{
return $this->dispatch($this->marshal($command, $source, $extras));
}
$queue = call_user_func($this->queueResolver, $connection);
/**
* Marshal a command from the given array.
*
* @param string $command
* @param array $array
* @return mixed
*/
protected function marshalFromArray($command, array $array)
{
return $this->marshal($command, new Collection, $array);
}
if (! $queue instanceof Queue) {
throw new RuntimeException('Queue resolver did not return a Queue implementation.');
}
/**
* Marshal a command from the given array accessible object.
*
* @param string $command
* @param \ArrayAccess $source
* @param array $extras
* @return mixed
*/
protected function marshal($command, ArrayAccess $source, array $extras = [])
{
$injected = [];
if (method_exists($command, 'queue')) {
return $command->queue($queue, $command);
} else {
return $this->pushCommandToQueue($queue, $command);
}
}
$reflection = new ReflectionClass($command);
/**
* Push the command onto the given queue instance.
*
* @param \Illuminate\Contracts\Queue\Queue $queue
* @param mixed $command
* @return mixed
*/
protected function pushCommandToQueue($queue, $command)
{
if (isset($command->queue, $command->delay)) {
return $queue->laterOn($command->queue, $command->delay, $command);
}
if ($constructor = $reflection->getConstructor())
{
$injected = array_map(function($parameter) use ($command, $source, $extras)
{
return $this->getParameterValueForCommand($command, $source, $parameter, $extras);
if (isset($command->queue)) {
return $queue->pushOn($command->queue, $command);
}
}, $constructor->getParameters());
}
if (isset($command->delay)) {
return $queue->later($command->delay, $command);
}
return $reflection->newInstanceArgs($injected);
}
return $queue->push($command);
}
/**
* Get a parameter value for a marshaled command.
*
* @param string $command
* @param \ArrayAccess $source
* @param \ReflectionParameter $parameter
* @param array $extras
* @return mixed
*/
protected function getParameterValueForCommand($command, ArrayAccess $source,
ReflectionParameter $parameter, array $extras = array())
{
if (array_key_exists($parameter->name, $extras))
{
return $extras[$parameter->name];
}
if (isset($source[$parameter->name]))
{
return $source[$parameter->name];
}
if ($parameter->isDefaultValueAvailable())
{
return $parameter->getDefaultValue();
}
MarshalException::whileMapping($command, $parameter);
}
/**
* Dispatch a command to its appropriate handler.
*
* @param mixed $command
* @param \Closure|null $afterResolving
* @return mixed
*/
public function dispatch($command, Closure $afterResolving = null)
{
if ($this->queueResolver && $this->commandShouldBeQueued($command))
{
return $this->dispatchToQueue($command);
}
else
{
return $this->dispatchNow($command, $afterResolving);
}
}
/**
* Dispatch a command to its appropriate handler in the current process.
*
* @param mixed $command
* @param \Closure|null $afterResolving
* @return mixed
*/
public function dispatchNow($command, Closure $afterResolving = null)
{
return $this->pipeline->send($command)->through($this->pipes)->then(function($command) use ($afterResolving)
{
if ($command instanceof SelfHandling)
{
return $this->container->call([$command, 'handle']);
}
$handler = $this->resolveHandler($command);
if ($afterResolving)
{
call_user_func($afterResolving, $handler);
}
return call_user_func(
[$handler, $this->getHandlerMethod($command)], $command
);
});
}
/**
* Determine if the given command should be queued.
*
* @param mixed $command
* @return bool
*/
protected function commandShouldBeQueued($command)
{
if ($command instanceof ShouldBeQueued)
{
return true;
}
return (new ReflectionClass($this->getHandlerClass($command)))->implementsInterface(
'Illuminate\Contracts\Queue\ShouldBeQueued'
);
}
/**
* Dispatch a command to its appropriate handler behind a queue.
*
* @param mixed $command
* @return mixed
*
* @throws \RuntimeException
*/
public function dispatchToQueue($command)
{
$queue = call_user_func($this->queueResolver);
if ( ! $queue instanceof Queue)
{
throw new RuntimeException("Queue resolver did not return a Queue implementation.");
}
if (method_exists($command, 'queue'))
{
$command->queue($queue, $command);
}
else
{
$queue->push($command);
}
}
/**
* Get the handler instance for the given command.
*
* @param mixed $command
* @return mixed
*/
public function resolveHandler($command)
{
if ($command instanceof SelfHandling)
{
return $command;
}
return $this->container->make($this->getHandlerClass($command));
}
/**
* Get the handler class for the given command.
*
* @param mixed $command
* @return string
*/
public function getHandlerClass($command)
{
if ($command instanceof SelfHandling)
{
return get_class($command);
}
return $this->inflectSegment($command, 0);
}
/**
* Get the handler method for the given command.
*
* @param mixed $command
* @return string
*/
public function getHandlerMethod($command)
{
if ($command instanceof SelfHandling)
{
return 'handle';
}
return $this->inflectSegment($command, 1);
}
/**
* Get the given handler segment for the given command.
*
* @param mixed $command
* @param int $segment
* @return string
*/
protected function inflectSegment($command, $segment)
{
$className = get_class($command);
if (isset($this->mappings[$className]))
{
return $this->getMappingSegment($className, $segment);
}
elseif ($this->mapper)
{
return $this->getMapperSegment($command, $segment);
}
throw new InvalidArgumentException("No handler registered for command [{$className}]");
}
/**
* Get the given segment from a given class handler.
*
* @param string $className
* @param int $segment
* @return string
*/
protected function getMappingSegment($className, $segment)
{
return explode('@', $this->mappings[$className])[$segment];
}
/**
* Get the given segment from a given class handler using the custom mapper.
*
* @param mixed $command
* @param int $segment
* @return string
*/
protected function getMapperSegment($command, $segment)
{
return explode('@', call_user_func($this->mapper, $command))[$segment];
}
/**
* Register command-to-handler mappings.
*
* @param array $commands
* @return void
*/
public function maps(array $commands)
{
$this->mappings = array_merge($this->mappings, $commands);
}
/**
* Register a fallback mapper callback.
*
* @param \Closure $mapper
* @return void
*/
public function mapUsing(Closure $mapper)
{
$this->mapper = $mapper;
}
/**
* Map the command to a handler within a given root namespace.
*
* @param mixed $command
* @param string $commandNamespace
* @param string $handlerNamespace
* @return string
*/
public static function simpleMapping($command, $commandNamespace, $handlerNamespace)
{
$command = str_replace($commandNamespace, '', get_class($command));
return $handlerNamespace.'\\'.trim($command, '\\').'Handler@handle';
}
/**
* Set the pipes through which commands should be piped before dispatching.
*
* @param array $pipes
* @return $this
*/
public function pipeThrough(array $pipes)
{
$this->pipes = $pipes;
return $this;
}
/**
* Set the pipes through which commands should be piped before dispatching.
*
* @param array $pipes
* @return $this
*/
public function pipeThrough(array $pipes)
{
$this->pipes = $pipes;
return $this;
}
}

View File

@@ -1,20 +0,0 @@
<?php namespace Illuminate\Bus;
use RuntimeException;
use ReflectionParameter;
class MarshalException extends RuntimeException {
/**
* Throw new a new exception.
*
* @param string $command
* @param \ReflectionParameter $parameter
* @return void
*/
public static function whileMapping($command, ReflectionParameter $parameter)
{
throw new static("Unable to map parameter [{$parameter->name}] to command [{$command}]");
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace Illuminate\Bus;
trait Queueable
{
/**
* The name of the connection the job should be sent to.
*
* @var string|null
*/
public $connection;
/**
* The name of the queue the job should be sent to.
*
* @var string|null
*/
public $queue;
/**
* The number of seconds before the job should be made available.
*
* @var int|null
*/
public $delay;
/**
* Set the desired connection for the job.
*
* @param string|null $connection
* @return $this
*/
public function onConnection($connection)
{
$this->connection = $connection;
return $this;
}
/**
* Set the desired queue for the job.
*
* @param string|null $queue
* @return $this
*/
public function onQueue($queue)
{
$this->queue = $queue;
return $this;
}
/**
* Set the desired delay for the job.
*
* @param int|null $delay
* @return $this
*/
public function delay($delay)
{
$this->delay = $delay;
return $this;
}
}

View File

@@ -14,10 +14,10 @@
}
],
"require": {
"php": ">=5.4.0",
"illuminate/contracts": "5.0.*",
"illuminate/pipeline": "5.0.*",
"illuminate/support": "5.0.*"
"php": ">=5.5.9",
"illuminate/contracts": "5.2.*",
"illuminate/pipeline": "5.2.*",
"illuminate/support": "5.2.*"
},
"autoload": {
"psr-4": {
@@ -26,7 +26,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
"dev-master": "5.2-dev"
}
},
"minimum-stability": "dev"

View File

@@ -1,130 +1,132 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
class ApcStore extends TaggableStore implements Store {
class ApcStore extends TaggableStore implements Store
{
use RetrievesMultipleKeys;
/**
* The APC wrapper instance.
*
* @var \Illuminate\Cache\ApcWrapper
*/
protected $apc;
/**
* The APC wrapper instance.
*
* @var \Illuminate\Cache\ApcWrapper
*/
protected $apc;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new APC store.
*
* @param \Illuminate\Cache\ApcWrapper $apc
* @param string $prefix
* @return void
*/
public function __construct(ApcWrapper $apc, $prefix = '')
{
$this->apc = $apc;
$this->prefix = $prefix;
}
/**
* Create a new APC store.
*
* @param \Illuminate\Cache\ApcWrapper $apc
* @param string $prefix
* @return void
*/
public function __construct(ApcWrapper $apc, $prefix = '')
{
$this->apc = $apc;
$this->prefix = $prefix;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$value = $this->apc->get($this->prefix.$key);
/**
* Retrieve an item from the cache by key.
*
* @param string|array $key
* @return mixed
*/
public function get($key)
{
$value = $this->apc->get($this->prefix.$key);
if ($value !== false)
{
return $value;
}
}
if ($value !== false) {
return $value;
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$this->apc->put($this->prefix.$key, $value, $minutes * 60);
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$this->apc->put($this->prefix.$key, $value, $minutes * 60);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value = 1)
{
return $this->apc->increment($this->prefix.$key, $value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value = 1)
{
return $this->apc->increment($this->prefix.$key, $value);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value = 1)
{
return $this->apc->decrement($this->prefix.$key, $value);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value = 1)
{
return $this->apc->decrement($this->prefix.$key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return array|bool
*/
public function forever($key, $value)
{
return $this->put($key, $value, 0);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return $this->apc->delete($this->prefix.$key);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return $this->apc->delete($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->apc->flush();
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->apc->flush();
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
}

View File

@@ -1,91 +1,92 @@
<?php namespace Illuminate\Cache;
<?php
class ApcWrapper {
namespace Illuminate\Cache;
/**
* Indicates if APCu is supported.
*
* @var bool
*/
protected $apcu = false;
class ApcWrapper
{
/**
* Indicates if APCu is supported.
*
* @var bool
*/
protected $apcu = false;
/**
* Create a new APC wrapper instance.
*
* @return void
*/
public function __construct()
{
$this->apcu = function_exists('apcu_fetch');
}
/**
* Create a new APC wrapper instance.
*
* @return void
*/
public function __construct()
{
$this->apcu = function_exists('apcu_fetch');
}
/**
* Get an item from the cache.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
return $this->apcu ? apcu_fetch($key) : apc_fetch($key);
}
/**
* Get an item from the cache.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
return $this->apcu ? apcu_fetch($key) : apc_fetch($key);
}
/**
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param int $seconds
* @return array|bool
*/
public function put($key, $value, $seconds)
{
return $this->apcu ? apcu_store($key, $value, $seconds) : apc_store($key, $value, $seconds);
}
/**
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param int $seconds
* @return array|bool
*/
public function put($key, $value, $seconds)
{
return $this->apcu ? apcu_store($key, $value, $seconds) : apc_store($key, $value, $seconds);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value)
{
return $this->apcu ? apcu_inc($key, $value) : apc_inc($key, $value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value)
{
return $this->apcu ? apcu_inc($key, $value) : apc_inc($key, $value);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value)
{
return $this->apcu ? apcu_dec($key, $value) : apc_dec($key, $value);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value)
{
return $this->apcu ? apcu_dec($key, $value) : apc_dec($key, $value);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function delete($key)
{
return $this->apcu ? apcu_delete($key) : apc_delete($key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->apcu ? apcu_clear_cache() : apc_clear_cache('user');
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function delete($key)
{
return $this->apcu ? apcu_delete($key) : apc_delete($key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->apcu ? apcu_clear_cache() : apc_clear_cache('user');
}
}

View File

@@ -1,112 +1,114 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
class ArrayStore extends TaggableStore implements Store {
class ArrayStore extends TaggableStore implements Store
{
use RetrievesMultipleKeys;
/**
* The array of stored values.
*
* @var array
*/
protected $storage = array();
/**
* The array of stored values.
*
* @var array
*/
protected $storage = [];
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
if (array_key_exists($key, $this->storage))
{
return $this->storage[$key];
}
}
/**
* Retrieve an item from the cache by key.
*
* @param string|array $key
* @return mixed
*/
public function get($key)
{
if (array_key_exists($key, $this->storage)) {
return $this->storage[$key];
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$this->storage[$key] = $value;
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$this->storage[$key] = $value;
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function increment($key, $value = 1)
{
$this->storage[$key] = $this->storage[$key] + $value;
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function increment($key, $value = 1)
{
$this->storage[$key] = $this->storage[$key] + $value;
return $this->storage[$key];
}
return $this->storage[$key];
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function decrement($key, $value = 1)
{
return $this->increment($key, $value * -1);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function decrement($key, $value = 1)
{
return $this->increment($key, $value * -1);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
unset($this->storage[$key]);
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
unset($this->storage[$key]);
return true;
}
return true;
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->storage = array();
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return '';
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->storage = [];
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return '';
}
}

View File

@@ -1,315 +1,298 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Closure;
use Illuminate\Support\Arr;
use InvalidArgumentException;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Contracts\Cache\Factory as FactoryContract;
class CacheManager implements FactoryContract {
class CacheManager implements FactoryContract
{
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;
/**
* The array of resolved cache stores.
*
* @var array
*/
protected $stores = [];
/**
* The array of resolved cache stores.
*
* @var array
*/
protected $stores = [];
/**
* The registered custom driver creators.
*
* @var array
*/
protected $customCreators = [];
/**
* The registered custom driver creators.
*
* @var array
*/
protected $customCreators = [];
/**
* Create a new Cache manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Create a new Cache manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Get a cache store instance by name.
*
* @param string|null $name
* @return mixed
*/
public function store($name = null)
{
$name = $name ?: $this->getDefaultDriver();
/**
* Get a cache store instance by name.
*
* @param string|null $name
* @return mixed
*/
public function store($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return $this->stores[$name] = $this->get($name);
}
return $this->stores[$name] = $this->get($name);
}
/**
* Get a cache driver instance.
*
* @param string $driver
* @return mixed
*/
public function driver($driver = null)
{
return $this->store($driver);
}
/**
* Get a cache driver instance.
*
* @param string $driver
* @return mixed
*/
public function driver($driver = null)
{
return $this->store($driver);
}
/**
* Attempt to get the store from the local cache.
*
* @param string $name
* @return \Illuminate\Contracts\Cache\Repository
*/
protected function get($name)
{
return isset($this->stores[$name]) ? $this->stores[$name] : $this->resolve($name);
}
/**
* Attempt to get the store from the local cache.
*
* @param string $name
* @return \Illuminate\Contracts\Cache\Repository
*/
protected function get($name)
{
return isset($this->stores[$name]) ? $this->stores[$name] : $this->resolve($name);
}
/**
* Resolve the given store.
*
* @param string $name
* @return \Illuminate\Contracts\Cache\Repository
*
* @throws \InvalidArgumentException
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
/**
* Resolve the given store.
*
* @param string $name
* @return \Illuminate\Contracts\Cache\Repository
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
if (is_null($config)) {
throw new InvalidArgumentException("Cache store [{$name}] is not defined.");
}
if (is_null($config))
{
throw new InvalidArgumentException("Cache store [{$name}] is not defined.");
}
if (isset($this->customCreators[$config['driver']])) {
return $this->callCustomCreator($config);
} else {
$driverMethod = 'create'.ucfirst($config['driver']).'Driver';
if (isset($this->customCreators[$config['driver']]))
{
return $this->callCustomCreator($config);
}
else
{
return $this->{"create".ucfirst($config['driver'])."Driver"}($config);
}
}
if (method_exists($this, $driverMethod)) {
return $this->{$driverMethod}($config);
} else {
throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
}
}
}
/**
* Call a custom driver creator.
*
* @param array $config
* @return mixed
*/
protected function callCustomCreator(array $config)
{
return $this->customCreators[$config['driver']]($this->app, $config);
}
/**
* Call a custom driver creator.
*
* @param array $config
* @return mixed
*/
protected function callCustomCreator(array $config)
{
return $this->customCreators[$config['driver']]($this->app, $config);
}
/**
* Create an instance of the APC cache driver.
*
* @param array $config
* @return \Illuminate\Cache\ApcStore
*/
protected function createApcDriver(array $config)
{
$prefix = $this->getPrefix($config);
/**
* Create an instance of the APC cache driver.
*
* @param array $config
* @return \Illuminate\Cache\ApcStore
*/
protected function createApcDriver(array $config)
{
$prefix = $this->getPrefix($config);
return $this->repository(new ApcStore(new ApcWrapper, $prefix));
}
return $this->repository(new ApcStore(new ApcWrapper, $prefix));
}
/**
* Create an instance of the array cache driver.
*
* @return \Illuminate\Cache\ArrayStore
*/
protected function createArrayDriver()
{
return $this->repository(new ArrayStore);
}
/**
* Create an instance of the array cache driver.
*
* @return \Illuminate\Cache\ArrayStore
*/
protected function createArrayDriver()
{
return $this->repository(new ArrayStore);
}
/**
* Create an instance of the file cache driver.
*
* @param array $config
* @return \Illuminate\Cache\FileStore
*/
protected function createFileDriver(array $config)
{
return $this->repository(new FileStore($this->app['files'], $config['path']));
}
/**
* Create an instance of the file cache driver.
*
* @param array $config
* @return \Illuminate\Cache\FileStore
*/
protected function createFileDriver(array $config)
{
return $this->repository(new FileStore($this->app['files'], $config['path']));
}
/**
* Create an instance of the Memcached cache driver.
*
* @param array $config
* @return \Illuminate\Cache\MemcachedStore
*/
protected function createMemcachedDriver(array $config)
{
$prefix = $this->getPrefix($config);
/**
* Create an instance of the Memcached cache driver.
*
* @param array $config
* @return \Illuminate\Cache\MemcachedStore
*/
protected function createMemcachedDriver(array $config)
{
$prefix = $this->getPrefix($config);
$memcached = $this->app['memcached.connector']->connect($config['servers']);
$memcached = $this->app['memcached.connector']->connect($config['servers']);
return $this->repository(new MemcachedStore($memcached, $prefix));
}
return $this->repository(new MemcachedStore($memcached, $prefix));
}
/**
* Create an instance of the Null cache driver.
*
* @return \Illuminate\Cache\NullStore
*/
protected function createNullDriver()
{
return $this->repository(new NullStore);
}
/**
* Create an instance of the Null cache driver.
*
* @return \Illuminate\Cache\NullStore
*/
protected function createNullDriver()
{
return $this->repository(new NullStore);
}
/**
* Create an instance of the WinCache cache driver.
*
* @param array $config
* @return \Illuminate\Cache\WinCacheStore
*/
protected function createWincacheDriver(array $config)
{
return $this->repository(new WinCacheStore($this->getPrefix($config)));
}
/**
* Create an instance of the Redis cache driver.
*
* @param array $config
* @return \Illuminate\Cache\RedisStore
*/
protected function createRedisDriver(array $config)
{
$redis = $this->app['redis'];
/**
* Create an instance of the XCache cache driver.
*
* @param array $config
* @return \Illuminate\Cache\WinCacheStore
*/
protected function createXcacheDriver(array $config)
{
return $this->repository(new XCacheStore($this->getPrefix($config)));
}
$connection = Arr::get($config, 'connection', 'default');
/**
* Create an instance of the Redis cache driver.
*
* @param array $config
* @return \Illuminate\Cache\RedisStore
*/
protected function createRedisDriver(array $config)
{
$redis = $this->app['redis'];
return $this->repository(new RedisStore($redis, $this->getPrefix($config), $connection));
}
$connection = array_get($config, 'connection', 'default') ?: 'default';
/**
* Create an instance of the database cache driver.
*
* @param array $config
* @return \Illuminate\Cache\DatabaseStore
*/
protected function createDatabaseDriver(array $config)
{
$connection = $this->app['db']->connection(Arr::get($config, 'connection'));
return $this->repository(new RedisStore($redis, $this->getPrefix($config), $connection));
}
return $this->repository(
new DatabaseStore(
$connection, $this->app['encrypter'], $config['table'], $this->getPrefix($config)
)
);
}
/**
* Create an instance of the database cache driver.
*
* @param array $config
* @return \Illuminate\Cache\DatabaseStore
*/
protected function createDatabaseDriver(array $config)
{
$connection = $this->app['db']->connection(array_get($config, 'connection'));
/**
* Create a new cache repository with the given implementation.
*
* @param \Illuminate\Contracts\Cache\Store $store
* @return \Illuminate\Cache\Repository
*/
public function repository(Store $store)
{
$repository = new Repository($store);
return $this->repository(
new DatabaseStore(
$connection, $this->app['encrypter'], $config['table'], $this->getPrefix($config)
)
);
}
if ($this->app->bound('Illuminate\Contracts\Events\Dispatcher')) {
$repository->setEventDispatcher(
$this->app['Illuminate\Contracts\Events\Dispatcher']
);
}
/**
* Create a new cache repository with the given implementation.
*
* @param \Illuminate\Contracts\Cache\Store $store
* @return \Illuminate\Cache\Repository
*/
public function repository(Store $store)
{
$repository = new Repository($store);
return $repository;
}
if ($this->app->bound('Illuminate\Contracts\Events\Dispatcher'))
{
$repository->setEventDispatcher(
$this->app['Illuminate\Contracts\Events\Dispatcher']
);
}
/**
* Get the cache prefix.
*
* @param array $config
* @return string
*/
protected function getPrefix(array $config)
{
return Arr::get($config, 'prefix') ?: $this->app['config']['cache.prefix'];
}
return $repository;
}
/**
* Get the cache connection configuration.
*
* @param string $name
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']["cache.stores.{$name}"];
}
/**
* Get the cache prefix.
*
* @param array $config
* @return string
*/
protected function getPrefix(array $config)
{
return array_get($config, 'prefix') ?: $this->app['config']['cache.prefix'];
}
/**
* Get the default cache driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['cache.default'];
}
/**
* Get the cache connection configuration.
*
* @param string $name
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']["cache.stores.{$name}"];
}
/**
* Set the default cache driver name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['cache.default'] = $name;
}
/**
* Get the default cache driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['cache.default'];
}
/**
* Register a custom driver creator Closure.
*
* @param string $driver
* @param \Closure $callback
* @return $this
*/
public function extend($driver, Closure $callback)
{
$this->customCreators[$driver] = $callback;
/**
* Set the default cache driver name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['cache.default'] = $name;
}
/**
* Register a custom driver creator Closure.
*
* @param string $driver
* @param \Closure $callback
* @return $this
*/
public function extend($driver, Closure $callback)
{
$this->customCreators[$driver] = $callback;
return $this;
}
/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return call_user_func_array(array($this->store(), $method), $parameters);
}
return $this;
}
/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return call_user_func_array([$this->store(), $method], $parameters);
}
}

View File

@@ -1,73 +1,64 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Illuminate\Support\ServiceProvider;
use Illuminate\Cache\Console\ClearCommand;
use Illuminate\Cache\Console\CacheTableCommand;
class CacheServiceProvider extends ServiceProvider {
class CacheServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('cache', function ($app) {
return new CacheManager($app);
});
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('cache', function($app)
{
return new CacheManager($app);
});
$this->app->singleton('cache.store', function ($app) {
return $app['cache']->driver();
});
$this->app->singleton('cache.store', function($app)
{
return $app['cache']->driver();
});
$this->app->singleton('memcached.connector', function () {
return new MemcachedConnector;
});
$this->app->singleton('memcached.connector', function()
{
return new MemcachedConnector;
});
$this->registerCommands();
}
$this->registerCommands();
}
/**
* Register the cache related console commands.
*
* @return void
*/
public function registerCommands()
{
$this->app->singleton('command.cache.clear', function ($app) {
return new ClearCommand($app['cache']);
});
/**
* Register the cache related console commands.
*
* @return void
*/
public function registerCommands()
{
$this->app->singleton('command.cache.clear', function($app)
{
return new ClearCommand($app['cache']);
});
$this->app->singleton('command.cache.table', function($app)
{
return new CacheTableCommand($app['files'], $app['composer']);
});
$this->commands('command.cache.clear', 'command.cache.table');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'cache', 'cache.store', 'memcached.connector', 'command.cache.clear', 'command.cache.table',
];
}
$this->commands('command.cache.clear');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'cache', 'cache.store', 'memcached.connector', 'command.cache.clear',
];
}
}

View File

@@ -1,80 +1,81 @@
<?php namespace Illuminate\Cache\Console;
<?php
namespace Illuminate\Cache\Console;
use Illuminate\Console\Command;
use Illuminate\Foundation\Composer;
use Illuminate\Support\Composer;
use Illuminate\Filesystem\Filesystem;
class CacheTableCommand extends Command {
class CacheTableCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'cache:table';
/**
* The console command name.
*
* @var string
*/
protected $name = 'cache:table';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a migration for the cache database table';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a migration for the cache database table';
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* @var \Illuminate\Support\Composer
*/
protected $composer;
/**
* @var \Illuminate\Foundation\Composer
*/
protected $composer;
/**
* Create a new session table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\Support\Composer $composer
* @return void
*/
public function __construct(Filesystem $files, Composer $composer)
{
parent::__construct();
/**
* Create a new session table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\Foundation\Composer $composer
* @return void
*/
public function __construct(Filesystem $files, Composer $composer)
{
parent::__construct();
$this->files = $files;
$this->composer = $composer;
}
$this->files = $files;
$this->composer = $composer;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$fullPath = $this->createBaseMigration();
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$fullPath = $this->createBaseMigration();
$this->files->put($fullPath, $this->files->get(__DIR__.'/stubs/cache.stub'));
$this->files->put($fullPath, $this->files->get(__DIR__.'/stubs/cache.stub'));
$this->info('Migration created successfully!');
$this->info('Migration created successfully!');
$this->composer->dumpAutoloads();
}
$this->composer->dumpAutoloads();
}
/**
* Create a base migration file for the table.
*
* @return string
*/
protected function createBaseMigration()
{
$name = 'create_cache_table';
/**
* Create a base migration file for the table.
*
* @return string
*/
protected function createBaseMigration()
{
$name = 'create_cache_table';
$path = $this->laravel->databasePath().'/migrations';
return $this->laravel['migration.creator']->create($name, $path);
}
$path = $this->laravel->databasePath().'/migrations';
return $this->laravel['migration.creator']->create($name, $path);
}
}

View File

@@ -1,73 +1,74 @@
<?php namespace Illuminate\Cache\Console;
<?php
namespace Illuminate\Cache\Console;
use Illuminate\Console\Command;
use Illuminate\Cache\CacheManager;
use Symfony\Component\Console\Input\InputArgument;
class ClearCommand extends Command {
class ClearCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'cache:clear';
/**
* The console command name.
*
* @var string
*/
protected $name = 'cache:clear';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Flush the application cache';
/**
* The console command description.
*
* @var string
*/
protected $description = "Flush the application cache";
/**
* The cache manager instance.
*
* @var \Illuminate\Cache\CacheManager
*/
protected $cache;
/**
* The cache manager instance.
*
* @var \Illuminate\Cache\CacheManager
*/
protected $cache;
/**
* Create a new cache clear command instance.
*
* @param \Illuminate\Cache\CacheManager $cache
* @return void
*/
public function __construct(CacheManager $cache)
{
parent::__construct();
/**
* Create a new cache clear command instance.
*
* @param \Illuminate\Cache\CacheManager $cache
* @return void
*/
public function __construct(CacheManager $cache)
{
parent::__construct();
$this->cache = $cache;
}
$this->cache = $cache;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$storeName = $this->argument('store');
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$storeName = $this->argument('store');
$this->laravel['events']->fire('cache:clearing', [$storeName]);
$this->laravel['events']->fire('cache:clearing', [$storeName]);
$this->cache->store($storeName)->flush();
$this->cache->store($storeName)->flush();
$this->laravel['events']->fire('cache:cleared', [$storeName]);
$this->laravel['events']->fire('cache:cleared', [$storeName]);
$this->info('Application cache cleared!');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['store', InputArgument::OPTIONAL, 'The name of the store you would like to clear.'],
];
}
$this->info('Application cache cleared!');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['store', InputArgument::OPTIONAL, 'The name of the store you would like to clear.'],
];
}
}

View File

@@ -3,31 +3,29 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCacheTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('cache', function(Blueprint $table)
{
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('cache');
}
class CreateCacheTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('cache', function (Blueprint $table) {
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('cache');
}
}

View File

@@ -1,228 +1,266 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Closure;
use Exception;
use LogicException;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract;
class DatabaseStore implements Store {
class DatabaseStore implements Store
{
use RetrievesMultipleKeys;
/**
* The database connection instance.
*
* @var \Illuminate\Database\ConnectionInterface
*/
protected $connection;
/**
* The database connection instance.
*
* @var \Illuminate\Database\ConnectionInterface
*/
protected $connection;
/**
* The encrypter instance.
*
* @var \Illuminate\Contracts\Encryption\Encrypter
*/
protected $encrypter;
/**
* The encrypter instance.
*
* @var \Illuminate\Contracts\Encryption\Encrypter
*/
protected $encrypter;
/**
* The name of the cache table.
*
* @var string
*/
protected $table;
/**
* The name of the cache table.
*
* @var string
*/
protected $table;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new database store.
*
* @param \Illuminate\Database\ConnectionInterface $connection
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
* @param string $table
* @param string $prefix
* @return void
*/
public function __construct(ConnectionInterface $connection, EncrypterContract $encrypter, $table, $prefix = '')
{
$this->table = $table;
$this->prefix = $prefix;
$this->encrypter = $encrypter;
$this->connection = $connection;
}
/**
* Create a new database store.
*
* @param \Illuminate\Database\ConnectionInterface $connection
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
* @param string $table
* @param string $prefix
* @return void
*/
public function __construct(ConnectionInterface $connection, EncrypterContract $encrypter, $table, $prefix = '')
{
$this->table = $table;
$this->prefix = $prefix;
$this->encrypter = $encrypter;
$this->connection = $connection;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$prefixed = $this->prefix.$key;
/**
* Retrieve an item from the cache by key.
*
* @param string|array $key
* @return mixed
*/
public function get($key)
{
$prefixed = $this->prefix.$key;
$cache = $this->table()->where('key', '=', $prefixed)->first();
$cache = $this->table()->where('key', '=', $prefixed)->first();
// If we have a cache record we will check the expiration time against current
// time on the system and see if the record has expired. If it has, we will
// remove the records from the database table so it isn't returned again.
if ( ! is_null($cache))
{
if (is_array($cache)) $cache = (object) $cache;
// If we have a cache record we will check the expiration time against current
// time on the system and see if the record has expired. If it has, we will
// remove the records from the database table so it isn't returned again.
if (! is_null($cache)) {
if (is_array($cache)) {
$cache = (object) $cache;
}
if (time() >= $cache->expiration)
{
$this->forget($key);
if (time() >= $cache->expiration) {
$this->forget($key);
return;
}
return;
}
return $this->encrypter->decrypt($cache->value);
}
}
return $this->encrypter->decrypt($cache->value);
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$key = $this->prefix.$key;
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$key = $this->prefix.$key;
// All of the cached values in the database are encrypted in case this is used
// as a session data store by the consumer. We'll also calculate the expire
// time and place that on the table so we will check it on our retrieval.
$value = $this->encrypter->encrypt($value);
// All of the cached values in the database are encrypted in case this is used
// as a session data store by the consumer. We'll also calculate the expire
// time and place that on the table so we will check it on our retrieval.
$value = $this->encrypter->encrypt($value);
$expiration = $this->getTime() + ($minutes * 60);
$expiration = $this->getTime() + ($minutes * 60);
try
{
$this->table()->insert(compact('key', 'value', 'expiration'));
}
catch (Exception $e)
{
$this->table()->where('key', '=', $key)->update(compact('value', 'expiration'));
}
}
try {
$this->table()->insert(compact('key', 'value', 'expiration'));
} catch (Exception $e) {
$this->table()->where('key', '=', $key)->update(compact('value', 'expiration'));
}
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*
* @throws \LogicException
*/
public function increment($key, $value = 1)
{
throw new LogicException("Increment operations not supported by this driver.");
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value = 1)
{
return $this->incrementOrDecrement($key, $value, function ($current, $value) {
return $current + $value;
});
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*
* @throws \LogicException
*/
public function decrement($key, $value = 1)
{
throw new LogicException("Decrement operations not supported by this driver.");
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value = 1)
{
return $this->incrementOrDecrement($key, $value, function ($current, $value) {
return $current - $value;
});
}
/**
* Get the current system time.
*
* @return int
*/
protected function getTime()
{
return time();
}
/**
* Increment or decrement an item in the cache.
*
* @param string $key
* @param mixed $value
* @param \Closure $callback
* @return int|bool
*/
protected function incrementOrDecrement($key, $value, Closure $callback)
{
return $this->connection->transaction(function () use ($key, $value, $callback) {
$prefixed = $this->prefix.$key;
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->put($key, $value, 5256000);
}
$cache = $this->table()->where('key', $prefixed)->lockForUpdate()->first();
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
$this->table()->where('key', '=', $this->prefix.$key)->delete();
if (is_null($cache)) {
return false;
}
return true;
}
if (is_array($cache)) {
$cache = (object) $cache;
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->table()->delete();
}
$current = $this->encrypter->decrypt($cache->value);
$new = $callback($current, $value);
/**
* Get a query builder for the cache table.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function table()
{
return $this->connection->table($this->table);
}
if (! is_numeric($current)) {
return false;
}
/**
* Get the underlying database connection.
*
* @return \Illuminate\Database\ConnectionInterface
*/
public function getConnection()
{
return $this->connection;
}
$this->table()->where('key', $prefixed)->update([
'value' => $this->encrypter->encrypt($new),
]);
/**
* Get the encrypter instance.
*
* @return \Illuminate\Contracts\Encryption\Encrypter
*/
public function getEncrypter()
{
return $this->encrypter;
}
return $new;
});
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* Get the current system time.
*
* @return int
*/
protected function getTime()
{
return time();
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->put($key, $value, 5256000);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
$this->table()->where('key', '=', $this->prefix.$key)->delete();
return true;
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->table()->delete();
}
/**
* Get a query builder for the cache table.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function table()
{
return $this->connection->table($this->table);
}
/**
* Get the underlying database connection.
*
* @return \Illuminate\Database\ConnectionInterface
*/
public function getConnection()
{
return $this->connection;
}
/**
* Get the encrypter instance.
*
* @return \Illuminate\Contracts\Encryption\Encrypter
*/
public function getEncrypter()
{
return $this->encrypter;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Illuminate\Cache\Events;
class CacheHit
{
/**
* The key that was hit.
*
* @var string
*/
public $key;
/**
* The value that was retrieved.
*
* @var mixed
*/
public $value;
/**
* The tags that were assigned to the key.
*
* @var array
*/
public $tags;
/**
* Create a new event instance.
*
* @param string $key
* @param mixed $value
* @param array $tags
* @return void
*/
public function __construct($key, $value, array $tags = [])
{
$this->key = $key;
$this->tags = $tags;
$this->value = $value;
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Illuminate\Cache\Events;
class CacheMissed
{
/**
* THe key that was missed.
*
* @var string
*/
public $key;
/**
* The tags that were assigned to the key.
*
* @var array
*/
public $tags;
/**
* Create a new event instance.
*
* @param string $key
* @param array $tags
* @return void
*/
public function __construct($key, array $tags = [])
{
$this->key = $key;
$this->tags = $tags;
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Illuminate\Cache\Events;
class KeyForgotten
{
/**
* The key that was forgotten.
*
* @var string
*/
public $key;
/**
* The tags that were assigned to the key.
*
* @var array
*/
public $tags;
/**
* Create a new event instance.
*
* @param string $key
* @param array $tags
* @return void
*/
public function __construct($key, $tags = [])
{
$this->key = $key;
$this->tags = $tags;
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Illuminate\Cache\Events;
class KeyWritten
{
/**
* The key that was written.
*
* @var string
*/
public $key;
/**
* The value that was written.
*
* @var mixed
*/
public $value;
/**
* The number of minutes the key should be valid.
*
* @var int
*/
public $minutes;
/**
* The tags that were assigned to the key.
*
* @var array
*/
public $tags;
/**
* Create a new event instance.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @param array $tags
* @return void
*/
public function __construct($key, $value, $minutes, $tags = [])
{
$this->key = $key;
$this->tags = $tags;
$this->value = $value;
$this->minutes = $minutes;
}
}

View File

@@ -1,256 +1,254 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Exception;
use Illuminate\Support\Arr;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Contracts\Cache\Store;
class FileStore implements Store {
class FileStore implements Store
{
use RetrievesMultipleKeys;
/**
* The Illuminate Filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The Illuminate Filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The file cache directory.
*
* @var string
*/
protected $directory;
/**
* The file cache directory.
*
* @var string
*/
protected $directory;
/**
* Create a new file cache store instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param string $directory
* @return void
*/
public function __construct(Filesystem $files, $directory)
{
$this->files = $files;
$this->directory = $directory;
}
/**
* Create a new file cache store instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param string $directory
* @return void
*/
public function __construct(Filesystem $files, $directory)
{
$this->files = $files;
$this->directory = $directory;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
return array_get($this->getPayload($key), 'data');
}
/**
* Retrieve an item from the cache by key.
*
* @param string|array $key
* @return mixed
*/
public function get($key)
{
return Arr::get($this->getPayload($key), 'data');
}
/**
* Retrieve an item and expiry time from the cache by key.
*
* @param string $key
* @return array
*/
protected function getPayload($key)
{
$path = $this->path($key);
/**
* Retrieve an item and expiry time from the cache by key.
*
* @param string $key
* @return array
*/
protected function getPayload($key)
{
$path = $this->path($key);
// If the file doesn't exists, we obviously can't return the cache so we will
// just return null. Otherwise, we'll get the contents of the file and get
// the expiration UNIX timestamps from the start of the file's contents.
try
{
$expire = substr($contents = $this->files->get($path), 0, 10);
}
catch (Exception $e)
{
return array('data' => null, 'time' => null);
}
// If the file doesn't exists, we obviously can't return the cache so we will
// just return null. Otherwise, we'll get the contents of the file and get
// the expiration UNIX timestamps from the start of the file's contents.
try {
$expire = substr(
$contents = $this->files->get($path, true), 0, 10
);
} catch (Exception $e) {
return ['data' => null, 'time' => null];
}
// If the current time is greater than expiration timestamps we will delete
// the file and return null. This helps clean up the old files and keeps
// this directory much cleaner for us as old files aren't hanging out.
if (time() >= $expire)
{
$this->forget($key);
// If the current time is greater than expiration timestamps we will delete
// the file and return null. This helps clean up the old files and keeps
// this directory much cleaner for us as old files aren't hanging out.
if (time() >= $expire) {
$this->forget($key);
return array('data' => null, 'time' => null);
}
return ['data' => null, 'time' => null];
}
$data = unserialize(substr($contents, 10));
$data = unserialize(substr($contents, 10));
// Next, we'll extract the number of minutes that are remaining for a cache
// so that we can properly retain the time for things like the increment
// operation that may be performed on the cache. We'll round this out.
$time = ceil(($expire - time()) / 60);
// Next, we'll extract the number of minutes that are remaining for a cache
// so that we can properly retain the time for things like the increment
// operation that may be performed on the cache. We'll round this out.
$time = ceil(($expire - time()) / 60);
return compact('data', 'time');
}
return compact('data', 'time');
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$value = $this->expiration($minutes).serialize($value);
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$value = $this->expiration($minutes).serialize($value);
$this->createCacheDirectory($path = $this->path($key));
$this->createCacheDirectory($path = $this->path($key));
$this->files->put($path, $value);
}
$this->files->put($path, $value, true);
}
/**
* Create the file cache directory if necessary.
*
* @param string $path
* @return void
*/
protected function createCacheDirectory($path)
{
try
{
$this->files->makeDirectory(dirname($path), 0777, true, true);
}
catch (Exception $e)
{
//
}
}
/**
* Create the file cache directory if necessary.
*
* @param string $path
* @return void
*/
protected function createCacheDirectory($path)
{
if (! $this->files->exists(dirname($path))) {
$this->files->makeDirectory(dirname($path), 0777, true, true);
}
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function increment($key, $value = 1)
{
$raw = $this->getPayload($key);
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function increment($key, $value = 1)
{
$raw = $this->getPayload($key);
$int = ((int) $raw['data']) + $value;
$int = ((int) $raw['data']) + $value;
$this->put($key, $int, (int) $raw['time']);
$this->put($key, $int, (int) $raw['time']);
return $int;
}
return $int;
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function decrement($key, $value = 1)
{
return $this->increment($key, $value * -1);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function decrement($key, $value = 1)
{
return $this->increment($key, $value * -1);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
$file = $this->path($key);
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
$file = $this->path($key);
if ($this->files->exists($file))
{
return $this->files->delete($file);
}
if ($this->files->exists($file)) {
return $this->files->delete($file);
}
return false;
}
return false;
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
if ($this->files->isDirectory($this->directory))
{
foreach ($this->files->directories($this->directory) as $directory)
{
$this->files->deleteDirectory($directory);
}
}
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
if ($this->files->isDirectory($this->directory)) {
foreach ($this->files->directories($this->directory) as $directory) {
$this->files->deleteDirectory($directory);
}
}
}
/**
* Get the full path for the given cache key.
*
* @param string $key
* @return string
*/
protected function path($key)
{
$parts = array_slice(str_split($hash = md5($key), 2), 0, 2);
/**
* Get the full path for the given cache key.
*
* @param string $key
* @return string
*/
protected function path($key)
{
$parts = array_slice(str_split($hash = sha1($key), 2), 0, 2);
return $this->directory.'/'.implode('/', $parts).'/'.$hash;
}
return $this->directory.'/'.implode('/', $parts).'/'.$hash;
}
/**
* Get the expiration time based on the given minutes.
*
* @param int $minutes
* @return int
*/
protected function expiration($minutes)
{
if ($minutes === 0) return 9999999999;
/**
* Get the expiration time based on the given minutes.
*
* @param int $minutes
* @return int
*/
protected function expiration($minutes)
{
$time = time() + ($minutes * 60);
return time() + ($minutes * 60);
}
if ($minutes === 0 || $time > 9999999999) {
return 9999999999;
}
/**
* Get the Filesystem instance.
*
* @return \Illuminate\Filesystem\Filesystem
*/
public function getFilesystem()
{
return $this->files;
}
return (int) $time;
}
/**
* Get the working directory of the cache.
*
* @return string
*/
public function getDirectory()
{
return $this->directory;
}
/**
* Get the Filesystem instance.
*
* @return \Illuminate\Filesystem\Filesystem
*/
public function getFilesystem()
{
return $this->files;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return '';
}
/**
* Get the working directory of the cache.
*
* @return string
*/
public function getDirectory()
{
return $this->directory;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return '';
}
}

View File

@@ -1,55 +1,53 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Memcached;
use RuntimeException;
class MemcachedConnector {
class MemcachedConnector
{
/**
* Create a new Memcached connection.
*
* @param array $servers
* @return \Memcached
*
* @throws \RuntimeException
*/
public function connect(array $servers)
{
$memcached = $this->getMemcached();
/**
* Create a new Memcached connection.
*
* @param array $servers
* @return \Memcached
*
* @throws \RuntimeException
*/
public function connect(array $servers)
{
$memcached = $this->getMemcached();
// For each server in the array, we'll just extract the configuration and add
// the server to the Memcached connection. Once we have added all of these
// servers we'll verify the connection is successful and return it back.
foreach ($servers as $server) {
$memcached->addServer(
$server['host'], $server['port'], $server['weight']
);
}
// For each server in the array, we'll just extract the configuration and add
// the server to the Memcached connection. Once we have added all of these
// servers we'll verify the connection is successful and return it back.
foreach ($servers as $server)
{
$memcached->addServer(
$server['host'], $server['port'], $server['weight']
);
}
$memcachedStatus = $memcached->getVersion();
$memcachedStatus = $memcached->getVersion();
if (! is_array($memcachedStatus)) {
throw new RuntimeException('No Memcached servers added.');
}
if ( ! is_array($memcachedStatus))
{
throw new RuntimeException("No Memcached servers added.");
}
if (in_array('255.255.255', $memcachedStatus) && count(array_unique($memcachedStatus)) === 1) {
throw new RuntimeException('Could not establish Memcached connection.');
}
if (in_array('255.255.255', $memcachedStatus) && count(array_unique($memcachedStatus)) === 1)
{
throw new RuntimeException("Could not establish Memcached connection.");
}
return $memcached;
}
/**
* Get a new Memcached instance.
*
* @return \Memcached
*/
protected function getMemcached()
{
return new Memcached;
}
return $memcached;
}
/**
* Get a new Memcached instance.
*
* @return \Memcached
*/
protected function getMemcached()
{
return new Memcached;
}
}

View File

@@ -1,153 +1,206 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Memcached;
use Illuminate\Contracts\Cache\Store;
class MemcachedStore extends TaggableStore implements Store {
class MemcachedStore extends TaggableStore implements Store
{
/**
* The Memcached instance.
*
* @var \Memcached
*/
protected $memcached;
/**
* The Memcached instance.
*
* @var \Memcached
*/
protected $memcached;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new Memcached store.
*
* @param \Memcached $memcached
* @param string $prefix
* @return void
*/
public function __construct($memcached, $prefix = '')
{
$this->setPrefix($prefix);
$this->memcached = $memcached;
}
/**
* Create a new Memcached store.
*
* @param \Memcached $memcached
* @param string $prefix
* @return void
*/
public function __construct($memcached, $prefix = '')
{
$this->memcached = $memcached;
$this->prefix = strlen($prefix) > 0 ? $prefix.':' : '';
}
/**
* Retrieve an item from the cache by key.
*
* @param string|array $key
* @return mixed
*/
public function get($key)
{
$value = $this->memcached->get($this->prefix.$key);
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$value = $this->memcached->get($this->prefix.$key);
if ($this->memcached->getResultCode() == 0) {
return $value;
}
}
if ($this->memcached->getResultCode() == 0)
{
return $value;
}
}
/**
* Retrieve multiple items from the cache by key.
*
* Items not found in the cache will have a null value.
*
* @param array $keys
* @return array
*/
public function many(array $keys)
{
$prefixedKeys = array_map(function ($key) {
return $this->prefix.$key;
}, $keys);
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$this->memcached->set($this->prefix.$key, $value, $minutes * 60);
}
$values = $this->memcached->getMulti($prefixedKeys, null, Memcached::GET_PRESERVE_ORDER);
/**
* Store an item in the cache if the key doesn't exist.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return bool
*/
public function add($key, $value, $minutes)
{
return $this->memcached->add($this->prefix.$key, $value, $minutes * 60);
}
if ($this->memcached->getResultCode() != 0) {
return array_fill_keys($keys, null);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value = 1)
{
return $this->memcached->increment($this->prefix.$key, $value);
}
return array_combine($keys, $values);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value = 1)
{
return $this->memcached->decrement($this->prefix.$key, $value);
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$this->memcached->set($this->prefix.$key, $value, $minutes * 60);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
}
/**
* Store multiple items in the cache for a given number of minutes.
*
* @param array $values
* @param int $minutes
* @return void
*/
public function putMany(array $values, $minutes)
{
$prefixedValues = [];
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return $this->memcached->delete($this->prefix.$key);
}
foreach ($values as $key => $value) {
$prefixedValues[$this->prefix.$key] = $value;
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->memcached->flush();
}
$this->memcached->setMulti($prefixedValues, $minutes * 60);
}
/**
* Get the underlying Memcached connection.
*
* @return \Memcached
*/
public function getMemcached()
{
return $this->memcached;
}
/**
* Store an item in the cache if the key doesn't exist.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return bool
*/
public function add($key, $value, $minutes)
{
return $this->memcached->add($this->prefix.$key, $value, $minutes * 60);
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value = 1)
{
return $this->memcached->increment($this->prefix.$key, $value);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value = 1)
{
return $this->memcached->decrement($this->prefix.$key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return $this->memcached->delete($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->memcached->flush();
}
/**
* Get the underlying Memcached connection.
*
* @return \Memcached
*/
public function getMemcached()
{
return $this->memcached;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* Set the cache key prefix.
*
* @param string $prefix
* @return void
*/
public function setPrefix($prefix)
{
$this->prefix = ! empty($prefix) ? $prefix.':' : '';
}
}

View File

@@ -1,105 +1,108 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
class NullStore extends TaggableStore implements Store {
class NullStore extends TaggableStore implements Store
{
use RetrievesMultipleKeys;
/**
* The array of stored values.
*
* @var array
*/
protected $storage = array();
/**
* The array of stored values.
*
* @var array
*/
protected $storage = [];
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
//
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
//
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
//
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
//
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function increment($key, $value = 1)
{
//
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function increment($key, $value = 1)
{
//
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function decrement($key, $value = 1)
{
//
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function decrement($key, $value = 1)
{
//
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
//
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
//
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
//
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
//
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
//
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return '';
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
//
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return '';
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Repository as Cache;
class RateLimiter
{
/**
* The cache store implementation.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;
/**
* Create a new rate limiter instance.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @return void
*/
public function __construct(Cache $cache)
{
$this->cache = $cache;
}
/**
* Determine if the given key has been "accessed" too many times.
*
* @param string $key
* @param int $maxAttempts
* @param int $decayMinutes
* @return bool
*/
public function tooManyAttempts($key, $maxAttempts, $decayMinutes = 1)
{
if ($this->cache->has($key.':lockout')) {
return true;
}
if ($this->attempts($key) > $maxAttempts) {
$this->cache->add($key.':lockout', time() + ($decayMinutes * 60), $decayMinutes);
$this->resetAttempts($key);
return true;
}
return false;
}
/**
* Increment the counter for a given key for a given decay time.
*
* @param string $key
* @param int $decayMinutes
* @return int
*/
public function hit($key, $decayMinutes = 1)
{
$this->cache->add($key, 1, $decayMinutes);
return (int) $this->cache->increment($key);
}
/**
* Get the number of attempts for the given key.
*
* @param string $key
* @return mixed
*/
public function attempts($key)
{
return $this->cache->get($key, 0);
}
/**
* Reset the number of attempts for the given key.
*
* @param string $key
* @return mixed
*/
public function resetAttempts($key)
{
return $this->cache->forget($key);
}
/**
* Get the number of retries left for the given key.
*
* @param string $key
* @param int $maxAttempts
* @return int
*/
public function retriesLeft($key, $maxAttempts)
{
$attempts = $this->attempts($key);
return $attempts === 0 ? $maxAttempts : $maxAttempts - $attempts + 1;
}
/**
* Clear the hits and lockout for the given key.
*
* @param string $key
* @return void
*/
public function clear($key)
{
$this->resetAttempts($key);
$this->cache->forget($key.':lockout');
}
/**
* Get the number of seconds until the "key" is accessible again.
*
* @param string $key
* @return int
*/
public function availableIn($key)
{
return $this->cache->get($key.':lockout') - time();
}
}

View File

@@ -1,186 +1,238 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Redis\Database as Redis;
class RedisStore extends TaggableStore implements Store {
class RedisStore extends TaggableStore implements Store
{
/**
* The Redis database connection.
*
* @var \Illuminate\Redis\Database
*/
protected $redis;
/**
* The Redis database connection.
*
* @var \Illuminate\Redis\Database
*/
protected $redis;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* The Redis connection that should be used.
*
* @var string
*/
protected $connection;
/**
* The Redis connection that should be used.
*
* @var string
*/
protected $connection;
/**
* Create a new Redis store.
*
* @param \Illuminate\Redis\Database $redis
* @param string $prefix
* @param string $connection
* @return void
*/
public function __construct(Redis $redis, $prefix = '', $connection = 'default')
{
$this->redis = $redis;
$this->setPrefix($prefix);
$this->connection = $connection;
}
/**
* Create a new Redis store.
*
* @param \Illuminate\Redis\Database $redis
* @param string $prefix
* @param string $connection
* @return void
*/
public function __construct(Redis $redis, $prefix = '', $connection = 'default')
{
$this->redis = $redis;
$this->connection = $connection;
$this->prefix = strlen($prefix) > 0 ? $prefix.':' : '';
}
/**
* Retrieve an item from the cache by key.
*
* @param string|array $key
* @return mixed
*/
public function get($key)
{
if (! is_null($value = $this->connection()->get($this->prefix.$key))) {
return is_numeric($value) ? $value : unserialize($value);
}
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
if ( ! is_null($value = $this->connection()->get($this->prefix.$key)))
{
return is_numeric($value) ? $value : unserialize($value);
}
}
/**
* Retrieve multiple items from the cache by key.
*
* Items not found in the cache will have a null value.
*
* @param array $keys
* @return array
*/
public function many(array $keys)
{
$return = [];
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$value = is_numeric($value) ? $value : serialize($value);
$prefixedKeys = array_map(function ($key) {
return $this->prefix.$key;
}, $keys);
$minutes = max(1, $minutes);
$values = $this->connection()->mget($prefixedKeys);
$this->connection()->setex($this->prefix.$key, $minutes * 60, $value);
}
foreach ($values as $index => $value) {
$return[$keys[$index]] = is_numeric($value) ? $value : unserialize($value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function increment($key, $value = 1)
{
return $this->connection()->incrby($this->prefix.$key, $value);
}
return $return;
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function decrement($key, $value = 1)
{
return $this->connection()->decrby($this->prefix.$key, $value);
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$value = is_numeric($value) ? $value : serialize($value);
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$value = is_numeric($value) ? $value : serialize($value);
$this->connection()->setex($this->prefix.$key, (int) max(1, $minutes * 60), $value);
}
$this->connection()->set($this->prefix.$key, $value);
}
/**
* Store multiple items in the cache for a given number of minutes.
*
* @param array $values
* @param int $minutes
* @return void
*/
public function putMany(array $values, $minutes)
{
$this->connection()->multi();
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return (bool) $this->connection()->del($this->prefix.$key);
}
foreach ($values as $key => $value) {
$this->put($key, $value, $minutes);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->connection()->flushdb();
}
$this->connection()->exec();
}
/**
* Begin executing a new tags operation.
*
* @param array|mixed $names
* @return \Illuminate\Cache\RedisTaggedCache
*/
public function tags($names)
{
return new RedisTaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args()));
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function increment($key, $value = 1)
{
return $this->connection()->incrby($this->prefix.$key, $value);
}
/**
* Get the Redis connection instance.
*
* @return \Predis\ClientInterface
*/
public function connection()
{
return $this->redis->connection($this->connection);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function decrement($key, $value = 1)
{
return $this->connection()->decrby($this->prefix.$key, $value);
}
/**
* Set the connection name to be used.
*
* @param string $connection
* @return void
*/
public function setConnection($connection)
{
$this->connection = $connection;
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$value = is_numeric($value) ? $value : serialize($value);
/**
* Get the Redis database instance.
*
* @return \Illuminate\Redis\Database
*/
public function getRedis()
{
return $this->redis;
}
$this->connection()->set($this->prefix.$key, $value);
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return (bool) $this->connection()->del($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->connection()->flushdb();
}
/**
* Begin executing a new tags operation.
*
* @param array|mixed $names
* @return \Illuminate\Cache\RedisTaggedCache
*/
public function tags($names)
{
return new RedisTaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args()));
}
/**
* Get the Redis connection instance.
*
* @return \Predis\ClientInterface
*/
public function connection()
{
return $this->redis->connection($this->connection);
}
/**
* Set the connection name to be used.
*
* @param string $connection
* @return void
*/
public function setConnection($connection)
{
$this->connection = $connection;
}
/**
* Get the Redis database instance.
*
* @return \Illuminate\Redis\Database
*/
public function getRedis()
{
return $this->redis;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* Set the cache key prefix.
*
* @param string $prefix
* @return void
*/
public function setPrefix($prefix)
{
$this->prefix = ! empty($prefix) ? $prefix.':' : '';
}
}

View File

@@ -1,90 +1,164 @@
<?php namespace Illuminate\Cache;
<?php
class RedisTaggedCache extends TaggedCache {
namespace Illuminate\Cache;
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->pushForeverKeys($namespace = $this->tags->getNamespace(), $key);
class RedisTaggedCache extends TaggedCache
{
/**
* Forever reference key.
*
* @var string
*/
const REFERENCE_KEY_FOREVER = 'forever_ref';
/**
* Standard reference key.
*
* @var string
*/
const REFERENCE_KEY_STANDARD = 'standard_ref';
$this->store->forever(sha1($namespace).':'.$key, $value);
}
/**
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return void
*/
public function put($key, $value, $minutes = null)
{
$this->pushStandardKeys($this->tags->getNamespace(), $key);
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->deleteForeverKeys();
parent::put($key, $value, $minutes);
}
parent::flush();
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->pushForeverKeys($this->tags->getNamespace(), $key);
/**
* Store a copy of the full key for each namespace segment.
*
* @param string $namespace
* @param string $key
* @return void
*/
protected function pushForeverKeys($namespace, $key)
{
$fullKey = $this->getPrefix().sha1($namespace).':'.$key;
parent::forever($key, $value);
}
foreach (explode('|', $namespace) as $segment)
{
$this->store->connection()->lpush($this->foreverKey($segment), $fullKey);
}
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->deleteForeverKeys();
$this->deleteStandardKeys();
/**
* Delete all of the items that were stored forever.
*
* @return void
*/
protected function deleteForeverKeys()
{
foreach (explode('|', $this->tags->getNamespace()) as $segment)
{
$this->deleteForeverValues($segment = $this->foreverKey($segment));
parent::flush();
}
$this->store->connection()->del($segment);
}
}
/**
* Store standard key references into store.
*
* @param string $namespace
* @param string $key
* @return void
*/
protected function pushStandardKeys($namespace, $key)
{
$this->pushKeys($namespace, $key, self::REFERENCE_KEY_STANDARD);
}
/**
* Delete all of the keys that have been stored forever.
*
* @param string $foreverKey
* @return void
*/
protected function deleteForeverValues($foreverKey)
{
$forever = array_unique($this->store->connection()->lrange($foreverKey, 0, -1));
/**
* Store forever key references into store.
*
* @param string $namespace
* @param string $key
* @return void
*/
protected function pushForeverKeys($namespace, $key)
{
$this->pushKeys($namespace, $key, self::REFERENCE_KEY_FOREVER);
}
if (count($forever) > 0)
{
call_user_func_array(array($this->store->connection(), 'del'), $forever);
}
}
/**
* Store a reference to the cache key against the reference key.
*
* @param string $namespace
* @param string $key
* @param string $reference
* @return void
*/
protected function pushKeys($namespace, $key, $reference)
{
$fullKey = $this->getPrefix().sha1($namespace).':'.$key;
/**
* Get the forever reference key for the segment.
*
* @param string $segment
* @return string
*/
protected function foreverKey($segment)
{
return $this->getPrefix().$segment.':forever';
}
foreach (explode('|', $namespace) as $segment) {
$this->store->connection()->sadd($this->referenceKey($segment, $reference), $fullKey);
}
}
/**
* Delete all of the items that were stored forever.
*
* @return void
*/
protected function deleteForeverKeys()
{
$this->deleteKeysByReference(self::REFERENCE_KEY_FOREVER);
}
/**
* Delete all standard items.
*
* @return void
*/
protected function deleteStandardKeys()
{
$this->deleteKeysByReference(self::REFERENCE_KEY_STANDARD);
}
/**
* Find and delete all of the items that were stored against a reference.
*
* @param string $reference
* @return void
*/
protected function deleteKeysByReference($reference)
{
foreach (explode('|', $this->tags->getNamespace()) as $segment) {
$this->deleteValues($segment = $this->referenceKey($segment, $reference));
$this->store->connection()->del($segment);
}
}
/**
* Delete item keys that have been stored against a reference.
*
* @param string $referenceKey
* @return void
*/
protected function deleteValues($referenceKey)
{
$values = array_unique($this->store->connection()->smembers($referenceKey));
if (count($values) > 0) {
call_user_func_array([$this->store->connection(), 'del'], $values);
}
}
/**
* Get the reference key for the segment.
*
* @param string $segment
* @param string $suffix
* @return string
*/
protected function referenceKey($segment, $suffix)
{
return $this->getPrefix().$segment.':'.$suffix;
}
}

View File

@@ -1,369 +1,499 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Closure;
use DateTime;
use ArrayAccess;
use Carbon\Carbon;
use BadMethodCallException;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Cache\Repository as CacheContract;
class Repository implements CacheContract, ArrayAccess {
class Repository implements CacheContract, ArrayAccess
{
use Macroable {
__call as macroCall;
}
use Macroable {
__call as macroCall;
}
/**
* The cache store implementation.
*
* @var \Illuminate\Contracts\Cache\Store
*/
protected $store;
/**
* The cache store implementation.
*
* @var \Illuminate\Contracts\Cache\Store
*/
protected $store;
/**
* The event dispatcher implementation.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;
/**
* The event dispatcher implementation.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;
/**
* The default number of minutes to store items.
*
* @var int
*/
protected $default = 60;
/**
* The default number of minutes to store items.
*
* @var int
*/
protected $default = 60;
/**
* Create a new cache repository instance.
*
* @param \Illuminate\Contracts\Cache\Store $store
* @return void
*/
public function __construct(Store $store)
{
$this->store = $store;
}
/**
* Create a new cache repository instance.
*
* @param \Illuminate\Contracts\Cache\Store $store
*/
public function __construct(Store $store)
{
$this->store = $store;
}
/**
* Set the event dispatcher instance.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function setEventDispatcher(Dispatcher $events)
{
$this->events = $events;
}
/**
* Set the event dispatcher instance.
*
* @param \Illuminate\Contracts\Events\Dispatcher
* @return void
*/
public function setEventDispatcher(Dispatcher $events)
{
$this->events = $events;
}
/**
* Fire an event for this cache instance.
*
* @param string $event
* @param array $payload
* @return void
*/
protected function fireCacheEvent($event, $payload)
{
if (! isset($this->events)) {
return;
}
/**
* Fire an event for this cache instance.
*
* @param string $event
* @param array $payload
* @return void
*/
protected function fireCacheEvent($event, $payload)
{
if (isset($this->events))
{
$this->events->fire('cache.'.$event, $payload);
}
}
switch ($event) {
case 'hit':
if (count($payload) == 2) {
$payload[] = [];
}
/**
* Determine if an item exists in the cache.
*
* @param string $key
* @return bool
*/
public function has($key)
{
return ! is_null($this->get($key));
}
return $this->events->fire(new Events\CacheHit($payload[0], $payload[1], $payload[2]));
case 'missed':
if (count($payload) == 1) {
$payload[] = [];
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
$value = $this->store->get($key);
return $this->events->fire(new Events\CacheMissed($payload[0], $payload[1]));
case 'delete':
if (count($payload) == 1) {
$payload[] = [];
}
if (is_null($value))
{
$this->fireCacheEvent('missed', [$key]);
return $this->events->fire(new Events\KeyForgotten($payload[0], $payload[1]));
case 'write':
if (count($payload) == 3) {
$payload[] = [];
}
$value = value($default);
}
else
{
$this->fireCacheEvent('hit', [$key, $value]);
}
return $this->events->fire(new Events\KeyWritten($payload[0], $payload[1], $payload[2], $payload[3]));
}
}
return $value;
}
/**
* Determine if an item exists in the cache.
*
* @param string $key
* @return bool
*/
public function has($key)
{
return ! is_null($this->get($key));
}
/**
* Retrieve an item from the cache and delete it.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function pull($key, $default = null)
{
$value = $this->get($key, $default);
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
if (is_array($key)) {
return $this->many($key);
}
$this->forget($key);
$value = $this->store->get($this->itemKey($key));
return $value;
}
if (is_null($value)) {
$this->fireCacheEvent('missed', [$key]);
/**
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$minutes = $this->getMinutes($minutes);
$value = value($default);
} else {
$this->fireCacheEvent('hit', [$key, $value]);
}
if ( ! is_null($minutes))
{
$this->store->put($key, $value, $minutes);
return $value;
}
$this->fireCacheEvent('write', [$key, $value, $minutes]);
}
}
/**
* Retrieve multiple items from the cache by key.
*
* Items not found in the cache will have a null value.
*
* @param array $keys
* @return array
*/
public function many(array $keys)
{
$normalizedKeys = [];
/**
* Store an item in the cache if the key does not exist.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return bool
*/
public function add($key, $value, $minutes)
{
if (method_exists($this->store, 'add'))
{
return $this->store->add($key, $value, $minutes);
}
foreach ($keys as $key => $value) {
$normalizedKeys[] = is_string($key) ? $key : $value;
}
if (is_null($this->get($key)))
{
$this->put($key, $value, $minutes);
$values = $this->store->many($normalizedKeys);
return true;
}
foreach ($values as $key => &$value) {
if (is_null($value)) {
$this->fireCacheEvent('missed', [$key]);
return false;
}
$value = isset($keys[$key]) ? value($keys[$key]) : null;
} else {
$this->fireCacheEvent('hit', [$key, $value]);
}
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->store->forever($key, $value);
return $values;
}
$this->fireCacheEvent('write', [$key, $value, 0]);
}
/**
* Retrieve an item from the cache and delete it.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function pull($key, $default = null)
{
$value = $this->get($key, $default);
/**
* Get an item from the cache, or store the default value.
*
* @param string $key
* @param \DateTime|int $minutes
* @param \Closure $callback
* @return mixed
*/
public function remember($key, $minutes, Closure $callback)
{
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes in storage.
if ( ! is_null($value = $this->get($key)))
{
return $value;
}
$this->forget($key);
$this->put($key, $value = $callback(), $minutes);
return $value;
}
return $value;
}
/**
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return void
*/
public function put($key, $value, $minutes = null)
{
if (is_array($key) && filter_var($value, FILTER_VALIDATE_INT) !== false) {
return $this->putMany($key, $value);
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param \Closure $callback
* @return mixed
*/
public function sear($key, Closure $callback)
{
return $this->rememberForever($key, $callback);
}
$minutes = $this->getMinutes($minutes);
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param \Closure $callback
* @return mixed
*/
public function rememberForever($key, Closure $callback)
{
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes. It's easy.
if ( ! is_null($value = $this->get($key)))
{
return $value;
}
if (! is_null($minutes)) {
$this->store->put($this->itemKey($key), $value, $minutes);
$this->forever($key, $value = $callback());
$this->fireCacheEvent('write', [$key, $value, $minutes]);
}
}
return $value;
}
/**
* Store multiple items in the cache for a given number of minutes.
*
* @param array $values
* @param int $minutes
* @return void
*/
public function putMany(array $values, $minutes)
{
$minutes = $this->getMinutes($minutes);
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
$success = $this->store->forget($key);
if (! is_null($minutes)) {
$this->store->putMany($values, $minutes);
$this->fireCacheEvent('delete', [$key]);
foreach ($values as $key => $value) {
$this->fireCacheEvent('write', [$key, $value, $minutes]);
}
}
}
return $success;
}
/**
* Store an item in the cache if the key does not exist.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return bool
*/
public function add($key, $value, $minutes)
{
$minutes = $this->getMinutes($minutes);
/**
* Get the default cache time.
*
* @return int
*/
public function getDefaultCacheTime()
{
return $this->default;
}
if (is_null($minutes)) {
return false;
}
/**
* Set the default cache time in minutes.
*
* @param int $minutes
* @return void
*/
public function setDefaultCacheTime($minutes)
{
$this->default = $minutes;
}
if (method_exists($this->store, 'add')) {
return $this->store->add($this->itemKey($key), $value, $minutes);
}
/**
* Get the cache store implementation.
*
* @return \Illuminate\Contracts\Cache\Store
*/
public function getStore()
{
return $this->store;
}
if (is_null($this->get($key))) {
$this->put($key, $value, $minutes);
/**
* Determine if a cached value exists.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return $this->has($key);
}
return true;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->get($key);
}
return false;
}
/**
* Store an item in the cache for the default time.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value)
{
$this->put($key, $value, $this->default);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->store->forever($this->itemKey($key), $value);
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
$this->forget($key);
}
$this->fireCacheEvent('write', [$key, $value, 0]);
}
/**
* Calculate the number of minutes with the given duration.
*
* @param \DateTime|int $duration
* @return int|null
*/
protected function getMinutes($duration)
{
if ($duration instanceof DateTime)
{
$fromNow = Carbon::instance($duration)->diffInMinutes();
/**
* Get an item from the cache, or store the default value.
*
* @param string $key
* @param \DateTime|int $minutes
* @param \Closure $callback
* @return mixed
*/
public function remember($key, $minutes, Closure $callback)
{
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes in storage.
if (! is_null($value = $this->get($key))) {
return $value;
}
return $fromNow > 0 ? $fromNow : null;
}
$this->put($key, $value = $callback(), $minutes);
return is_string($duration) ? (int) $duration : $duration;
}
return $value;
}
/**
* Handle dynamic calls into macros or pass missing methods to the store.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
if (static::hasMacro($method))
{
return $this->macroCall($method, $parameters);
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param \Closure $callback
* @return mixed
*/
public function sear($key, Closure $callback)
{
return $this->rememberForever($key, $callback);
}
return call_user_func_array(array($this->store, $method), $parameters);
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param \Closure $callback
* @return mixed
*/
public function rememberForever($key, Closure $callback)
{
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes. It's easy.
if (! is_null($value = $this->get($key))) {
return $value;
}
$this->forever($key, $value = $callback());
return $value;
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
$success = $this->store->forget($this->itemKey($key));
$this->fireCacheEvent('delete', [$key]);
return $success;
}
/**
* Begin executing a new tags operation if the store supports it.
*
* @param array|mixed $names
* @return \Illuminate\Cache\TaggedCache
*
* @throws \BadMethodCallException
*/
public function tags($names)
{
if (method_exists($this->store, 'tags')) {
$taggedCache = $this->store->tags($names);
if (! is_null($this->events)) {
$taggedCache->setEventDispatcher($this->events);
}
$taggedCache->setDefaultCacheTime($this->default);
return $taggedCache;
}
throw new BadMethodCallException('This cache store does not support tagging.');
}
/**
* Format the key for a cache item.
*
* @param string $key
* @return string
*/
protected function itemKey($key)
{
return $key;
}
/**
* Get the default cache time.
*
* @return int
*/
public function getDefaultCacheTime()
{
return $this->default;
}
/**
* Set the default cache time in minutes.
*
* @param int $minutes
* @return void
*/
public function setDefaultCacheTime($minutes)
{
$this->default = $minutes;
}
/**
* Get the cache store implementation.
*
* @return \Illuminate\Contracts\Cache\Store
*/
public function getStore()
{
return $this->store;
}
/**
* Determine if a cached value exists.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return $this->has($key);
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->get($key);
}
/**
* Store an item in the cache for the default time.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value)
{
$this->put($key, $value, $this->default);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
$this->forget($key);
}
/**
* Calculate the number of minutes with the given duration.
*
* @param \DateTime|int $duration
* @return int|null
*/
protected function getMinutes($duration)
{
if ($duration instanceof DateTime) {
$fromNow = Carbon::now()->diffInMinutes(Carbon::instance($duration), false);
return $fromNow > 0 ? $fromNow : null;
}
return is_string($duration) ? (int) $duration : $duration;
}
/**
* Handle dynamic calls into macros or pass missing methods to the store.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
if (static::hasMacro($method)) {
return $this->macroCall($method, $parameters);
}
return call_user_func_array([$this->store, $method], $parameters);
}
/**
* Clone cache repository instance.
*
* @return void
*/
public function __clone()
{
$this->store = clone $this->store;
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Illuminate\Cache;
trait RetrievesMultipleKeys
{
/**
* Retrieve multiple items from the cache by key.
*
* Items not found in the cache will have a null value.
*
* @param array $keys
* @return array
*/
public function many(array $keys)
{
$return = [];
foreach ($keys as $key) {
$return[$key] = $this->get($key);
}
return $return;
}
/**
* Store multiple items in the cache for a given number of minutes.
*
* @param array $values
* @param int $minutes
* @return void
*/
public function putMany(array $values, $minutes)
{
foreach ($values as $key => $value) {
$this->put($key, $value, $minutes);
}
}
}

View File

@@ -1,99 +1,110 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
class TagSet {
class TagSet
{
/**
* The cache store implementation.
*
* @var \Illuminate\Contracts\Cache\Store
*/
protected $store;
/**
* The cache store implementation.
*
* @var \Illuminate\Contracts\Cache\Store
*/
protected $store;
/**
* The tag names.
*
* @var array
*/
protected $names = [];
/**
* The tag names.
*
* @var array
*/
protected $names = array();
/**
* Create a new TagSet instance.
*
* @param \Illuminate\Contracts\Cache\Store $store
* @param array $names
* @return void
*/
public function __construct(Store $store, array $names = [])
{
$this->store = $store;
$this->names = $names;
}
/**
* Create a new TagSet instance.
*
* @param \Illuminate\Contracts\Cache\Store $store
* @param array $names
* @return void
*/
public function __construct(Store $store, array $names = array())
{
$this->store = $store;
$this->names = $names;
}
/**
* Reset all tags in the set.
*
* @return void
*/
public function reset()
{
array_walk($this->names, [$this, 'resetTag']);
}
/**
* Reset all tags in the set.
*
* @return void
*/
public function reset()
{
array_walk($this->names, array($this, 'resetTag'));
}
/**
* Get the unique tag identifier for a given tag.
*
* @param string $name
* @return string
*/
public function tagId($name)
{
return $this->store->get($this->tagKey($name)) ?: $this->resetTag($name);
}
/**
* Get the unique tag identifier for a given tag.
*
* @param string $name
* @return string
*/
public function tagId($name)
{
return $this->store->get($this->tagKey($name)) ?: $this->resetTag($name);
}
/**
* Get an array of tag identifiers for all of the tags in the set.
*
* @return array
*/
protected function tagIds()
{
return array_map([$this, 'tagId'], $this->names);
}
/**
* Get an array of tag identifiers for all of the tags in the set.
*
* @return array
*/
protected function tagIds()
{
return array_map(array($this, 'tagId'), $this->names);
}
/**
* Get a unique namespace that changes when any of the tags are flushed.
*
* @return string
*/
public function getNamespace()
{
return implode('|', $this->tagIds());
}
/**
* Get a unique namespace that changes when any of the tags are flushed.
*
* @return string
*/
public function getNamespace()
{
return implode('|', $this->tagIds());
}
/**
* Reset the tag and return the new tag identifier.
*
* @param string $name
* @return string
*/
public function resetTag($name)
{
$this->store->forever($this->tagKey($name), $id = str_replace('.', '', uniqid('', true)));
/**
* Reset the tag and return the new tag identifier.
*
* @param string $name
* @return string
*/
public function resetTag($name)
{
$this->store->forever($this->tagKey($name), $id = str_replace('.', '', uniqid('', true)));
return $id;
}
return $id;
}
/**
* Get the tag identifier key for a given tag.
*
* @param string $name
* @return string
*/
public function tagKey($name)
{
return 'tag:'.$name.':key';
}
/**
* Get the tag identifier key for a given tag.
*
* @param string $name
* @return string
*/
public function tagKey($name)
{
return 'tag:'.$name.':key';
}
/**
* Get all of the tag names in the set.
*
* @return array
*/
public function getNames()
{
return $this->names;
}
}

View File

@@ -1,27 +1,17 @@
<?php namespace Illuminate\Cache;
<?php
abstract class TaggableStore {
/**
* Begin executing a new tags operation.
*
* @param string $name
* @return \Illuminate\Cache\TaggedCache
*/
public function section($name)
{
return $this->tags($name);
}
/**
* Begin executing a new tags operation.
*
* @param array|mixed $names
* @return \Illuminate\Cache\TaggedCache
*/
public function tags($names)
{
return new TaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args()));
}
namespace Illuminate\Cache;
abstract class TaggableStore
{
/**
* Begin executing a new tags operation.
*
* @param array|mixed $names
* @return \Illuminate\Cache\TaggedCache
*/
public function tags($names)
{
return new TaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args()));
}
}

View File

@@ -1,247 +1,94 @@
<?php namespace Illuminate\Cache;
<?php
namespace Illuminate\Cache;
use Closure;
use DateTime;
use Carbon\Carbon;
use Illuminate\Contracts\Cache\Store;
class TaggedCache implements Store {
class TaggedCache extends Repository
{
use RetrievesMultipleKeys;
/**
* The cache store implementation.
*
* @var \Illuminate\Contracts\Cache\Store
*/
protected $store;
/**
* The tag set instance.
*
* @var \Illuminate\Cache\TagSet
*/
protected $tags;
/**
* The tag set instance.
*
* @var \Illuminate\Cache\TagSet
*/
protected $tags;
/**
* Create a new tagged cache instance.
*
* @param \Illuminate\Contracts\Cache\Store $store
* @param \Illuminate\Cache\TagSet $tags
* @return void
*/
public function __construct(Store $store, TagSet $tags)
{
parent::__construct($store);
/**
* Create a new tagged cache instance.
*
* @param \Illuminate\Contracts\Cache\Store $store
* @param \Illuminate\Cache\TagSet $tags
* @return void
*/
public function __construct(Store $store, TagSet $tags)
{
$this->tags = $tags;
$this->store = $store;
}
$this->tags = $tags;
}
/**
* Determine if an item exists in the cache.
*
* @param string $key
* @return bool
*/
public function has($key)
{
return ! is_null($this->get($key));
}
/**
* {@inheritdoc}
*/
protected function fireCacheEvent($event, $payload)
{
$payload[] = $this->tags->getNames();
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
$value = $this->store->get($this->taggedItemKey($key));
parent::fireCacheEvent($event, $payload);
}
return ! is_null($value) ? $value : value($default);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1)
{
$this->store->increment($this->itemKey($key), $value);
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$minutes = $this->getMinutes($minutes);
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1)
{
$this->store->decrement($this->itemKey($key), $value);
}
if ( ! is_null($minutes))
{
$this->store->put($this->taggedItemKey($key), $value, $minutes);
}
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->tags->reset();
}
/**
* Store an item in the cache if the key does not exist.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return bool
*/
public function add($key, $value, $minutes)
{
if (is_null($this->get($key)))
{
$this->put($key, $value, $minutes);
return true;
}
return false;
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1)
{
$this->store->increment($this->taggedItemKey($key), $value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1)
{
$this->store->decrement($this->taggedItemKey($key), $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->store->forever($this->taggedItemKey($key), $value);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return $this->store->forget($this->taggedItemKey($key));
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->tags->reset();
}
/**
* Get an item from the cache, or store the default value.
*
* @param string $key
* @param \DateTime|int $minutes
* @param \Closure $callback
* @return mixed
*/
public function remember($key, $minutes, Closure $callback)
{
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes in storage.
if ( ! is_null($value = $this->get($key))) return $value;
$this->put($key, $value = $callback(), $minutes);
return $value;
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param \Closure $callback
* @return mixed
*/
public function sear($key, Closure $callback)
{
return $this->rememberForever($key, $callback);
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param \Closure $callback
* @return mixed
*/
public function rememberForever($key, Closure $callback)
{
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes. It's easy.
if ( ! is_null($value = $this->get($key))) return $value;
$this->forever($key, $value = $callback());
return $value;
}
/**
* Get a fully qualified key for a tagged item.
*
* @param string $key
* @return string
*/
public function taggedItemKey($key)
{
return sha1($this->tags->getNamespace()).':'.$key;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->store->getPrefix();
}
/**
* Calculate the number of minutes with the given duration.
*
* @param \DateTime|int $duration
* @return int|null
*/
protected function getMinutes($duration)
{
if ($duration instanceof DateTime)
{
$fromNow = Carbon::instance($duration)->diffInMinutes();
return $fromNow > 0 ? $fromNow : null;
}
return is_string($duration) ? (int) $duration : $duration;
}
/**
* {@inheritdoc}
*/
protected function itemKey($key)
{
return $this->taggedItemKey($key);
}
/**
* Get a fully qualified key for a tagged item.
*
* @param string $key
* @return string
*/
public function taggedItemKey($key)
{
return sha1($this->tags->getNamespace()).':'.$key;
}
}

View File

@@ -1,121 +0,0 @@
<?php namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
class WinCacheStore extends TaggableStore implements Store {
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new WinCache store.
*
* @param string $prefix
* @return void
*/
public function __construct($prefix = '')
{
$this->prefix = $prefix;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$value = wincache_ucache_get($this->prefix.$key);
if ($value !== false)
{
return $value;
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
wincache_ucache_set($this->prefix.$key, $value, $minutes * 60);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value = 1)
{
return wincache_ucache_inc($this->prefix.$key, $value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value = 1)
{
return wincache_ucache_dec($this->prefix.$key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return wincache_ucache_delete($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
wincache_ucache_clear();
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
}

View File

@@ -1,121 +0,0 @@
<?php namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
class XCacheStore extends TaggableStore implements Store {
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new WinCache store.
*
* @param string $prefix
* @return void
*/
public function __construct($prefix = '')
{
$this->prefix = $prefix;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$value = xcache_get($this->prefix.$key);
if (isset($value))
{
return $value;
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
xcache_set($this->prefix.$key, $value, $minutes * 60);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function increment($key, $value = 1)
{
return xcache_inc($this->prefix.$key, $value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function decrement($key, $value = 1)
{
return xcache_dec($this->prefix.$key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
return $this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return xcache_unset($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
xcache_clear_cache(XC_TYPE_VAR);
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
}

View File

@@ -14,10 +14,10 @@
}
],
"require": {
"php": ">=5.4.0",
"illuminate/contracts": "5.0.*",
"illuminate/support": "5.0.*",
"nesbot/carbon": "~1.0"
"php": ">=5.5.9",
"illuminate/contracts": "5.2.*",
"illuminate/support": "5.2.*",
"nesbot/carbon": "~1.20"
},
"autoload": {
"psr-4": {
@@ -26,13 +26,13 @@
},
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
"dev-master": "5.2-dev"
}
},
"suggest": {
"illuminate/database": "Required to use the database cache driver (5.0.*).",
"illuminate/filesystem": "Required to use the file cache driver (5.0.*).",
"illuminate/redis": "Required to use the redis cache driver (5.0.*)."
"illuminate/database": "Required to use the database cache driver (5.2.*).",
"illuminate/filesystem": "Required to use the file cache driver (5.2.*).",
"illuminate/redis": "Required to use the redis cache driver (5.2.*)."
},
"minimum-stability": "dev"
}

View File

@@ -1,158 +1,156 @@
<?php namespace Illuminate\Config;
<?php
namespace Illuminate\Config;
use ArrayAccess;
use Illuminate\Support\Arr;
use Illuminate\Contracts\Config\Repository as ConfigContract;
class Repository implements ArrayAccess, ConfigContract {
class Repository implements ArrayAccess, ConfigContract
{
/**
* All of the configuration items.
*
* @var array
*/
protected $items = [];
/**
* All of the configuration items.
*
* @var array
*/
protected $items = [];
/**
* Create a new configuration repository.
*
* @param array $items
* @return void
*/
public function __construct(array $items = [])
{
$this->items = $items;
}
/**
* Create a new configuration repository.
*
* @param array $items
* @return void
*/
public function __construct(array $items = array())
{
$this->items = $items;
}
/**
* Determine if the given configuration value exists.
*
* @param string $key
* @return bool
*/
public function has($key)
{
return Arr::has($this->items, $key);
}
/**
* Determine if the given configuration value exists.
*
* @param string $key
* @return bool
*/
public function has($key)
{
return array_has($this->items, $key);
}
/**
* Get the specified configuration value.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
return Arr::get($this->items, $key, $default);
}
/**
* Get the specified configuration value.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
return array_get($this->items, $key, $default);
}
/**
* Set a given configuration value.
*
* @param array|string $key
* @param mixed $value
* @return void
*/
public function set($key, $value = null)
{
if (is_array($key)) {
foreach ($key as $innerKey => $innerValue) {
Arr::set($this->items, $innerKey, $innerValue);
}
} else {
Arr::set($this->items, $key, $value);
}
}
/**
* Set a given configuration value.
*
* @param array|string $key
* @param mixed $value
* @return void
*/
public function set($key, $value = null)
{
if (is_array($key))
{
foreach ($key as $innerKey => $innerValue)
{
array_set($this->items, $innerKey, $innerValue);
}
}
else
{
array_set($this->items, $key, $value);
}
}
/**
* Prepend a value onto an array configuration value.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function prepend($key, $value)
{
$array = $this->get($key);
/**
* Prepend a value onto an array configuration value.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function prepend($key, $value)
{
$array = $this->get($key);
array_unshift($array, $value);
array_unshift($array, $value);
$this->set($key, $array);
}
$this->set($key, $array);
}
/**
* Push a value onto an array configuration value.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function push($key, $value)
{
$array = $this->get($key);
/**
* Push a value onto an array configuration value.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function push($key, $value)
{
$array = $this->get($key);
$array[] = $value;
$array[] = $value;
$this->set($key, $array);
}
$this->set($key, $array);
}
/**
* Get all of the configuration items for the application.
*
* @return array
*/
public function all()
{
return $this->items;
}
/**
* Get all of the configuration items for the application.
*
* @return array
*/
public function all()
{
return $this->items;
}
/**
* Determine if the given configuration option exists.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return $this->has($key);
}
/**
* Determine if the given configuration option exists.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return $this->has($key);
}
/**
* Get a configuration option.
*
* @param string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->get($key);
}
/**
* Get a configuration option.
*
* @param string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->get($key);
}
/**
* Set a configuration option.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value)
{
$this->set($key, $value);
}
/**
* Unset a configuration option.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
$this->set($key, null);
}
/**
* Set a configuration option.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value)
{
$this->set($key, $value);
}
/**
* Unset a configuration option.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
$this->set($key, null);
}
}

View File

@@ -14,9 +14,10 @@
}
],
"require": {
"php": ">=5.4.0",
"illuminate/contracts": "5.0.*",
"illuminate/support": "5.0.*"
"php": ">=5.5.9",
"illuminate/contracts": "5.2.*",
"illuminate/filesystem": "5.2.*",
"illuminate/support": "5.2.*"
},
"autoload": {
"psr-4": {
@@ -25,7 +26,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
"dev-master": "5.2-dev"
}
},
"minimum-stability": "dev"

View File

@@ -1,29 +1,18 @@
<?php namespace Illuminate\Console;
<?php
use RuntimeException;
namespace Illuminate\Console;
trait AppNamespaceDetectorTrait {
/**
* Get the application namespace from the Composer file.
*
* @return string
*
* @throws \RuntimeException
*/
protected function getAppNamespace()
{
$composer = json_decode(file_get_contents(base_path().'/composer.json'), true);
foreach ((array) data_get($composer, 'autoload.psr-4') as $namespace => $path)
{
foreach ((array) $path as $pathChoice)
{
if (realpath(app_path()) == realpath(base_path().'/'.$pathChoice)) return $namespace;
}
}
throw new RuntimeException("Unable to detect application namespace.");
}
use Illuminate\Container\Container;
trait AppNamespaceDetectorTrait
{
/**
* Get the application namespace.
*
* @return string
*/
protected function getAppNamespace()
{
return Container::getInstance()->getNamespace();
}
}

View File

@@ -1,4 +1,6 @@
<?php namespace Illuminate\Console;
<?php
namespace Illuminate\Console;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Container\Container;
@@ -9,159 +11,162 @@ use Symfony\Component\Console\Application as SymfonyApplication;
use Symfony\Component\Console\Command\Command as SymfonyCommand;
use Illuminate\Contracts\Console\Application as ApplicationContract;
class Application extends SymfonyApplication implements ApplicationContract {
class Application extends SymfonyApplication implements ApplicationContract
{
/**
* The Laravel application instance.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $laravel;
/**
* The Laravel application instance.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $laravel;
/**
* The output from the previous command.
*
* @var \Symfony\Component\Console\Output\BufferedOutput
*/
protected $lastOutput;
/**
* The output from the previous command.
*
* @var \Symfony\Component\Console\Output\BufferedOutput
*/
protected $lastOutput;
/**
* Create a new Artisan console application.
*
* @param \Illuminate\Contracts\Container\Container $laravel
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @param string $version
* @return void
*/
public function __construct(Container $laravel, Dispatcher $events, $version)
{
parent::__construct('Laravel Framework', $version);
/**
* Create a new Artisan console application.
*
* @param \Illuminate\Contracts\Container\Container $laravel
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @param string $version
* @return void
*/
public function __construct(Container $laravel, Dispatcher $events, $version)
{
parent::__construct('Laravel Framework', $version);
$this->laravel = $laravel;
$this->setAutoExit(false);
$this->setCatchExceptions(false);
$this->laravel = $laravel;
$this->setAutoExit(false);
$this->setCatchExceptions(false);
$events->fire(new Events\ArtisanStarting($this));
}
$events->fire('artisan.start', [$this]);
}
/**
* Run an Artisan console command by name.
*
* @param string $command
* @param array $parameters
* @return int
*/
public function call($command, array $parameters = [])
{
$parameters = collect($parameters)->prepend($command);
/**
* Run an Artisan console command by name.
*
* @param string $command
* @param array $parameters
* @return int
*/
public function call($command, array $parameters = array())
{
$parameters['command'] = $command;
$this->lastOutput = new BufferedOutput;
$this->lastOutput = new BufferedOutput;
$this->setCatchExceptions(false);
return $this->find($command)->run(new ArrayInput($parameters), $this->lastOutput);
}
$result = $this->run(new ArrayInput($parameters->toArray()), $this->lastOutput);
/**
* Get the output for the last run command.
*
* @return string
*/
public function output()
{
return $this->lastOutput ? $this->lastOutput->fetch() : '';
}
$this->setCatchExceptions(true);
/**
* Add a command to the console.
*
* @param \Symfony\Component\Console\Command\Command $command
* @return \Symfony\Component\Console\Command\Command
*/
public function add(SymfonyCommand $command)
{
if ($command instanceof Command)
{
$command->setLaravel($this->laravel);
}
return $result;
}
return $this->addToParent($command);
}
/**
* Get the output for the last run command.
*
* @return string
*/
public function output()
{
return $this->lastOutput ? $this->lastOutput->fetch() : '';
}
/**
* Add the command to the parent instance.
*
* @param \Symfony\Component\Console\Command\Command $command
* @return \Symfony\Component\Console\Command\Command
*/
protected function addToParent(SymfonyCommand $command)
{
return parent::add($command);
}
/**
* Add a command to the console.
*
* @param \Symfony\Component\Console\Command\Command $command
* @return \Symfony\Component\Console\Command\Command
*/
public function add(SymfonyCommand $command)
{
if ($command instanceof Command) {
$command->setLaravel($this->laravel);
}
/**
* Add a command, resolving through the application.
*
* @param string $command
* @return \Symfony\Component\Console\Command\Command
*/
public function resolve($command)
{
return $this->add($this->laravel->make($command));
}
return $this->addToParent($command);
}
/**
* Resolve an array of commands through the application.
*
* @param array|mixed $commands
* @return $this
*/
public function resolveCommands($commands)
{
$commands = is_array($commands) ? $commands : func_get_args();
/**
* Add the command to the parent instance.
*
* @param \Symfony\Component\Console\Command\Command $command
* @return \Symfony\Component\Console\Command\Command
*/
protected function addToParent(SymfonyCommand $command)
{
return parent::add($command);
}
foreach ($commands as $command)
{
$this->resolve($command);
}
/**
* Add a command, resolving through the application.
*
* @param string $command
* @return \Symfony\Component\Console\Command\Command
*/
public function resolve($command)
{
return $this->add($this->laravel->make($command));
}
return $this;
}
/**
* Resolve an array of commands through the application.
*
* @param array|mixed $commands
* @return $this
*/
public function resolveCommands($commands)
{
$commands = is_array($commands) ? $commands : func_get_args();
/**
* Get the default input definitions for the applications.
*
* This is used to add the --env option to every available command.
*
* @return \Symfony\Component\Console\Input\InputDefinition
*/
protected function getDefaultInputDefinition()
{
$definition = parent::getDefaultInputDefinition();
foreach ($commands as $command) {
$this->resolve($command);
}
$definition->addOption($this->getEnvironmentOption());
return $this;
}
return $definition;
}
/**
* Get the default input definitions for the applications.
*
* This is used to add the --env option to every available command.
*
* @return \Symfony\Component\Console\Input\InputDefinition
*/
protected function getDefaultInputDefinition()
{
$definition = parent::getDefaultInputDefinition();
/**
* Get the global environment option for the definition.
*
* @return \Symfony\Component\Console\Input\InputOption
*/
protected function getEnvironmentOption()
{
$message = 'The environment the command should run under.';
$definition->addOption($this->getEnvironmentOption());
return new InputOption('--env', null, InputOption::VALUE_OPTIONAL, $message);
}
return $definition;
}
/**
* Get the Laravel application instance.
*
* @return \Illuminate\Contracts\Foundation\Application
*/
public function getLaravel()
{
return $this->laravel;
}
/**
* Get the global environment option for the definition.
*
* @return \Symfony\Component\Console\Input\InputOption
*/
protected function getEnvironmentOption()
{
$message = 'The environment the command should run under.';
return new InputOption('--env', null, InputOption::VALUE_OPTIONAL, $message);
}
/**
* Get the Laravel application instance.
*
* @return \Illuminate\Contracts\Foundation\Application
*/
public function getLaravel()
{
return $this->laravel;
}
}

View File

@@ -1,5 +1,8 @@
<?php namespace Illuminate\Console;
<?php
namespace Illuminate\Console;
use Illuminate\Contracts\Support\Arrayable;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
@@ -7,381 +10,514 @@ use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Illuminate\Contracts\Foundation\Application as LaravelApplication;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Command\Command as SymfonyCommand;
class Command extends \Symfony\Component\Console\Command\Command {
class Command extends SymfonyCommand
{
/**
* The Laravel application instance.
*
* @var \Illuminate\Contracts\Foundation\Application
*/
protected $laravel;
/**
* The Laravel application instance.
*
* @var \Illuminate\Contracts\Foundation\Application
*/
protected $laravel;
/**
* The input interface implementation.
*
* @var \Symfony\Component\Console\Input\InputInterface
*/
protected $input;
/**
* The input interface implementation.
*
* @var \Symfony\Component\Console\Input\InputInterface
*/
protected $input;
/**
* The output interface implementation.
*
* @var \Illuminate\Console\OutputStyle
*/
protected $output;
/**
* The output interface implementation.
*
* @var \Symfony\Component\Console\Output\OutputInterface
*/
protected $output;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature;
/**
* The console command name.
*
* @var string
*/
protected $name;
/**
* The console command name.
*
* @var string
*/
protected $name;
/**
* The console command description.
*
* @var string
*/
protected $description;
/**
* The console command description.
*
* @var string
*/
protected $description;
/**
* Create a new console command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct($this->name);
/**
* The default verbosity of output commands.
*
* @var int
*/
protected $verbosity = OutputInterface::VERBOSITY_NORMAL;
// We will go ahead and set the name, description, and parameters on console
// commands just to make things a little easier on the developer. This is
// so they don't have to all be manually specified in the constructors.
$this->setDescription($this->description);
/**
* The mapping between human readable verbosity levels and Symfony's OutputInterface.
*
* @var array
*/
protected $verbosityMap = [
'v' => OutputInterface::VERBOSITY_VERBOSE,
'vv' => OutputInterface::VERBOSITY_VERY_VERBOSE,
'vvv' => OutputInterface::VERBOSITY_DEBUG,
'quiet' => OutputInterface::VERBOSITY_QUIET,
'normal' => OutputInterface::VERBOSITY_NORMAL,
];
$this->specifyParameters();
}
/**
* Create a new console command instance.
*
* @return void
*/
public function __construct()
{
// We will go ahead and set the name, description, and parameters on console
// commands just to make things a little easier on the developer. This is
// so they don't have to all be manually specified in the constructors.
if (isset($this->signature)) {
$this->configureUsingFluentDefinition();
} else {
parent::__construct($this->name);
}
/**
* Specify the arguments and options on the command.
*
* @return void
*/
protected function specifyParameters()
{
// We will loop through all of the arguments and options for the command and
// set them all on the base command instance. This specifies what can get
// passed into these commands as "parameters" to control the execution.
foreach ($this->getArguments() as $arguments)
{
call_user_func_array(array($this, 'addArgument'), $arguments);
}
$this->setDescription($this->description);
foreach ($this->getOptions() as $options)
{
call_user_func_array(array($this, 'addOption'), $options);
}
}
if (! isset($this->signature)) {
$this->specifyParameters();
}
}
/**
* Run the console command.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return int
*/
public function run(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
/**
* Configure the console command using a fluent definition.
*
* @return void
*/
protected function configureUsingFluentDefinition()
{
list($name, $arguments, $options) = Parser::parse($this->signature);
$this->output = $output;
parent::__construct($name);
return parent::run($input, $output);
}
foreach ($arguments as $argument) {
$this->getDefinition()->addArgument($argument);
}
/**
* Execute the console command.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return mixed
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$method = method_exists($this, 'handle') ? 'handle' : 'fire';
foreach ($options as $option) {
$this->getDefinition()->addOption($option);
}
}
return $this->laravel->call([$this, $method]);
}
/**
* Specify the arguments and options on the command.
*
* @return void
*/
protected function specifyParameters()
{
// We will loop through all of the arguments and options for the command and
// set them all on the base command instance. This specifies what can get
// passed into these commands as "parameters" to control the execution.
foreach ($this->getArguments() as $arguments) {
call_user_func_array([$this, 'addArgument'], $arguments);
}
/**
* Call another console command.
*
* @param string $command
* @param array $arguments
* @return int
*/
public function call($command, array $arguments = array())
{
$instance = $this->getApplication()->find($command);
foreach ($this->getOptions() as $options) {
call_user_func_array([$this, 'addOption'], $options);
}
}
$arguments['command'] = $command;
/**
* Run the console command.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return int
*/
public function run(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
return $instance->run(new ArrayInput($arguments), $this->output);
}
$this->output = new OutputStyle($input, $output);
/**
* Call another console command silently.
*
* @param string $command
* @param array $arguments
* @return int
*/
public function callSilent($command, array $arguments = array())
{
$instance = $this->getApplication()->find($command);
return parent::run($input, $output);
}
$arguments['command'] = $command;
/**
* Execute the console command.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return mixed
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$method = method_exists($this, 'handle') ? 'handle' : 'fire';
return $instance->run(new ArrayInput($arguments), new NullOutput);
}
return $this->laravel->call([$this, $method]);
}
/**
* Get the value of a command argument.
*
* @param string $key
* @return string|array
*/
public function argument($key = null)
{
if (is_null($key)) return $this->input->getArguments();
/**
* Call another console command.
*
* @param string $command
* @param array $arguments
* @return int
*/
public function call($command, array $arguments = [])
{
$instance = $this->getApplication()->find($command);
return $this->input->getArgument($key);
}
$arguments['command'] = $command;
/**
* Get the value of a command option.
*
* @param string $key
* @return string|array
*/
public function option($key = null)
{
if (is_null($key)) return $this->input->getOptions();
return $instance->run(new ArrayInput($arguments), $this->output);
}
return $this->input->getOption($key);
}
/**
* Call another console command silently.
*
* @param string $command
* @param array $arguments
* @return int
*/
public function callSilent($command, array $arguments = [])
{
$instance = $this->getApplication()->find($command);
/**
* Confirm a question with the user.
*
* @param string $question
* @param bool $default
* @return bool
*/
public function confirm($question, $default = false)
{
$helper = $this->getHelperSet()->get('question');
$arguments['command'] = $command;
$question = new ConfirmationQuestion("<question>{$question}</question> ", $default);
return $instance->run(new ArrayInput($arguments), new NullOutput);
}
return $helper->ask($this->input, $this->output, $question);
}
/**
* Determine if the given argument is present.
*
* @param string|int $name
* @return bool
*/
public function hasArgument($name)
{
return $this->input->hasArgument($name);
}
/**
* Prompt the user for input.
*
* @param string $question
* @param string $default
* @return string
*/
public function ask($question, $default = null)
{
$helper = $this->getHelperSet()->get('question');
/**
* Get the value of a command argument.
*
* @param string $key
* @return string|array
*/
public function argument($key = null)
{
if (is_null($key)) {
return $this->input->getArguments();
}
$question = new Question("<question>$question</question> ", $default);
return $this->input->getArgument($key);
}
return $helper->ask($this->input, $this->output, $question);
}
/**
* Determine if the given option is present.
*
* @param string $name
* @return bool
*/
public function hasOption($name)
{
return $this->input->hasOption($name);
}
/**
* Prompt the user for input with auto completion.
*
* @param string $question
* @param array $choices
* @param string $default
* @return string
*/
public function askWithCompletion($question, array $choices, $default = null)
{
$helper = $this->getHelperSet()->get('question');
/**
* Get the value of a command option.
*
* @param string $key
* @return string|array
*/
public function option($key = null)
{
if (is_null($key)) {
return $this->input->getOptions();
}
$question = new Question("<question>$question</question> ", $default);
return $this->input->getOption($key);
}
$question->setAutocompleterValues($choices);
/**
* Confirm a question with the user.
*
* @param string $question
* @param bool $default
* @return bool
*/
public function confirm($question, $default = false)
{
return $this->output->confirm($question, $default);
}
return $helper->ask($this->input, $this->output, $question);
}
/**
* Prompt the user for input.
*
* @param string $question
* @param string $default
* @return string
*/
public function ask($question, $default = null)
{
return $this->output->ask($question, $default);
}
/**
* Prompt the user for input but hide the answer from the console.
*
* @param string $question
* @param bool $fallback
* @return string
*/
public function secret($question, $fallback = true)
{
$helper = $this->getHelperSet()->get('question');
/**
* Prompt the user for input with auto completion.
*
* @param string $question
* @param array $choices
* @param string $default
* @return string
*/
public function anticipate($question, array $choices, $default = null)
{
return $this->askWithCompletion($question, $choices, $default);
}
$question = new Question("<question>$question</question> ");
/**
* Prompt the user for input with auto completion.
*
* @param string $question
* @param array $choices
* @param string $default
* @return string
*/
public function askWithCompletion($question, array $choices, $default = null)
{
$question = new Question($question, $default);
$question->setHidden(true)->setHiddenFallback($fallback);
$question->setAutocompleterValues($choices);
return $helper->ask($this->input, $this->output, $question);
}
return $this->output->askQuestion($question);
}
/**
* Give the user a single choice from an array of answers.
*
* @param string $question
* @param array $choices
* @param string $default
* @param mixed $attempts
* @param bool $multiple
* @return bool
*/
public function choice($question, array $choices, $default = null, $attempts = null, $multiple = null)
{
$helper = $this->getHelperSet()->get('question');
/**
* Prompt the user for input but hide the answer from the console.
*
* @param string $question
* @param bool $fallback
* @return string
*/
public function secret($question, $fallback = true)
{
$question = new Question($question);
$question = new ChoiceQuestion("<question>$question</question> ", $choices, $default);
$question->setHidden(true)->setHiddenFallback($fallback);
$question->setMaxAttempts($attempts)->setMultiselect($multiple);
return $this->output->askQuestion($question);
}
return $helper->ask($this->input, $this->output, $question);
}
/**
* Give the user a single choice from an array of answers.
*
* @param string $question
* @param array $choices
* @param string $default
* @param mixed $attempts
* @param bool $multiple
* @return string
*/
public function choice($question, array $choices, $default = null, $attempts = null, $multiple = null)
{
$question = new ChoiceQuestion($question, $choices, $default);
/**
* Format input to textual table.
*
* @param array $headers
* @param array $rows
* @param string $style
* @return void
*/
public function table(array $headers, array $rows, $style = 'default')
{
$table = new Table($this->output);
$question->setMaxAttempts($attempts)->setMultiselect($multiple);
$table->setHeaders($headers)->setRows($rows)->setStyle($style)->render();
}
return $this->output->askQuestion($question);
}
/**
* Write a string as information output.
*
* @param string $string
* @return void
*/
public function info($string)
{
$this->output->writeln("<info>$string</info>");
}
/**
* Format input to textual table.
*
* @param array $headers
* @param \Illuminate\Contracts\Support\Arrayable|array $rows
* @param string $style
* @return void
*/
public function table(array $headers, $rows, $style = 'default')
{
$table = new Table($this->output);
/**
* Write a string as standard output.
*
* @param string $string
* @return void
*/
public function line($string)
{
$this->output->writeln($string);
}
if ($rows instanceof Arrayable) {
$rows = $rows->toArray();
}
/**
* Write a string as comment output.
*
* @param string $string
* @return void
*/
public function comment($string)
{
$this->output->writeln("<comment>$string</comment>");
}
$table->setHeaders($headers)->setRows($rows)->setStyle($style)->render();
}
/**
* Write a string as question output.
*
* @param string $string
* @return void
*/
public function question($string)
{
$this->output->writeln("<question>$string</question>");
}
/**
* Write a string as information output.
*
* @param string $string
* @param null|int|string $verbosity
* @return void
*/
public function info($string, $verbosity = null)
{
$this->line($string, 'info', $verbosity);
}
/**
* Write a string as error output.
*
* @param string $string
* @return void
*/
public function error($string)
{
$this->output->writeln("<error>$string</error>");
}
/**
* Write a string as standard output.
*
* @param string $string
* @param string $style
* @param null|int|string $verbosity
* @return void
*/
public function line($string, $style = null, $verbosity = null)
{
$styled = $style ? "<$style>$string</$style>" : $string;
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array();
}
$this->output->writeln($styled, $this->parseVerbosity($verbosity));
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array();
}
/**
* Write a string as comment output.
*
* @param string $string
* @param null|int|string $verbosity
* @return void
*/
public function comment($string, $verbosity = null)
{
$this->line($string, 'comment', $verbosity);
}
/**
* Get the output implementation.
*
* @return \Symfony\Component\Console\Output\OutputInterface
*/
public function getOutput()
{
return $this->output;
}
/**
* Write a string as question output.
*
* @param string $string
* @param null|int|string $verbosity
* @return void
*/
public function question($string, $verbosity = null)
{
$this->line($string, 'question', $verbosity);
}
/**
* Get the Laravel application instance.
*
* @return \Illuminate\Contracts\Foundation\Application
*/
public function getLaravel()
{
return $this->laravel;
}
/**
* Write a string as error output.
*
* @param string $string
* @param null|int|string $verbosity
* @return void
*/
public function error($string, $verbosity = null)
{
$this->line($string, 'error', $verbosity);
}
/**
* Set the Laravel application instance.
*
* @param \Illuminate\Contracts\Foundation\Application $laravel
* @return void
*/
public function setLaravel(LaravelApplication $laravel)
{
$this->laravel = $laravel;
}
/**
* Write a string as warning output.
*
* @param string $string
* @param null|int|string $verbosity
* @return void
*/
public function warn($string, $verbosity = null)
{
if (! $this->output->getFormatter()->hasStyle('warning')) {
$style = new OutputFormatterStyle('yellow');
$this->output->getFormatter()->setStyle('warning', $style);
}
$this->line($string, 'warning', $verbosity);
}
/**
* Get the verbosity level in terms of Symfony's OutputInterface level.
*
* @param string|int $level
* @return int
*/
protected function parseVerbosity($level = null)
{
if (isset($this->verbosityMap[$level])) {
$level = $this->verbosityMap[$level];
} elseif (! is_int($level)) {
$level = $this->verbosity;
}
return $level;
}
/**
* Set the verbosity level.
*
* @param string|int $level
* @return void
*/
protected function setVerbosity($level)
{
$this->verbosity = $this->parseVerbosity($level);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [];
}
/**
* Get the output implementation.
*
* @return \Symfony\Component\Console\Output\OutputInterface
*/
public function getOutput()
{
return $this->output;
}
/**
* Get the Laravel application instance.
*
* @return \Illuminate\Contracts\Foundation\Application
*/
public function getLaravel()
{
return $this->laravel;
}
/**
* Set the Laravel application instance.
*
* @param \Illuminate\Contracts\Container\Container $laravel
* @return void
*/
public function setLaravel($laravel)
{
$this->laravel = $laravel;
}
}

View File

@@ -1,50 +1,55 @@
<?php namespace Illuminate\Console;
<?php
namespace Illuminate\Console;
use Closure;
trait ConfirmableTrait {
trait ConfirmableTrait
{
/**
* Confirm before proceeding with the action.
*
* @param string $warning
* @param \Closure|bool|null $callback
* @return bool
*/
public function confirmToProceed($warning = 'Application In Production!', $callback = null)
{
$callback = is_null($callback) ? $this->getDefaultConfirmCallback() : $callback;
/**
* Confirm before proceeding with the action.
*
* @param string $warning
* @param \Closure|null $callback
* @return bool
*/
public function confirmToProceed($warning = 'Application In Production!', Closure $callback = null)
{
$shouldConfirm = $callback ?: $this->getDefaultConfirmCallback();
$shouldConfirm = $callback instanceof Closure ? call_user_func($callback) : $callback;
if (call_user_func($shouldConfirm))
{
if ($this->option('force')) return true;
if ($shouldConfirm) {
if ($this->option('force')) {
return true;
}
$this->comment(str_repeat('*', strlen($warning) + 12));
$this->comment('* '.$warning.' *');
$this->comment(str_repeat('*', strlen($warning) + 12));
$this->output->writeln('');
$this->comment(str_repeat('*', strlen($warning) + 12));
$this->comment('* '.$warning.' *');
$this->comment(str_repeat('*', strlen($warning) + 12));
$this->output->writeln('');
$confirmed = $this->confirm('Do you really wish to run this command? [y/N]');
$confirmed = $this->confirm('Do you really wish to run this command?');
if ( ! $confirmed)
{
$this->comment('Command Cancelled!');
if (! $confirmed) {
$this->comment('Command Cancelled!');
return false;
}
}
return false;
}
}
return true;
}
/**
* Get the default confirmation callback.
*
* @return \Closure
*/
protected function getDefaultConfirmCallback()
{
return function() { return $this->getLaravel()->environment() == 'production'; };
}
return true;
}
/**
* Get the default confirmation callback.
*
* @return \Closure
*/
protected function getDefaultConfirmCallback()
{
return function () {
return $this->getLaravel()->environment() == 'production';
};
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Illuminate\Console\Events;
class ArtisanStarting
{
/**
* The Artisan application instance.
*
* @var \Illuminate\Console\Application
*/
public $artisan;
/**
* Create a new event instance.
*
* @param \Illuminate\Console\Application $artisan
* @return void
*/
public function __construct($artisan)
{
$this->artisan = $artisan;
}
}

View File

@@ -1,208 +1,219 @@
<?php namespace Illuminate\Console;
<?php
namespace Illuminate\Console;
use Illuminate\Support\Str;
use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputArgument;
abstract class GeneratorCommand extends Command {
abstract class GeneratorCommand extends Command
{
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
use AppNamespaceDetectorTrait;
/**
* The type of class being generated.
*
* @var string
*/
protected $type;
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* Create a new controller creator command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @return void
*/
public function __construct(Filesystem $files)
{
parent::__construct();
/**
* The type of class being generated.
*
* @var string
*/
protected $type;
$this->files = $files;
}
/**
* Create a new controller creator command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @return void
*/
public function __construct(Filesystem $files)
{
parent::__construct();
/**
* Get the stub file for the generator.
*
* @return string
*/
abstract protected function getStub();
$this->files = $files;
}
/**
* Execute the console command.
*
* @return bool|null
*/
public function fire()
{
$name = $this->parseName($this->getNameInput());
/**
* Get the stub file for the generator.
*
* @return string
*/
abstract protected function getStub();
$path = $this->getPath($name);
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$name = $this->parseName($this->getNameInput());
if ($this->alreadyExists($this->getNameInput())) {
$this->error($this->type.' already exists!');
if ($this->files->exists($path = $this->getPath($name)))
{
$this->error($this->type.' already exists!');
return false;
}
return false;
}
$this->makeDirectory($path);
$this->makeDirectory($path);
$this->files->put($path, $this->buildClass($name));
$this->files->put($path, $this->buildClass($name));
$this->info($this->type.' created successfully.');
}
$this->info($this->type.' created successfully.');
}
/**
* Determine if the class already exists.
*
* @param string $rawName
* @return bool
*/
protected function alreadyExists($rawName)
{
$name = $this->parseName($rawName);
/**
* Get the destination class path.
*
* @param string $name
* @return string
*/
protected function getPath($name)
{
$name = str_replace($this->getAppNamespace(), '', $name);
return $this->files->exists($this->getPath($name));
}
return $this->laravel['path'].'/'.str_replace('\\', '/', $name).'.php';
}
/**
* Get the destination class path.
*
* @param string $name
* @return string
*/
protected function getPath($name)
{
$name = str_replace($this->laravel->getNamespace(), '', $name);
/**
* Parse the name and format according to the root namespace.
*
* @param string $name
* @return string
*/
protected function parseName($name)
{
$rootNamespace = $this->getAppNamespace();
return $this->laravel['path'].'/'.str_replace('\\', '/', $name).'.php';
}
if (starts_with($name, $rootNamespace))
{
return $name;
}
/**
* Parse the name and format according to the root namespace.
*
* @param string $name
* @return string
*/
protected function parseName($name)
{
$rootNamespace = $this->laravel->getNamespace();
if (str_contains($name, '/'))
{
$name = str_replace('/', '\\', $name);
}
if (Str::startsWith($name, $rootNamespace)) {
return $name;
}
return $this->parseName($this->getDefaultNamespace(trim($rootNamespace, '\\')).'\\'.$name);
}
if (Str::contains($name, '/')) {
$name = str_replace('/', '\\', $name);
}
/**
* Get the default namespace for the class.
*
* @param string $rootNamespace
* @return string
*/
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace;
}
return $this->parseName($this->getDefaultNamespace(trim($rootNamespace, '\\')).'\\'.$name);
}
/**
* Build the directory for the class if necessary.
*
* @param string $path
* @return string
*/
protected function makeDirectory($path)
{
if ( ! $this->files->isDirectory(dirname($path)))
{
$this->files->makeDirectory(dirname($path), 0777, true, true);
}
}
/**
* Get the default namespace for the class.
*
* @param string $rootNamespace
* @return string
*/
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace;
}
/**
* Build the class with the given name.
*
* @param string $name
* @return string
*/
protected function buildClass($name)
{
$stub = $this->files->get($this->getStub());
/**
* Build the directory for the class if necessary.
*
* @param string $path
* @return string
*/
protected function makeDirectory($path)
{
if (! $this->files->isDirectory(dirname($path))) {
$this->files->makeDirectory(dirname($path), 0777, true, true);
}
}
return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);
}
/**
* Build the class with the given name.
*
* @param string $name
* @return string
*/
protected function buildClass($name)
{
$stub = $this->files->get($this->getStub());
/**
* Replace the namespace for the given stub.
*
* @param string $stub
* @param string $name
* @return $this
*/
protected function replaceNamespace(&$stub, $name)
{
$stub = str_replace(
'{{namespace}}', $this->getNamespace($name), $stub
);
return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);
}
$stub = str_replace(
'{{rootNamespace}}', $this->getAppNamespace(), $stub
);
/**
* Replace the namespace for the given stub.
*
* @param string $stub
* @param string $name
* @return $this
*/
protected function replaceNamespace(&$stub, $name)
{
$stub = str_replace(
'DummyNamespace', $this->getNamespace($name), $stub
);
return $this;
}
$stub = str_replace(
'DummyRootNamespace', $this->laravel->getNamespace(), $stub
);
/**
* Get the full namespace name for a given class.
*
* @param string $name
* @return string
*/
protected function getNamespace($name)
{
return trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
}
return $this;
}
/**
* Replace the class name for the given stub.
*
* @param string $stub
* @param string $name
* @return string
*/
protected function replaceClass($stub, $name)
{
$class = str_replace($this->getNamespace($name).'\\', '', $name);
/**
* Get the full namespace name for a given class.
*
* @param string $name
* @return string
*/
protected function getNamespace($name)
{
return trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
}
return str_replace('{{class}}', $class, $stub);
}
/**
* Replace the class name for the given stub.
*
* @param string $stub
* @param string $name
* @return string
*/
protected function replaceClass($stub, $name)
{
$class = str_replace($this->getNamespace($name).'\\', '', $name);
/**
* Get the desired class name from the input.
*
* @return string
*/
protected function getNameInput()
{
return $this->argument('name');
}
return str_replace('DummyClass', $class, $stub);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array(
array('name', InputArgument::REQUIRED, 'The name of the class'),
);
}
/**
* Get the desired class name from the input.
*
* @return string
*/
protected function getNameInput()
{
return trim($this->argument('name'));
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the class'],
];
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Illuminate\Console;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class OutputStyle extends SymfonyStyle
{
/**
* The output instance.
*
* @var \Symfony\Component\Console\Output\OutputInterface
*/
private $output;
/**
* Create a new Console OutputStyle instance.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return void
*/
public function __construct(InputInterface $input, OutputInterface $output)
{
$this->output = $output;
parent::__construct($input, $output);
}
/**
* Returns whether verbosity is quiet (-q).
*
* @return bool
*/
public function isQuiet()
{
return $this->output->isQuiet();
}
/**
* Returns whether verbosity is verbose (-v).
*
* @return bool
*/
public function isVerbose()
{
return $this->output->isVerbose();
}
/**
* Returns whether verbosity is very verbose (-vv).
*
* @return bool
*/
public function isVeryVerbose()
{
return $this->output->isVeryVerbose();
}
/**
* Returns whether verbosity is debug (-vvv).
*
* @return bool
*/
public function isDebug()
{
return $this->output->isDebug();
}
}

View File

@@ -0,0 +1,136 @@
<?php
namespace Illuminate\Console;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
class Parser
{
/**
* Parse the given console command definition into an array.
*
* @param string $expression
* @return array
*
* @throws \InvalidArgumentException
*/
public static function parse($expression)
{
if (trim($expression) === '') {
throw new InvalidArgumentException('Console command definition is empty.');
}
preg_match('/[^\s]+/', $expression, $matches);
if (isset($matches[0])) {
$name = $matches[0];
} else {
throw new InvalidArgumentException('Unable to determine command name from signature.');
}
preg_match_all('/\{\s*(.*?)\s*\}/', $expression, $matches);
$tokens = isset($matches[1]) ? $matches[1] : [];
if (count($tokens)) {
return array_merge([$name], static::parameters($tokens));
}
return [$name, [], []];
}
/**
* Extract all of the parameters from the tokens.
*
* @param array $tokens
* @return array
*/
protected static function parameters(array $tokens)
{
$arguments = [];
$options = [];
foreach ($tokens as $token) {
if (! Str::startsWith($token, '--')) {
$arguments[] = static::parseArgument($token);
} else {
$options[] = static::parseOption(ltrim($token, '-'));
}
}
return [$arguments, $options];
}
/**
* Parse an argument expression.
*
* @param string $token
* @return \Symfony\Component\Console\Input\InputArgument
*/
protected static function parseArgument($token)
{
$description = null;
if (Str::contains($token, ' : ')) {
list($token, $description) = explode(' : ', $token, 2);
$token = trim($token);
$description = trim($description);
}
switch (true) {
case Str::endsWith($token, '?*'):
return new InputArgument(trim($token, '?*'), InputArgument::IS_ARRAY, $description);
case Str::endsWith($token, '*'):
return new InputArgument(trim($token, '*'), InputArgument::IS_ARRAY | InputArgument::REQUIRED, $description);
case Str::endsWith($token, '?'):
return new InputArgument(trim($token, '?'), InputArgument::OPTIONAL, $description);
case preg_match('/(.+)\=(.+)/', $token, $matches):
return new InputArgument($matches[1], InputArgument::OPTIONAL, $description, $matches[2]);
default:
return new InputArgument($token, InputArgument::REQUIRED, $description);
}
}
/**
* Parse an option expression.
*
* @param string $token
* @return \Symfony\Component\Console\Input\InputOption
*/
protected static function parseOption($token)
{
$description = null;
if (Str::contains($token, ' : ')) {
list($token, $description) = explode(' : ', $token);
$token = trim($token);
$description = trim($description);
}
$shortcut = null;
$matches = preg_split('/\s*\|\s*/', $token, 2);
if (isset($matches[1])) {
$shortcut = $matches[0];
$token = $matches[1];
}
switch (true) {
case Str::endsWith($token, '='):
return new InputOption(trim($token, '='), $shortcut, InputOption::VALUE_OPTIONAL, $description);
case Str::endsWith($token, '=*'):
return new InputOption(trim($token, '=*'), $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description);
case preg_match('/(.+)\=(.+)/', $token, $matches):
return new InputOption($matches[1], $shortcut, InputOption::VALUE_OPTIONAL, $description, $matches[2]);
default:
return new InputOption($token, $shortcut, InputOption::VALUE_NONE, $description);
}
}
}

View File

@@ -1,36 +1,37 @@
<?php namespace Illuminate\Console;
<?php
namespace Illuminate\Console;
use Illuminate\Support\ServiceProvider;
class ScheduleServiceProvider extends ServiceProvider {
class ScheduleServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->commands('Illuminate\Console\Scheduling\ScheduleRunCommand');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'Illuminate\Console\Scheduling\ScheduleRunCommand',
];
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->commands('Illuminate\Console\Scheduling\ScheduleRunCommand');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'Illuminate\Console\Scheduling\ScheduleRunCommand',
];
}
}

View File

@@ -1,126 +1,126 @@
<?php namespace Illuminate\Console\Scheduling;
<?php
namespace Illuminate\Console\Scheduling;
use LogicException;
use InvalidArgumentException;
use Illuminate\Contracts\Container\Container;
class CallbackEvent extends Event {
class CallbackEvent extends Event
{
/**
* The callback to call.
*
* @var string
*/
protected $callback;
/**
* The callback to call.
*
* @var string
*/
protected $callback;
/**
* The parameters to pass to the method.
*
* @var array
*/
protected $parameters;
/**
* The parameters to pass to the method.
*
* @var array
*/
protected $parameters;
/**
* Create a new event instance.
*
* @param string $callback
* @param array $parameters
* @return void
*
* @throws \InvalidArgumentException
*/
public function __construct($callback, array $parameters = [])
{
$this->callback = $callback;
$this->parameters = $parameters;
/**
* Create a new event instance.
*
* @param string $callback
* @param array $parameters
* @return void
*/
public function __construct($callback, array $parameters = array())
{
$this->callback = $callback;
$this->parameters = $parameters;
if (! is_string($this->callback) && ! is_callable($this->callback)) {
throw new InvalidArgumentException(
'Invalid scheduled callback event. Must be string or callable.'
);
}
}
if ( ! is_string($this->callback) && ! is_callable($this->callback))
{
throw new InvalidArgumentException(
"Invalid scheduled callback event. Must be string or callable."
);
}
}
/**
* Run the given event.
*
* @param \Illuminate\Contracts\Container\Container $container
* @return mixed
*
* @throws \Exception
*/
public function run(Container $container)
{
if ($this->description) {
touch($this->mutexPath());
}
/**
* Run the given event.
*
* @param \Illuminate\Contracts\Container\Container $container
* @return mixed
*/
public function run(Container $container)
{
if ($this->description)
{
touch($this->mutexPath());
}
try {
$response = $container->call($this->callback, $this->parameters);
} finally {
$this->removeMutex();
}
try {
$response = $container->call($this->callback, $this->parameters);
} catch (\Exception $e) {
$this->removeMutex();
parent::callAfterCallbacks($container);
throw $e;
}
return $response;
}
$this->removeMutex();
/**
* Remove the mutex file from disk.
*
* @return void
*/
protected function removeMutex()
{
if ($this->description) {
@unlink($this->mutexPath());
}
}
parent::callAfterCallbacks($container);
/**
* Do not allow the event to overlap each other.
*
* @return $this
*
* @throws \LogicException
*/
public function withoutOverlapping()
{
if (! isset($this->description)) {
throw new LogicException(
"A scheduled event name is required to prevent overlapping. Use the 'name' method before 'withoutOverlapping'."
);
}
return $response;
}
return $this->skip(function () {
return file_exists($this->mutexPath());
});
}
/**
* Remove the mutex file from disk.
*
* @return void
*/
protected function removeMutex()
{
if ($this->description)
{
@unlink($this->mutexPath());
}
}
/**
* Get the mutex path for the scheduled command.
*
* @return string
*/
protected function mutexPath()
{
return storage_path('framework/schedule-'.sha1($this->description));
}
/**
* Do not allow the event to overlap each other.
*
* @return $this
*/
public function withoutOverlapping()
{
if ( ! isset($this->description))
{
throw new LogicException(
"A scheduled event name is required to prevent overlapping. Use the 'name' method before 'withoutOverlapping'."
);
}
return $this->skip(function()
{
return file_exists($this->mutexPath());
});
}
/**
* Get the mutex path for the scheduled command.
*
* @return string
*/
protected function mutexPath()
{
return storage_path().'/framework/schedule-'.md5($this->description);
}
/**
* Get the summary of the event for display.
*
* @return string
*/
public function getSummaryForDisplay()
{
if (is_string($this->description)) return $this->description;
return is_string($this->callback) ? $this->callback : 'Closure';
}
/**
* Get the summary of the event for display.
*
* @return string
*/
public function getSummaryForDisplay()
{
if (is_string($this->description)) {
return $this->description;
}
return is_string($this->callback) ? $this->callback : 'Closure';
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,76 +1,108 @@
<?php namespace Illuminate\Console\Scheduling;
<?php
use Illuminate\Contracts\Foundation\Application;
namespace Illuminate\Console\Scheduling;
class Schedule {
use Symfony\Component\Process\ProcessUtils;
use Symfony\Component\Process\PhpExecutableFinder;
/**
* All of the events on the schedule.
*
* @var array
*/
protected $events = [];
class Schedule
{
/**
* All of the events on the schedule.
*
* @var array
*/
protected $events = [];
/**
* Add a new callback event to the schedule.
*
* @param string $callback
* @param array $parameters
* @return \Illuminate\Console\Scheduling\Event
*/
public function call($callback, array $parameters = array())
{
$this->events[] = $event = new CallbackEvent($callback, $parameters);
/**
* Add a new callback event to the schedule.
*
* @param string $callback
* @param array $parameters
* @return \Illuminate\Console\Scheduling\Event
*/
public function call($callback, array $parameters = [])
{
$this->events[] = $event = new CallbackEvent($callback, $parameters);
return $event;
}
return $event;
}
/**
* Add a new Artisan command event to the schedule.
*
* @param string $command
* @return \Illuminate\Console\Scheduling\Event
*/
public function command($command)
{
return $this->exec(PHP_BINARY.' artisan '.$command);
}
/**
* Add a new Artisan command event to the schedule.
*
* @param string $command
* @param array $parameters
* @return \Illuminate\Console\Scheduling\Event
*/
public function command($command, array $parameters = [])
{
$binary = ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false));
/**
* Add a new command event to the schedule.
*
* @param string $command
* @return \Illuminate\Console\Scheduling\Event
*/
public function exec($command)
{
$this->events[] = $event = new Event($command);
if (defined('HHVM_VERSION')) {
$binary .= ' --php';
}
return $event;
}
if (defined('ARTISAN_BINARY')) {
$artisan = ProcessUtils::escapeArgument(ARTISAN_BINARY);
} else {
$artisan = 'artisan';
}
/**
* Get all of the events on the schedule.
*
* @return array
*/
public function events()
{
return $this->events;
}
return $this->exec("{$binary} {$artisan} {$command}", $parameters);
}
/**
* Get all of the events on the schedule that are due.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return array
*/
public function dueEvents(Application $app)
{
return array_filter($this->events, function($event) use ($app)
{
return $event->isDue($app);
});
}
/**
* Add a new command event to the schedule.
*
* @param string $command
* @param array $parameters
* @return \Illuminate\Console\Scheduling\Event
*/
public function exec($command, array $parameters = [])
{
if (count($parameters)) {
$command .= ' '.$this->compileParameters($parameters);
}
$this->events[] = $event = new Event($command);
return $event;
}
/**
* Compile parameters for a command.
*
* @param array $parameters
* @return string
*/
protected function compileParameters(array $parameters)
{
return collect($parameters)->map(function ($value, $key) {
return is_numeric($key) ? $value : $key.'='.(is_numeric($value) ? $value : ProcessUtils::escapeArgument($value));
})->implode(' ');
}
/**
* Get all of the events on the schedule.
*
* @return array
*/
public function events()
{
return $this->events;
}
/**
* Get all of the events on the schedule that are due.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return array
*/
public function dueEvents($app)
{
return array_filter($this->events, function ($event) use ($app) {
return $event->isDue($app);
});
}
}

Some files were not shown because too many files have changed in this diff Show More