mirror of
https://github.com/linuxserver/Heimdall.git
synced 2025-12-01 20:49:53 +09:00
Update to laravel 7
This commit is contained in:
14
vendor/laravel/framework/README.md
vendored
14
vendor/laravel/framework/README.md
vendored
@@ -1,7 +1,7 @@
|
||||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://laravel.com/assets/img/components/logo-laravel.svg"></a></p>
|
||||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400"></a></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
|
||||
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/d/total.svg" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/v/stable.svg" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/license.svg" alt="License"></a>
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
## About Laravel
|
||||
|
||||
> **Note:** This repository contains the core code of the Laravel framework. If you want to build an application using Laravel 5, visit the main [Laravel repository](https://github.com/laravel/laravel).
|
||||
> **Note:** This repository contains the core code of the Laravel framework. If you want to build an application using Laravel, visit the main [Laravel repository](https://github.com/laravel/laravel).
|
||||
|
||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as:
|
||||
|
||||
@@ -20,7 +20,7 @@ Laravel is a web application framework with expressive, elegant syntax. We belie
|
||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
||||
|
||||
Laravel is accessible, yet powerful, providing tools needed for large, robust applications. A superb combination of simplicity, elegance, and innovation gives you a complete toolset required to build any application with which you are tasked
|
||||
Laravel is accessible, yet powerful, providing tools needed for large, robust applications. A superb combination of simplicity, elegance, and innovation gives you a complete toolset required to build any application with which you are tasked.
|
||||
|
||||
## Learning Laravel
|
||||
|
||||
@@ -34,12 +34,12 @@ Thank you for considering contributing to the Laravel framework! The contributio
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
||||
|
||||
## Security Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
||||
Please review [our security policy](https://github.com/laravel/framework/security/policy) on how to report security vulnerabilities.
|
||||
|
||||
## License
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](LICENSE.md).
|
||||
|
||||
114
vendor/laravel/framework/composer.json
vendored
114
vendor/laravel/framework/composer.json
vendored
@@ -15,32 +15,35 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"php": "^7.2.5|^8.0",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"doctrine/inflector": "^1.1",
|
||||
"dragonmantank/cron-expression": "^2.0",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"laravel/nexmo-notification-channel": "^1.0",
|
||||
"laravel/slack-notification-channel": "^1.0",
|
||||
"league/flysystem": "^1.0.8",
|
||||
"monolog/monolog": "^1.12",
|
||||
"nesbot/carbon": "^1.26.3",
|
||||
"opis/closure": "^3.1",
|
||||
"doctrine/inflector": "^1.4|^2.0",
|
||||
"dragonmantank/cron-expression": "^2.3.1",
|
||||
"egulias/email-validator": "^2.1.10",
|
||||
"league/commonmark": "^1.3",
|
||||
"league/flysystem": "^1.1",
|
||||
"monolog/monolog": "^2.0",
|
||||
"nesbot/carbon": "^2.31",
|
||||
"opis/closure": "^3.6",
|
||||
"psr/container": "^1.0",
|
||||
"psr/simple-cache": "^1.0",
|
||||
"ramsey/uuid": "^3.7",
|
||||
"ramsey/uuid": "^3.7|^4.0",
|
||||
"swiftmailer/swiftmailer": "^6.0",
|
||||
"symfony/console": "^4.1",
|
||||
"symfony/debug": "^4.1",
|
||||
"symfony/finder": "^4.1",
|
||||
"symfony/http-foundation": "^4.1",
|
||||
"symfony/http-kernel": "^4.1",
|
||||
"symfony/process": "^4.1",
|
||||
"symfony/routing": "^4.1",
|
||||
"symfony/var-dumper": "^4.1",
|
||||
"tijsverkoyen/css-to-inline-styles": "^2.2.1",
|
||||
"vlucas/phpdotenv": "^2.2"
|
||||
"symfony/console": "^5.0",
|
||||
"symfony/error-handler": "^5.0",
|
||||
"symfony/finder": "^5.0",
|
||||
"symfony/http-foundation": "^5.0",
|
||||
"symfony/http-kernel": "^5.0",
|
||||
"symfony/mime": "^5.0",
|
||||
"symfony/polyfill-php73": "^1.17",
|
||||
"symfony/process": "^5.0",
|
||||
"symfony/routing": "^5.0",
|
||||
"symfony/var-dumper": "^5.0",
|
||||
"tijsverkoyen/css-to-inline-styles": "^2.2.2",
|
||||
"vlucas/phpdotenv": "^4.0",
|
||||
"voku/portable-ascii": "^1.4.8"
|
||||
},
|
||||
"replace": {
|
||||
"illuminate/auth": "self.version",
|
||||
@@ -68,29 +71,31 @@
|
||||
"illuminate/routing": "self.version",
|
||||
"illuminate/session": "self.version",
|
||||
"illuminate/support": "self.version",
|
||||
"illuminate/testing": "self.version",
|
||||
"illuminate/translation": "self.version",
|
||||
"illuminate/validation": "self.version",
|
||||
"illuminate/view": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"aws/aws-sdk-php": "^3.155",
|
||||
"doctrine/dbal": "^2.6",
|
||||
"filp/whoops": "^2.8",
|
||||
"guzzlehttp/guzzle": "^6.3.1|^7.0.1",
|
||||
"league/flysystem-cached-adapter": "^1.0",
|
||||
"mockery/mockery": "~1.3.3|^1.4.2",
|
||||
"moontoast/math": "^1.1",
|
||||
"orchestra/testbench-core": "^5.8",
|
||||
"pda/pheanstalk": "^4.0",
|
||||
"phpunit/phpunit": "^8.4|^9.3.3",
|
||||
"predis/predis": "^1.1.1",
|
||||
"symfony/cache": "^5.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/container-implementation": "1.0"
|
||||
},
|
||||
"conflict": {
|
||||
"tightenco/collect": "<5.5.33"
|
||||
},
|
||||
"require-dev": {
|
||||
"aws/aws-sdk-php": "^3.0",
|
||||
"doctrine/dbal": "^2.6",
|
||||
"filp/whoops": "^2.1.4",
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
"league/flysystem-cached-adapter": "^1.0",
|
||||
"mockery/mockery": "^1.0",
|
||||
"moontoast/math": "^1.1",
|
||||
"orchestra/testbench-core": "3.7.*",
|
||||
"pda/pheanstalk": "^3.0|^4.0",
|
||||
"phpunit/phpunit": "^7.5",
|
||||
"predis/predis": "^1.1.1",
|
||||
"symfony/css-selector": "^4.1",
|
||||
"symfony/dom-crawler": "^4.1",
|
||||
"true/punycode": "^2.1"
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Illuminate/Foundation/helpers.php",
|
||||
@@ -110,30 +115,37 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.7-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ftp": "Required to use the Flysystem FTP driver.",
|
||||
"ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().",
|
||||
"ext-memcached": "Required to use the memcache cache driver.",
|
||||
"ext-pcntl": "Required to use all features of the queue worker.",
|
||||
"ext-posix": "Required to use all features of the queue worker.",
|
||||
"aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (^3.0).",
|
||||
"ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).",
|
||||
"aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage and SES mail driver (^3.155).",
|
||||
"doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6).",
|
||||
"filp/whoops": "Required for friendly error pages in development (^2.1.4).",
|
||||
"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 (^6.0).",
|
||||
"laravel/tinker": "Required to use the tinker console command (^1.0).",
|
||||
"filp/whoops": "Required for friendly error pages in development (^2.8).",
|
||||
"fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).",
|
||||
"guzzlehttp/guzzle": "Required to use the HTTP Client, Mailgun mail driver and the ping methods on schedules (^6.3.1|^7.0.1).",
|
||||
"laravel/tinker": "Required to use the tinker console command (^2.0).",
|
||||
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).",
|
||||
"league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).",
|
||||
"league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (^1.0).",
|
||||
"league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).",
|
||||
"mockery/mockery": "Required to use mocking (~1.3.3|^1.4.2).",
|
||||
"moontoast/math": "Required to use ordered UUIDs (^1.1).",
|
||||
"nexmo/client": "Required to use the Nexmo transport (^1.0).",
|
||||
"pda/pheanstalk": "Required to use the beanstalk queue driver (^3.0|^4.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 (^3.0).",
|
||||
"symfony/css-selector": "Required to use some of the crawler integration testing tools (^4.1).",
|
||||
"symfony/dom-crawler": "Required to use most of the crawler integration testing tools (^4.1).",
|
||||
"symfony/psr-http-message-bridge": "Required to psr7 bridging features (^1.0)."
|
||||
"nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).",
|
||||
"pda/pheanstalk": "Required to use the beanstalk queue driver (^4.0).",
|
||||
"phpunit/phpunit": "Required to use assertions and run tests (^8.4|^9.3.3).",
|
||||
"predis/predis": "Required to use the predis connector (^1.1.2).",
|
||||
"psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).",
|
||||
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^4.0).",
|
||||
"symfony/cache": "Required to PSR-6 cache bridge (^5.0).",
|
||||
"symfony/filesystem": "Required to create relative storage directory symbolic links (^5.0).",
|
||||
"symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0).",
|
||||
"wildbit/swiftmailer-postmark": "Required to use Postmark mail driver (^3.0)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
|
||||
@@ -3,8 +3,62 @@
|
||||
namespace Illuminate\Auth\Access;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class AuthorizationException extends Exception
|
||||
{
|
||||
//
|
||||
/**
|
||||
* The response from the gate.
|
||||
*
|
||||
* @var \Illuminate\Auth\Access\Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* Create a new authorization exception instance.
|
||||
*
|
||||
* @param string|null $message
|
||||
* @param mixed $code
|
||||
* @param \Throwable|null $previous
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($message = null, $code = null, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message ?? 'This action is unauthorized.', 0, $previous);
|
||||
|
||||
$this->code = $code ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response from the gate.
|
||||
*
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*/
|
||||
public function response()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the response from the gate.
|
||||
*
|
||||
* @param \Illuminate\Auth\Access\Response $response
|
||||
* @return $this
|
||||
*/
|
||||
public function setResponse($response)
|
||||
{
|
||||
$this->response = $response;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a deny response object from this exception.
|
||||
*
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*/
|
||||
public function toResponse()
|
||||
{
|
||||
return Response::deny($this->message, $this->code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
namespace Illuminate\Auth\Access;
|
||||
|
||||
use Exception;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
|
||||
class Gate implements GateContract
|
||||
{
|
||||
@@ -57,6 +57,20 @@ class Gate implements GateContract
|
||||
*/
|
||||
protected $afterCallbacks = [];
|
||||
|
||||
/**
|
||||
* All of the defined abilities using class@method notation.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $stringCallbacks = [];
|
||||
|
||||
/**
|
||||
* The callback to be used to guess policy names.
|
||||
*
|
||||
* @var callable|null
|
||||
*/
|
||||
protected $guessPolicyNamesUsingCallback;
|
||||
|
||||
/**
|
||||
* Create a new gate instance.
|
||||
*
|
||||
@@ -66,10 +80,12 @@ class Gate implements GateContract
|
||||
* @param array $policies
|
||||
* @param array $beforeCallbacks
|
||||
* @param array $afterCallbacks
|
||||
* @param callable|null $guessPolicyNamesUsingCallback
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Container $container, callable $userResolver, array $abilities = [],
|
||||
array $policies = [], array $beforeCallbacks = [], array $afterCallbacks = [])
|
||||
array $policies = [], array $beforeCallbacks = [], array $afterCallbacks = [],
|
||||
callable $guessPolicyNamesUsingCallback = null)
|
||||
{
|
||||
$this->policies = $policies;
|
||||
$this->container = $container;
|
||||
@@ -77,6 +93,7 @@ class Gate implements GateContract
|
||||
$this->userResolver = $userResolver;
|
||||
$this->afterCallbacks = $afterCallbacks;
|
||||
$this->beforeCallbacks = $beforeCallbacks;
|
||||
$this->guessPolicyNamesUsingCallback = $guessPolicyNamesUsingCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,9 +126,15 @@ class Gate implements GateContract
|
||||
*/
|
||||
public function define($ability, $callback)
|
||||
{
|
||||
if (is_array($callback) && isset($callback[0]) && is_string($callback[0])) {
|
||||
$callback = $callback[0].'@'.$callback[1];
|
||||
}
|
||||
|
||||
if (is_callable($callback)) {
|
||||
$this->abilities[$ability] = $callback;
|
||||
} elseif (is_string($callback)) {
|
||||
$this->stringCallbacks[$ability] = $callback;
|
||||
|
||||
$this->abilities[$ability] = $this->buildAbilityCallback($ability, $callback);
|
||||
} else {
|
||||
throw new InvalidArgumentException("Callback must be a callable or a 'Class@method' string.");
|
||||
@@ -125,16 +148,17 @@ class Gate implements GateContract
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $class
|
||||
* @param array|null $abilities
|
||||
* @param array|null $abilities
|
||||
* @return $this
|
||||
*/
|
||||
public function resource($name, $class, array $abilities = null)
|
||||
{
|
||||
$abilities = $abilities ?: [
|
||||
'view' => 'view',
|
||||
'create' => 'create',
|
||||
'update' => 'update',
|
||||
'delete' => 'delete',
|
||||
'viewAny' => 'viewAny',
|
||||
'view' => 'view',
|
||||
'create' => 'create',
|
||||
'update' => 'update',
|
||||
'delete' => 'delete',
|
||||
];
|
||||
|
||||
foreach ($abilities as $ability => $method) {
|
||||
@@ -254,11 +278,7 @@ class Gate implements GateContract
|
||||
public function check($abilities, $arguments = [])
|
||||
{
|
||||
return collect($abilities)->every(function ($ability) use ($arguments) {
|
||||
try {
|
||||
return (bool) $this->raw($ability, $arguments);
|
||||
} catch (AuthorizationException $e) {
|
||||
return false;
|
||||
}
|
||||
return $this->inspect($ability, $arguments)->allowed();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -276,6 +296,18 @@ class Gate implements GateContract
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if all of the given abilities should be denied for the current user.
|
||||
*
|
||||
* @param iterable|string $abilities
|
||||
* @param array|mixed $arguments
|
||||
* @return bool
|
||||
*/
|
||||
public function none($abilities, $arguments = [])
|
||||
{
|
||||
return ! $this->any($abilities, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given ability should be granted for the current user.
|
||||
*
|
||||
@@ -287,13 +319,29 @@ class Gate implements GateContract
|
||||
*/
|
||||
public function authorize($ability, $arguments = [])
|
||||
{
|
||||
$result = $this->raw($ability, $arguments);
|
||||
return $this->inspect($ability, $arguments)->authorize();
|
||||
}
|
||||
|
||||
if ($result instanceof Response) {
|
||||
return $result;
|
||||
/**
|
||||
* Inspect the user for the given ability.
|
||||
*
|
||||
* @param string $ability
|
||||
* @param array|mixed $arguments
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*/
|
||||
public function inspect($ability, $arguments = [])
|
||||
{
|
||||
try {
|
||||
$result = $this->raw($ability, $arguments);
|
||||
|
||||
if ($result instanceof Response) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $result ? Response::allow() : Response::deny();
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->toResponse();
|
||||
}
|
||||
|
||||
return $result ? $this->allow() : $this->deny();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -302,6 +350,8 @@ class Gate implements GateContract
|
||||
* @param string $ability
|
||||
* @param array|mixed $arguments
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function raw($ability, $arguments = [])
|
||||
{
|
||||
@@ -333,7 +383,7 @@ class Gate implements GateContract
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable|null $user
|
||||
* @param \Closure|string|array $class
|
||||
* @param string|null $method
|
||||
* @param string|null $method
|
||||
* @return bool
|
||||
*/
|
||||
protected function canBeCalledWithUser($user, $class, $method = null)
|
||||
@@ -386,6 +436,8 @@ class Gate implements GateContract
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return bool
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
protected function callbackAllowsGuests($callback)
|
||||
{
|
||||
@@ -402,7 +454,7 @@ class Gate implements GateContract
|
||||
*/
|
||||
protected function parameterAllowsGuests($parameter)
|
||||
{
|
||||
return ($parameter->getClass() && $parameter->allowsNull()) ||
|
||||
return ($parameter->hasType() && $parameter->allowsNull()) ||
|
||||
($parameter->isDefaultValueAvailable() && is_null($parameter->getDefaultValue()));
|
||||
}
|
||||
|
||||
@@ -431,14 +483,12 @@ class Gate implements GateContract
|
||||
*/
|
||||
protected function callBeforeCallbacks($user, $ability, array $arguments)
|
||||
{
|
||||
$arguments = array_merge([$user, $ability], [$arguments]);
|
||||
|
||||
foreach ($this->beforeCallbacks as $before) {
|
||||
if (! $this->canBeCalledWithUser($user, $before)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! is_null($result = $before(...$arguments))) {
|
||||
if (! is_null($result = $before($user, $ability, $arguments))) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -484,13 +534,21 @@ class Gate implements GateContract
|
||||
return $callback;
|
||||
}
|
||||
|
||||
if (isset($this->stringCallbacks[$ability])) {
|
||||
[$class, $method] = Str::parseCallback($this->stringCallbacks[$ability]);
|
||||
|
||||
if ($this->canBeCalledWithUser($user, $class, $method ?: '__invoke')) {
|
||||
return $this->abilities[$ability];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->abilities[$ability]) &&
|
||||
$this->canBeCalledWithUser($user, $this->abilities[$ability])) {
|
||||
return $this->abilities[$ability];
|
||||
}
|
||||
|
||||
return function () {
|
||||
return null;
|
||||
//
|
||||
};
|
||||
}
|
||||
|
||||
@@ -514,6 +572,12 @@ class Gate implements GateContract
|
||||
return $this->resolvePolicy($this->policies[$class]);
|
||||
}
|
||||
|
||||
foreach ($this->guessPolicyName($class) as $guessedPolicy) {
|
||||
if (class_exists($guessedPolicy)) {
|
||||
return $this->resolvePolicy($guessedPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->policies as $expected => $policy) {
|
||||
if (is_subclass_of($class, $expected)) {
|
||||
return $this->resolvePolicy($policy);
|
||||
@@ -521,11 +585,43 @@ class Gate implements GateContract
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess the policy name for the given class.
|
||||
*
|
||||
* @param string $class
|
||||
* @return array
|
||||
*/
|
||||
protected function guessPolicyName($class)
|
||||
{
|
||||
if ($this->guessPolicyNamesUsingCallback) {
|
||||
return Arr::wrap(call_user_func($this->guessPolicyNamesUsingCallback, $class));
|
||||
}
|
||||
|
||||
$classDirname = str_replace('/', '\\', dirname(str_replace('\\', '/', $class)));
|
||||
|
||||
return [$classDirname.'\\Policies\\'.class_basename($class).'Policy'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a callback to be used to guess policy names.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function guessPolicyNamesUsing(callable $callback)
|
||||
{
|
||||
$this->guessPolicyNamesUsingCallback = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a policy class instance of the given type.
|
||||
*
|
||||
* @param object|string $class
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function resolvePolicy($class)
|
||||
{
|
||||
@@ -580,7 +676,7 @@ class Gate implements GateContract
|
||||
protected function callPolicyBefore($policy, $user, $ability, $arguments)
|
||||
{
|
||||
if (! method_exists($policy, 'before')) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->canBeCalledWithUser($user, $policy, 'before')) {
|
||||
@@ -607,7 +703,7 @@ class Gate implements GateContract
|
||||
}
|
||||
|
||||
if (! is_callable([$policy, $method])) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->canBeCalledWithUser($user, $policy, $method)) {
|
||||
@@ -640,7 +736,8 @@ class Gate implements GateContract
|
||||
|
||||
return new static(
|
||||
$this->container, $callback, $this->abilities,
|
||||
$this->policies, $this->beforeCallbacks, $this->afterCallbacks
|
||||
$this->policies, $this->beforeCallbacks, $this->afterCallbacks,
|
||||
$this->guessPolicyNamesUsingCallback
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,23 +8,23 @@ trait HandlesAuthorization
|
||||
* Create a new access response.
|
||||
*
|
||||
* @param string|null $message
|
||||
* @param mixed $code
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*/
|
||||
protected function allow($message = null)
|
||||
protected function allow($message = null, $code = null)
|
||||
{
|
||||
return new Response($message);
|
||||
return Response::allow($message, $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an unauthorized exception.
|
||||
*
|
||||
* @param string $message
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @param string|null $message
|
||||
* @param mixed|null $code
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*/
|
||||
protected function deny($message = 'This action is unauthorized.')
|
||||
protected function deny($message = null, $code = null)
|
||||
{
|
||||
throw new AuthorizationException($message);
|
||||
return Response::deny($message, $code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,17 @@
|
||||
|
||||
namespace Illuminate\Auth\Access;
|
||||
|
||||
class Response
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
class Response implements Arrayable
|
||||
{
|
||||
/**
|
||||
* Indicates whether the response was allowed.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $allowed;
|
||||
|
||||
/**
|
||||
* The response message.
|
||||
*
|
||||
@@ -11,17 +20,72 @@ class Response
|
||||
*/
|
||||
protected $message;
|
||||
|
||||
/**
|
||||
* The response code.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* Create a new response.
|
||||
*
|
||||
* @param string|null $message
|
||||
* @param bool $allowed
|
||||
* @param string $message
|
||||
* @param mixed $code
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($message = null)
|
||||
public function __construct($allowed, $message = '', $code = null)
|
||||
{
|
||||
$this->code = $code;
|
||||
$this->allowed = $allowed;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new "allow" Response.
|
||||
*
|
||||
* @param string|null $message
|
||||
* @param mixed $code
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*/
|
||||
public static function allow($message = null, $code = null)
|
||||
{
|
||||
return new static(true, $message, $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new "deny" Response.
|
||||
*
|
||||
* @param string|null $message
|
||||
* @param mixed $code
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*/
|
||||
public static function deny($message = null, $code = null)
|
||||
{
|
||||
return new static(false, $message, $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the response was allowed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function allowed()
|
||||
{
|
||||
return $this->allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the response was denied.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function denied()
|
||||
{
|
||||
return ! $this->allowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response message.
|
||||
*
|
||||
@@ -32,6 +96,47 @@ class Response
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response code / reason.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function code()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw authorization exception if response was denied.
|
||||
*
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
if ($this->denied()) {
|
||||
throw (new AuthorizationException($this->message(), $this->code()))
|
||||
->setResponse($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the response to an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'allowed' => $this->allowed(),
|
||||
'message' => $this->message(),
|
||||
'code' => $this->code(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string representation of the message.
|
||||
*
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
namespace Illuminate\Auth;
|
||||
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Contracts\Auth\Factory as FactoryContract;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class AuthManager implements FactoryContract
|
||||
{
|
||||
@@ -13,7 +13,7 @@ class AuthManager implements FactoryContract
|
||||
/**
|
||||
* The application instance.
|
||||
*
|
||||
* @var \Illuminate\Foundation\Application
|
||||
* @var \Illuminate\Contracts\Foundation\Application
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
@@ -43,7 +43,7 @@ class AuthManager implements FactoryContract
|
||||
/**
|
||||
* Create a new Auth manager instance.
|
||||
*
|
||||
* @param \Illuminate\Foundation\Application $app
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($app)
|
||||
@@ -58,7 +58,7 @@ class AuthManager implements FactoryContract
|
||||
/**
|
||||
* Attempt to get the guard from the local cache.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $name
|
||||
* @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
public function guard($name = null)
|
||||
@@ -94,7 +94,9 @@ class AuthManager implements FactoryContract
|
||||
return $this->{$driverMethod}($name, $config);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Auth driver [{$config['driver']}] for guard [{$name}] is not defined.");
|
||||
throw new InvalidArgumentException(
|
||||
"Auth driver [{$config['driver']}] for guard [{$name}] is not defined."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,7 +158,8 @@ class AuthManager implements FactoryContract
|
||||
$this->createUserProvider($config['provider'] ?? null),
|
||||
$this->app['request'],
|
||||
$config['input_key'] ?? 'api_token',
|
||||
$config['storage_key'] ?? 'api_token'
|
||||
$config['storage_key'] ?? 'api_token',
|
||||
$config['hash'] ?? false
|
||||
);
|
||||
|
||||
$this->app->refresh('request', $guard, 'setRequest');
|
||||
@@ -282,6 +285,16 @@ class AuthManager implements FactoryContract
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if any guards have already been resolved.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasResolvedGuards()
|
||||
{
|
||||
return count($this->guards) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically call the default driver instance.
|
||||
*
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
namespace Illuminate\Auth;
|
||||
|
||||
use Illuminate\Auth\Access\Gate;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Auth\Middleware\RequirePassword;
|
||||
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
||||
use Illuminate\Contracts\Routing\ResponseFactory;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -17,12 +20,11 @@ class AuthServiceProvider extends ServiceProvider
|
||||
public function register()
|
||||
{
|
||||
$this->registerAuthenticator();
|
||||
|
||||
$this->registerUserResolver();
|
||||
|
||||
$this->registerAccessGate();
|
||||
|
||||
$this->registerRequirePassword();
|
||||
$this->registerRequestRebindHandler();
|
||||
$this->registerEventRebindHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,6 +81,24 @@ class AuthServiceProvider extends ServiceProvider
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerRequirePassword()
|
||||
{
|
||||
$this->app->bind(
|
||||
RequirePassword::class, function ($app) {
|
||||
return new RequirePassword(
|
||||
$app[ResponseFactory::class],
|
||||
$app[UrlGenerator::class],
|
||||
$app['config']->get('auth.password_timeout')
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the re-binding of the request binding.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerRequestRebindHandler()
|
||||
{
|
||||
$this->app->rebinding('request', function ($app, $request) {
|
||||
@@ -87,4 +107,26 @@ class AuthServiceProvider extends ServiceProvider
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the re-binding of the event dispatcher binding.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerEventRebindHandler()
|
||||
{
|
||||
$this->app->rebinding('events', function ($app, $dispatcher) {
|
||||
if (! $app->resolved('auth')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($app['auth']->hasResolvedGuards() === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (method_exists($guard = $app['auth']->guard(), 'setDispatcher')) {
|
||||
$guard->setDispatcher($dispatcher);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Auth\Console;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Console\DetectsApplicationNamespace;
|
||||
|
||||
class AuthMakeCommand extends Command
|
||||
{
|
||||
use DetectsApplicationNamespace;
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'make:auth
|
||||
{--views : Only scaffold the authentication views}
|
||||
{--force : Overwrite existing views by default}';
|
||||
|
||||
/**
|
||||
* 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/verify.stub' => 'auth/verify.blade.php',
|
||||
'auth/passwords/email.stub' => 'auth/passwords/email.blade.php',
|
||||
'auth/passwords/reset.stub' => 'auth/passwords/reset.blade.php',
|
||||
'layouts/app.stub' => 'layouts/app.blade.php',
|
||||
'home.stub' => 'home.blade.php',
|
||||
];
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->createDirectories();
|
||||
|
||||
$this->exportViews();
|
||||
|
||||
if (! $this->option('views')) {
|
||||
file_put_contents(
|
||||
app_path('Http/Controllers/HomeController.php'),
|
||||
$this->compileControllerStub()
|
||||
);
|
||||
|
||||
file_put_contents(
|
||||
base_path('routes/web.php'),
|
||||
file_get_contents(__DIR__.'/stubs/make/routes.stub'),
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
$this->info('Authentication scaffolding generated successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the directories for the files.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function createDirectories()
|
||||
{
|
||||
if (! is_dir($directory = resource_path('views/layouts'))) {
|
||||
mkdir($directory, 0755, true);
|
||||
}
|
||||
|
||||
if (! is_dir($directory = resource_path('views/auth/passwords'))) {
|
||||
mkdir($directory, 0755, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the authentication views.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function exportViews()
|
||||
{
|
||||
foreach ($this->views as $key => $value) {
|
||||
if (file_exists($view = resource_path('views/'.$value)) && ! $this->option('force')) {
|
||||
if (! $this->confirm("The [{$value}] view already exists. Do you want to replace it?")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
copy(
|
||||
__DIR__.'/stubs/make/views/'.$key,
|
||||
$view
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the HomeController stub.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileControllerStub()
|
||||
{
|
||||
return str_replace(
|
||||
'{{namespace}}',
|
||||
$this->getAppNamespace(),
|
||||
file_get_contents(__DIR__.'/stubs/make/controllers/HomeController.stub')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace {{namespace}}Http\Controllers;
|
||||
|
||||
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\Contracts\Support\Renderable
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('home');
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
Auth::routes();
|
||||
|
||||
Route::get('/home', 'HomeController@index')->name('home');
|
||||
@@ -1,73 +0,0 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Login') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('login') }}">
|
||||
@csrf
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autofocus>
|
||||
|
||||
@if ($errors->has('email'))
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('email') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
|
||||
|
||||
@if ($errors->has('password'))
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('password') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
|
||||
|
||||
<label class="form-check-label" for="remember">
|
||||
{{ __('Remember Me') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Login') }}
|
||||
</button>
|
||||
|
||||
@if (Route::has('password.request'))
|
||||
<a class="btn btn-link" href="{{ route('password.request') }}">
|
||||
{{ __('Forgot Your Password?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -1,47 +0,0 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Reset Password') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('password.email') }}">
|
||||
@csrf
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required>
|
||||
|
||||
@if ($errors->has('email'))
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('email') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Send Password Reset Link') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -1,65 +0,0 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Reset Password') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('password.update') }}">
|
||||
@csrf
|
||||
|
||||
<input type="hidden" name="token" value="{{ $token }}">
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ $email ?? old('email') }}" required autofocus>
|
||||
|
||||
@if ($errors->has('email'))
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('email') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
|
||||
|
||||
@if ($errors->has('password'))
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('password') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Reset Password') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -1,77 +0,0 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Register') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('register') }}">
|
||||
@csrf
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name') }}" required autofocus>
|
||||
|
||||
@if ($errors->has('name'))
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('name') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required>
|
||||
|
||||
@if ($errors->has('email'))
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('email') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
|
||||
|
||||
@if ($errors->has('password'))
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('password') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Register') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -1,24 +0,0 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Verify Your Email Address') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
@if (session('resent'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ __('A fresh verification link has been sent to your email address.') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{ __('Before proceeding, please check your email for a verification link.') }}
|
||||
{{ __('If you did not receive the email') }}, <a href="{{ route('verification.resend') }}">{{ __('click here to request another') }}</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -1,23 +0,0 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">Dashboard</div>
|
||||
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
You are logged in!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -14,14 +14,14 @@
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="dns-prefetch" href="//fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
|
||||
|
||||
<!-- Styles -->
|
||||
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<nav class="navbar navbar-expand-md navbar-light navbar-laravel">
|
||||
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="{{ url('/') }}">
|
||||
{{ config('app.name', 'Laravel') }}
|
||||
|
||||
@@ -66,7 +66,7 @@ trait CreatesUserProviders
|
||||
*/
|
||||
protected function createDatabaseProvider($config)
|
||||
{
|
||||
$connection = $this->app['db']->connection();
|
||||
$connection = $this->app['db']->connection($config['connection'] ?? null);
|
||||
|
||||
return new DatabaseUserProvider($connection, $this->app['hash'], $config['table']);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
namespace Illuminate\Auth;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DatabaseUserProvider implements UserProvider
|
||||
{
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
namespace Illuminate\Auth;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class EloquentUserProvider implements UserProvider
|
||||
{
|
||||
@@ -47,9 +47,9 @@ class EloquentUserProvider implements UserProvider
|
||||
{
|
||||
$model = $this->createModel();
|
||||
|
||||
return $model->newQuery()
|
||||
->where($model->getAuthIdentifierName(), $identifier)
|
||||
->first();
|
||||
return $this->newModelQuery($model)
|
||||
->where($model->getAuthIdentifierName(), $identifier)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,15 +63,18 @@ class EloquentUserProvider implements UserProvider
|
||||
{
|
||||
$model = $this->createModel();
|
||||
|
||||
$model = $model->where($model->getAuthIdentifierName(), $identifier)->first();
|
||||
$retrievedModel = $this->newModelQuery($model)->where(
|
||||
$model->getAuthIdentifierName(), $identifier
|
||||
)->first();
|
||||
|
||||
if (! $model) {
|
||||
return null;
|
||||
if (! $retrievedModel) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rememberToken = $model->getRememberToken();
|
||||
$rememberToken = $retrievedModel->getRememberToken();
|
||||
|
||||
return $rememberToken && hash_equals($rememberToken, $token) ? $model : null;
|
||||
return $rememberToken && hash_equals($rememberToken, $token)
|
||||
? $retrievedModel : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,14 +107,14 @@ class EloquentUserProvider implements UserProvider
|
||||
{
|
||||
if (empty($credentials) ||
|
||||
(count($credentials) === 1 &&
|
||||
array_key_exists('password', $credentials))) {
|
||||
Str::contains($this->firstCredentialKey($credentials), 'password'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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();
|
||||
$query = $this->newModelQuery();
|
||||
|
||||
foreach ($credentials as $key => $value) {
|
||||
if (Str::contains($key, 'password')) {
|
||||
@@ -128,6 +131,19 @@ class EloquentUserProvider implements UserProvider
|
||||
return $query->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first key from the credential array.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return string|null
|
||||
*/
|
||||
protected function firstCredentialKey(array $credentials)
|
||||
{
|
||||
foreach ($credentials as $key => $value) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a user against the given credentials.
|
||||
*
|
||||
@@ -142,6 +158,19 @@ class EloquentUserProvider implements UserProvider
|
||||
return $this->hasher->check($plain, $user->getAuthPassword());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new query builder for the model instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model|null $model
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function newModelQuery($model = null)
|
||||
{
|
||||
return is_null($model)
|
||||
? $this->createModel()->newQuery()
|
||||
: $model->newQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the model.
|
||||
*
|
||||
|
||||
37
vendor/laravel/framework/src/Illuminate/Auth/Events/CurrentDeviceLogout.php
vendored
Normal file
37
vendor/laravel/framework/src/Illuminate/Auth/Events/CurrentDeviceLogout.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Auth\Events;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CurrentDeviceLogout
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* The authentication guard name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $guard;
|
||||
|
||||
/**
|
||||
* The authenticated user.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Auth\Authenticatable
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $guard
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($guard, $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->guard = $guard;
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ class Login
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $guard
|
||||
* @param string $guard
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
||||
* @param bool $remember
|
||||
* @return void
|
||||
|
||||
@@ -25,7 +25,7 @@ class Logout
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $guard
|
||||
* @param string $guard
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
||||
* @return void
|
||||
*/
|
||||
|
||||
37
vendor/laravel/framework/src/Illuminate/Auth/Events/OtherDeviceLogout.php
vendored
Normal file
37
vendor/laravel/framework/src/Illuminate/Auth/Events/OtherDeviceLogout.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Auth\Events;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class OtherDeviceLogout
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* The authentication guard name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $guard;
|
||||
|
||||
/**
|
||||
* The authenticated user.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Auth\Authenticatable
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $guard
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($guard, $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->guard = $guard;
|
||||
}
|
||||
}
|
||||
37
vendor/laravel/framework/src/Illuminate/Auth/Events/Validated.php
vendored
Normal file
37
vendor/laravel/framework/src/Illuminate/Auth/Events/Validated.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Auth\Events;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class Validated
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* The authentication guard name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $guard;
|
||||
|
||||
/**
|
||||
* The user retrieved and validated from the User Provider.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Auth\Authenticatable
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $guard
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($guard, $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->guard = $guard;
|
||||
}
|
||||
}
|
||||
@@ -41,9 +41,7 @@ class GenericUser implements UserContract
|
||||
*/
|
||||
public function getAuthIdentifier()
|
||||
{
|
||||
$name = $this->getAuthIdentifierName();
|
||||
|
||||
return $this->attributes[$name];
|
||||
return $this->attributes[$this->getAuthIdentifierName()];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Illuminate\Auth;
|
||||
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
|
||||
/**
|
||||
* These methods are typically the same across all guards.
|
||||
@@ -73,7 +73,7 @@ trait GuardHelpers
|
||||
/**
|
||||
* Get the ID for the currently authenticated user.
|
||||
*
|
||||
* @return int|null
|
||||
* @return int|string|null
|
||||
*/
|
||||
public function id()
|
||||
{
|
||||
|
||||
@@ -5,8 +5,9 @@ namespace Illuminate\Auth\Middleware;
|
||||
use Closure;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Contracts\Auth\Factory as Auth;
|
||||
use Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests;
|
||||
|
||||
class Authenticate
|
||||
class Authenticate implements AuthenticatesRequests
|
||||
{
|
||||
/**
|
||||
* The authentication factory instance.
|
||||
@@ -64,6 +65,20 @@ class Authenticate
|
||||
}
|
||||
}
|
||||
|
||||
$this->unauthenticated($request, $guards);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an unauthenticated user.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param array $guards
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Auth\AuthenticationException
|
||||
*/
|
||||
protected function unauthenticated($request, array $guards)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
'Unauthenticated.', $guards, $this->redirectTo($request)
|
||||
);
|
||||
@@ -73,7 +88,7 @@ class Authenticate
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
namespace Illuminate\Auth\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Contracts\Auth\Access\Gate;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Authorize
|
||||
{
|
||||
@@ -50,7 +50,7 @@ class Authorize
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param array|null $models
|
||||
* @return array|string|\Illuminate\Database\Eloquent\Model
|
||||
* @return \Illuminate\Database\Eloquent\Model|array|string
|
||||
*/
|
||||
protected function getGateArguments($request, $models)
|
||||
{
|
||||
@@ -72,7 +72,12 @@ class Authorize
|
||||
*/
|
||||
protected function getModel($request, $model)
|
||||
{
|
||||
return $this->isClassName($model) ? trim($model) : $request->route($model, $model);
|
||||
if ($this->isClassName($model)) {
|
||||
return trim($model);
|
||||
} else {
|
||||
return $request->route($model, null) ?:
|
||||
((preg_match("/^['\"](.*)['\"]$/", trim($model), $matches)) ? $matches[1] : null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
namespace Illuminate\Auth\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
class EnsureEmailIsVerified
|
||||
{
|
||||
@@ -13,16 +13,17 @@ class EnsureEmailIsVerified
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $redirectToRoute
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
public function handle($request, Closure $next, $redirectToRoute = null)
|
||||
{
|
||||
if (! $request->user() ||
|
||||
($request->user() instanceof MustVerifyEmail &&
|
||||
! $request->user()->hasVerifiedEmail())) {
|
||||
return $request->expectsJson()
|
||||
? abort(403, 'Your email address is not verified.')
|
||||
: Redirect::route('verification.notice');
|
||||
: Redirect::route($redirectToRoute ?: 'verification.notice');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
||||
84
vendor/laravel/framework/src/Illuminate/Auth/Middleware/RequirePassword.php
vendored
Normal file
84
vendor/laravel/framework/src/Illuminate/Auth/Middleware/RequirePassword.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Auth\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Routing\ResponseFactory;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
|
||||
class RequirePassword
|
||||
{
|
||||
/**
|
||||
* The response factory instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Routing\ResponseFactory
|
||||
*/
|
||||
protected $responseFactory;
|
||||
|
||||
/**
|
||||
* The URL generator instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Routing\UrlGenerator
|
||||
*/
|
||||
protected $urlGenerator;
|
||||
|
||||
/**
|
||||
* The password timeout.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $passwordTimeout;
|
||||
|
||||
/**
|
||||
* Create a new middleware instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Routing\ResponseFactory $responseFactory
|
||||
* @param \Illuminate\Contracts\Routing\UrlGenerator $urlGenerator
|
||||
* @param int|null $passwordTimeout
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ResponseFactory $responseFactory, UrlGenerator $urlGenerator, $passwordTimeout = null)
|
||||
{
|
||||
$this->responseFactory = $responseFactory;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->passwordTimeout = $passwordTimeout ?: 10800;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $redirectToRoute
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, $redirectToRoute = null)
|
||||
{
|
||||
if ($this->shouldConfirmPassword($request)) {
|
||||
if ($request->expectsJson()) {
|
||||
return $this->responseFactory->json([
|
||||
'message' => 'Password confirmation required.',
|
||||
], 423);
|
||||
}
|
||||
|
||||
return $this->responseFactory->redirectGuest(
|
||||
$this->urlGenerator->route($redirectToRoute ?? 'password.confirm')
|
||||
);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the confirmation timeout has expired.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return bool
|
||||
*/
|
||||
protected function shouldConfirmPassword($request)
|
||||
{
|
||||
$confirmedAt = time() - $request->session()->get('auth.password_confirmed_at', 0);
|
||||
|
||||
return $confirmedAt > $this->passwordTimeout;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Illuminate\Auth;
|
||||
|
||||
use Illuminate\Auth\Notifications\VerifyEmail;
|
||||
|
||||
trait MustVerifyEmail
|
||||
{
|
||||
/**
|
||||
@@ -33,6 +35,16 @@ trait MustVerifyEmail
|
||||
*/
|
||||
public function sendEmailVerificationNotification()
|
||||
{
|
||||
$this->notify(new Notifications\VerifyEmail);
|
||||
$this->notify(new VerifyEmail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the email address that should be used for verification.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEmailForVerification()
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace Illuminate\Auth\Notifications;
|
||||
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
|
||||
class ResetPassword extends Notification
|
||||
{
|
||||
@@ -15,6 +15,13 @@ class ResetPassword extends Notification
|
||||
*/
|
||||
public $token;
|
||||
|
||||
/**
|
||||
* The callback that should be used to create the reset password URL.
|
||||
*
|
||||
* @var \Closure|null
|
||||
*/
|
||||
public static $createUrlCallback;
|
||||
|
||||
/**
|
||||
* The callback that should be used to build the mail message.
|
||||
*
|
||||
@@ -56,12 +63,32 @@ class ResetPassword extends Notification
|
||||
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
|
||||
}
|
||||
|
||||
if (static::$createUrlCallback) {
|
||||
$url = call_user_func(static::$createUrlCallback, $notifiable, $this->token);
|
||||
} else {
|
||||
$url = url(route('password.reset', [
|
||||
'token' => $this->token,
|
||||
'email' => $notifiable->getEmailForPasswordReset(),
|
||||
], false));
|
||||
}
|
||||
|
||||
return (new MailMessage)
|
||||
->subject(Lang::getFromJson('Reset Password Notification'))
|
||||
->line(Lang::getFromJson('You are receiving this email because we received a password reset request for your account.'))
|
||||
->action(Lang::getFromJson('Reset Password'), url(config('app.url').route('password.reset', $this->token, false)))
|
||||
->line(Lang::getFromJson('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.users.expire')]))
|
||||
->line(Lang::getFromJson('If you did not request a password reset, no further action is required.'));
|
||||
->subject(Lang::get('Reset Password Notification'))
|
||||
->line(Lang::get('You are receiving this email because we received a password reset request for your account.'))
|
||||
->action(Lang::get('Reset Password'), $url)
|
||||
->line(Lang::get('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]))
|
||||
->line(Lang::get('If you did not request a password reset, no further action is required.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback that should be used when creating the reset password button URL.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
public static function createUrlUsing($callback)
|
||||
{
|
||||
static::$createUrlCallback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
namespace Illuminate\Auth\Notifications;
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class VerifyEmail extends Notification
|
||||
{
|
||||
@@ -36,18 +37,17 @@ class VerifyEmail extends Notification
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
$verificationUrl = $this->verificationUrl($notifiable);
|
||||
|
||||
if (static::$toMailCallback) {
|
||||
return call_user_func(static::$toMailCallback, $notifiable);
|
||||
return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);
|
||||
}
|
||||
|
||||
return (new MailMessage)
|
||||
->subject(Lang::getFromJson('Verify Email Address'))
|
||||
->line(Lang::getFromJson('Please click the button below to verify your email address.'))
|
||||
->action(
|
||||
Lang::getFromJson('Verify Email Address'),
|
||||
$this->verificationUrl($notifiable)
|
||||
)
|
||||
->line(Lang::getFromJson('If you did not create an account, no further action is required.'));
|
||||
->subject(Lang::get('Verify Email Address'))
|
||||
->line(Lang::get('Please click the button below to verify your email address.'))
|
||||
->action(Lang::get('Verify Email Address'), $verificationUrl)
|
||||
->line(Lang::get('If you did not create an account, no further action is required.'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +59,12 @@ class VerifyEmail extends Notification
|
||||
protected function verificationUrl($notifiable)
|
||||
{
|
||||
return URL::temporarySignedRoute(
|
||||
'verification.verify', Carbon::now()->addMinutes(60), ['id' => $notifiable->getKey()]
|
||||
'verification.verify',
|
||||
Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
|
||||
[
|
||||
'id' => $notifiable->getKey(),
|
||||
'hash' => sha1($notifiable->getEmailForVerification()),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
namespace Illuminate\Auth\Passwords;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
|
||||
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
|
||||
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DatabaseTokenRepository implements TokenRepositoryInterface
|
||||
{
|
||||
@@ -45,6 +45,13 @@ class DatabaseTokenRepository implements TokenRepositoryInterface
|
||||
*/
|
||||
protected $expires;
|
||||
|
||||
/**
|
||||
* Minimum number of seconds before re-redefining the token.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $throttle;
|
||||
|
||||
/**
|
||||
* Create a new token repository instance.
|
||||
*
|
||||
@@ -53,16 +60,19 @@ class DatabaseTokenRepository implements TokenRepositoryInterface
|
||||
* @param string $table
|
||||
* @param string $hashKey
|
||||
* @param int $expires
|
||||
* @param int $throttle
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ConnectionInterface $connection, HasherContract $hasher,
|
||||
$table, $hashKey, $expires = 60)
|
||||
$table, $hashKey, $expires = 60,
|
||||
$throttle = 60)
|
||||
{
|
||||
$this->table = $table;
|
||||
$this->hasher = $hasher;
|
||||
$this->hashKey = $hashKey;
|
||||
$this->expires = $expires * 60;
|
||||
$this->connection = $connection;
|
||||
$this->throttle = $throttle;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,6 +149,38 @@ class DatabaseTokenRepository implements TokenRepositoryInterface
|
||||
return Carbon::parse($createdAt)->addSeconds($this->expires)->isPast();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given user recently created a password reset token.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
|
||||
* @return bool
|
||||
*/
|
||||
public function recentlyCreatedToken(CanResetPasswordContract $user)
|
||||
{
|
||||
$record = (array) $this->getTable()->where(
|
||||
'email', $user->getEmailForPasswordReset()
|
||||
)->first();
|
||||
|
||||
return $record && $this->tokenRecentlyCreated($record['created_at']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the token was recently created.
|
||||
*
|
||||
* @param string $createdAt
|
||||
* @return bool
|
||||
*/
|
||||
protected function tokenRecentlyCreated($createdAt)
|
||||
{
|
||||
if ($this->throttle <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Carbon::parse($createdAt)->addSeconds(
|
||||
$this->throttle
|
||||
)->isFuture();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a token record by user.
|
||||
*
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
namespace Illuminate\Auth\Passwords;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
|
||||
use Illuminate\Contracts\Auth\PasswordBroker as PasswordBrokerContract;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Support\Arr;
|
||||
use UnexpectedValueException;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Contracts\Auth\PasswordBroker as PasswordBrokerContract;
|
||||
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
|
||||
|
||||
class PasswordBroker implements PasswordBrokerContract
|
||||
{
|
||||
@@ -25,13 +25,6 @@ class PasswordBroker implements PasswordBrokerContract
|
||||
*/
|
||||
protected $users;
|
||||
|
||||
/**
|
||||
* The custom password validator callback.
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $passwordValidator;
|
||||
|
||||
/**
|
||||
* Create a new password broker instance.
|
||||
*
|
||||
@@ -39,8 +32,7 @@ class PasswordBroker implements PasswordBrokerContract
|
||||
* @param \Illuminate\Contracts\Auth\UserProvider $users
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(TokenRepositoryInterface $tokens,
|
||||
UserProvider $users)
|
||||
public function __construct(TokenRepositoryInterface $tokens, UserProvider $users)
|
||||
{
|
||||
$this->users = $users;
|
||||
$this->tokens = $tokens;
|
||||
@@ -63,6 +55,10 @@ class PasswordBroker implements PasswordBrokerContract
|
||||
return static::INVALID_USER;
|
||||
}
|
||||
|
||||
if ($this->tokens->recentlyCreatedToken($user)) {
|
||||
return static::RESET_THROTTLED;
|
||||
}
|
||||
|
||||
// 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.
|
||||
@@ -82,11 +78,11 @@ class PasswordBroker implements PasswordBrokerContract
|
||||
*/
|
||||
public function reset(array $credentials, Closure $callback)
|
||||
{
|
||||
$user = $this->validateReset($credentials);
|
||||
|
||||
// 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;
|
||||
}
|
||||
@@ -115,10 +111,6 @@ class PasswordBroker implements PasswordBrokerContract
|
||||
return static::INVALID_USER;
|
||||
}
|
||||
|
||||
if (! $this->validateNewPassword($credentials)) {
|
||||
return static::INVALID_PASSWORD;
|
||||
}
|
||||
|
||||
if (! $this->tokens->exists($user, $credentials['token'])) {
|
||||
return static::INVALID_TOKEN;
|
||||
}
|
||||
@@ -126,55 +118,6 @@ class PasswordBroker implements PasswordBrokerContract
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if (isset($this->passwordValidator)) {
|
||||
[$password, $confirm] = [
|
||||
$credentials['password'],
|
||||
$credentials['password_confirmation'],
|
||||
];
|
||||
|
||||
return call_user_func(
|
||||
$this->passwordValidator, $credentials
|
||||
) && $password === $confirm;
|
||||
}
|
||||
|
||||
return $this->validatePasswordWithDefaults($credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the passwords are valid for the request.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return bool
|
||||
*/
|
||||
protected function validatePasswordWithDefaults(array $credentials)
|
||||
{
|
||||
[$password, $confirm] = [
|
||||
$credentials['password'],
|
||||
$credentials['password_confirmation'],
|
||||
];
|
||||
|
||||
return $password === $confirm && mb_strlen($password) >= 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user for the given credentials.
|
||||
*
|
||||
@@ -199,7 +142,7 @@ class PasswordBroker implements PasswordBrokerContract
|
||||
/**
|
||||
* Create a new password reset token for the given user.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
|
||||
* @return string
|
||||
*/
|
||||
public function createToken(CanResetPasswordContract $user)
|
||||
@@ -210,7 +153,7 @@ class PasswordBroker implements PasswordBrokerContract
|
||||
/**
|
||||
* Delete password reset tokens of the given user.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
|
||||
* @return void
|
||||
*/
|
||||
public function deleteToken(CanResetPasswordContract $user)
|
||||
@@ -221,8 +164,8 @@ class PasswordBroker implements PasswordBrokerContract
|
||||
/**
|
||||
* Validate the given password reset token.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
|
||||
* @param string $token
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
|
||||
* @param string $token
|
||||
* @return bool
|
||||
*/
|
||||
public function tokenExists(CanResetPasswordContract $user, $token)
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace Illuminate\Auth\Passwords;
|
||||
|
||||
use Illuminate\Contracts\Auth\PasswordBrokerFactory as FactoryContract;
|
||||
use Illuminate\Support\Str;
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Contracts\Auth\PasswordBrokerFactory as FactoryContract;
|
||||
|
||||
/**
|
||||
* @mixin \Illuminate\Contracts\Auth\PasswordBroker
|
||||
@@ -14,7 +14,7 @@ class PasswordBrokerManager implements FactoryContract
|
||||
/**
|
||||
* The application instance.
|
||||
*
|
||||
* @var \Illuminate\Foundation\Application
|
||||
* @var \Illuminate\Contracts\Foundation\Application
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
@@ -28,7 +28,7 @@ class PasswordBrokerManager implements FactoryContract
|
||||
/**
|
||||
* Create a new PasswordBroker manager instance.
|
||||
*
|
||||
* @param \Illuminate\Foundation\Application $app
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($app)
|
||||
@@ -46,9 +46,7 @@ class PasswordBrokerManager implements FactoryContract
|
||||
{
|
||||
$name = $name ?: $this->getDefaultDriver();
|
||||
|
||||
return isset($this->brokers[$name])
|
||||
? $this->brokers[$name]
|
||||
: $this->brokers[$name] = $this->resolve($name);
|
||||
return $this->brokers[$name] ?? ($this->brokers[$name] = $this->resolve($name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +95,8 @@ class PasswordBrokerManager implements FactoryContract
|
||||
$this->app['hash'],
|
||||
$config['table'],
|
||||
$key,
|
||||
$config['expire']
|
||||
$config['expire'],
|
||||
$config['throttle'] ?? 0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -137,7 +136,7 @@ class PasswordBrokerManager implements FactoryContract
|
||||
* Dynamically call the default driver instance.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
|
||||
@@ -2,17 +2,11 @@
|
||||
|
||||
namespace Illuminate\Auth\Passwords;
|
||||
|
||||
use Illuminate\Contracts\Support\DeferrableProvider;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class PasswordResetServiceProvider extends ServiceProvider
|
||||
class PasswordResetServiceProvider extends ServiceProvider implements DeferrableProvider
|
||||
{
|
||||
/**
|
||||
* Indicates if loading of the provider is deferred.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $defer = true;
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
|
||||
@@ -23,6 +23,14 @@ interface TokenRepositoryInterface
|
||||
*/
|
||||
public function exists(CanResetPasswordContract $user, $token);
|
||||
|
||||
/**
|
||||
* Determine if the given user recently created a password reset token.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
|
||||
* @return bool
|
||||
*/
|
||||
public function recentlyCreatedToken(CanResetPasswordContract $user);
|
||||
|
||||
/**
|
||||
* Delete a token record.
|
||||
*
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace Illuminate\Auth;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
|
||||
class RequestGuard implements Guard
|
||||
{
|
||||
@@ -30,7 +30,7 @@ class RequestGuard implements Guard
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Contracts\Auth\UserProvider|null $provider
|
||||
* @param \Illuminate\Contracts\Auth\UserProvider|null $provider
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(callable $callback, Request $request, UserProvider $provider = null)
|
||||
|
||||
@@ -2,19 +2,27 @@
|
||||
|
||||
namespace Illuminate\Auth;
|
||||
|
||||
use RuntimeException;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Contracts\Session\Session;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
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\HttpKernel\Exception\UnauthorizedHttpException;
|
||||
use Illuminate\Auth\Events\Attempting;
|
||||
use Illuminate\Auth\Events\Authenticated;
|
||||
use Illuminate\Auth\Events\CurrentDeviceLogout;
|
||||
use Illuminate\Auth\Events\Failed;
|
||||
use Illuminate\Auth\Events\Login;
|
||||
use Illuminate\Auth\Events\Logout;
|
||||
use Illuminate\Auth\Events\OtherDeviceLogout;
|
||||
use Illuminate\Auth\Events\Validated;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
||||
use Illuminate\Contracts\Auth\StatefulGuard;
|
||||
use Illuminate\Contracts\Auth\SupportsBasicAuth;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Contracts\Cookie\QueueingFactory as CookieJar;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Contracts\Session\Session;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
|
||||
|
||||
class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
{
|
||||
@@ -191,7 +199,7 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
/**
|
||||
* Get the ID for the currently authenticated user.
|
||||
*
|
||||
* @return int|null
|
||||
* @return int|string|null
|
||||
*/
|
||||
public function id()
|
||||
{
|
||||
@@ -339,7 +347,7 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
* Attempt to authenticate a user using the given credentials.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @param bool $remember
|
||||
* @param bool $remember
|
||||
* @return bool
|
||||
*/
|
||||
public function attempt(array $credentials = [], $remember = false)
|
||||
@@ -374,14 +382,20 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
*/
|
||||
protected function hasValidCredentials($user, $credentials)
|
||||
{
|
||||
return ! is_null($user) && $this->provider->validateCredentials($user, $credentials);
|
||||
$validated = ! is_null($user) && $this->provider->validateCredentials($user, $credentials);
|
||||
|
||||
if ($validated) {
|
||||
$this->fireValidatedEvent($user);
|
||||
}
|
||||
|
||||
return $validated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the given user ID into the application.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param bool $remember
|
||||
* @param bool $remember
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|false
|
||||
*/
|
||||
public function loginUsingId($id, $remember = false)
|
||||
@@ -482,17 +496,17 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
{
|
||||
$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)) {
|
||||
if (! is_null($this->user) && ! empty($user->getRememberToken())) {
|
||||
$this->cycleRememberToken($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.
|
||||
if (isset($this->events)) {
|
||||
$this->events->dispatch(new Events\Logout($this->name, $user));
|
||||
$this->events->dispatch(new Logout($this->name, $user));
|
||||
}
|
||||
|
||||
// Once we have fired the logout event we will clear the users out of memory
|
||||
@@ -531,6 +545,32 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
$this->provider->updateRememberToken($user, $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the user out of the application on their current device only.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function logoutCurrentDevice()
|
||||
{
|
||||
$user = $this->user();
|
||||
|
||||
$this->clearUserDataFromStorage();
|
||||
|
||||
// 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.
|
||||
if (isset($this->events)) {
|
||||
$this->events->dispatch(new CurrentDeviceLogout($this->name, $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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate other sessions for the current user.
|
||||
*
|
||||
@@ -550,7 +590,12 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
$attribute => Hash::make($password),
|
||||
]))->save();
|
||||
|
||||
$this->queueRecallerCookie($this->user());
|
||||
if ($this->recaller() ||
|
||||
$this->getCookieJar()->hasQueued($this->getRecallerName())) {
|
||||
$this->queueRecallerCookie($this->user());
|
||||
}
|
||||
|
||||
$this->fireOtherDeviceLogoutEvent($this->user());
|
||||
|
||||
return $result;
|
||||
}
|
||||
@@ -578,12 +623,27 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
protected function fireAttemptEvent(array $credentials, $remember = false)
|
||||
{
|
||||
if (isset($this->events)) {
|
||||
$this->events->dispatch(new Events\Attempting(
|
||||
$this->events->dispatch(new Attempting(
|
||||
$this->name, $credentials, $remember
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires the validated event if the dispatcher is set.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
||||
* @return void
|
||||
*/
|
||||
protected function fireValidatedEvent($user)
|
||||
{
|
||||
if (isset($this->events)) {
|
||||
$this->events->dispatch(new Validated(
|
||||
$this->name, $user
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire the login event if the dispatcher is set.
|
||||
*
|
||||
@@ -594,7 +654,7 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
protected function fireLoginEvent($user, $remember = false)
|
||||
{
|
||||
if (isset($this->events)) {
|
||||
$this->events->dispatch(new Events\Login(
|
||||
$this->events->dispatch(new Login(
|
||||
$this->name, $user, $remember
|
||||
));
|
||||
}
|
||||
@@ -609,7 +669,22 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
protected function fireAuthenticatedEvent($user)
|
||||
{
|
||||
if (isset($this->events)) {
|
||||
$this->events->dispatch(new Events\Authenticated(
|
||||
$this->events->dispatch(new Authenticated(
|
||||
$this->name, $user
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire the other device logout event if the dispatcher is set.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
||||
* @return void
|
||||
*/
|
||||
protected function fireOtherDeviceLogoutEvent($user)
|
||||
{
|
||||
if (isset($this->events)) {
|
||||
$this->events->dispatch(new OtherDeviceLogout(
|
||||
$this->name, $user
|
||||
));
|
||||
}
|
||||
@@ -625,7 +700,7 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
protected function fireFailedEvent($user, array $credentials)
|
||||
{
|
||||
if (isset($this->events)) {
|
||||
$this->events->dispatch(new Events\Failed(
|
||||
$this->events->dispatch(new Failed(
|
||||
$this->name, $user, $credentials
|
||||
));
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace Illuminate\Auth;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TokenGuard implements Guard
|
||||
{
|
||||
@@ -31,6 +31,13 @@ class TokenGuard implements Guard
|
||||
*/
|
||||
protected $storageKey;
|
||||
|
||||
/**
|
||||
* Indicates if the API token is hashed in storage.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $hash = false;
|
||||
|
||||
/**
|
||||
* Create a new authentication guard.
|
||||
*
|
||||
@@ -38,10 +45,17 @@ class TokenGuard implements Guard
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $inputKey
|
||||
* @param string $storageKey
|
||||
* @param bool $hash
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(UserProvider $provider, Request $request, $inputKey = 'api_token', $storageKey = 'api_token')
|
||||
public function __construct(
|
||||
UserProvider $provider,
|
||||
Request $request,
|
||||
$inputKey = 'api_token',
|
||||
$storageKey = 'api_token',
|
||||
$hash = false)
|
||||
{
|
||||
$this->hash = $hash;
|
||||
$this->request = $request;
|
||||
$this->provider = $provider;
|
||||
$this->inputKey = $inputKey;
|
||||
@@ -67,9 +81,9 @@ class TokenGuard implements Guard
|
||||
$token = $this->getTokenForRequest();
|
||||
|
||||
if (! empty($token)) {
|
||||
$user = $this->provider->retrieveByCredentials(
|
||||
[$this->storageKey => $token]
|
||||
);
|
||||
$user = $this->provider->retrieveByCredentials([
|
||||
$this->storageKey => $this->hash ? hash('sha256', $token) : $token,
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->user = $user;
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.7.*",
|
||||
"illuminate/http": "5.7.*",
|
||||
"illuminate/queue": "5.7.*",
|
||||
"illuminate/support": "5.7.*"
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/http": "^7.0",
|
||||
"illuminate/queue": "^7.0",
|
||||
"illuminate/support": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -27,13 +27,13 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.7-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/console": "Required to use the auth:clear-resets command (5.7.*).",
|
||||
"illuminate/queue": "Required to fire login / logout events (5.7.*).",
|
||||
"illuminate/session": "Required to use the session based guard (5.7.*)."
|
||||
"illuminate/console": "Required to use the auth:clear-resets command (^7.0).",
|
||||
"illuminate/queue": "Required to fire login / logout events (^7.0).",
|
||||
"illuminate/session": "Required to use the session based guard (^7.0)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace Illuminate\Broadcasting;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\Broadcaster;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Broadcasting\Broadcaster;
|
||||
use Illuminate\Support\Arr;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
|
||||
class BroadcastEvent implements ShouldQueue
|
||||
{
|
||||
@@ -21,6 +21,20 @@ class BroadcastEvent implements ShouldQueue
|
||||
*/
|
||||
public $event;
|
||||
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries;
|
||||
|
||||
/**
|
||||
* The number of seconds the job can run before timing out.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $timeout;
|
||||
|
||||
/**
|
||||
* Create a new job handler instance.
|
||||
*
|
||||
@@ -30,6 +44,8 @@ class BroadcastEvent implements ShouldQueue
|
||||
public function __construct($event)
|
||||
{
|
||||
$this->event = $event;
|
||||
$this->tries = property_exists($event, 'tries') ? $event->tries : null;
|
||||
$this->timeout = property_exists($event, 'timeout') ? $event->timeout : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,15 +3,17 @@
|
||||
namespace Illuminate\Broadcasting;
|
||||
|
||||
use Closure;
|
||||
use Pusher\Pusher;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Broadcasting\Broadcasters\LogBroadcaster;
|
||||
use Illuminate\Broadcasting\Broadcasters\NullBroadcaster;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
|
||||
use Illuminate\Broadcasting\Broadcasters\RedisBroadcaster;
|
||||
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
|
||||
use Illuminate\Broadcasting\Broadcasters\RedisBroadcaster;
|
||||
use Illuminate\Contracts\Broadcasting\Factory as FactoryContract;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
|
||||
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcherContract;
|
||||
use Illuminate\Contracts\Foundation\CachesRoutes;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Pusher\Pusher;
|
||||
|
||||
/**
|
||||
* @mixin \Illuminate\Contracts\Broadcasting\Broadcaster
|
||||
@@ -21,7 +23,7 @@ class BroadcastManager implements FactoryContract
|
||||
/**
|
||||
* The application instance.
|
||||
*
|
||||
* @var \Illuminate\Foundation\Application
|
||||
* @var \Illuminate\Contracts\Container\Container
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
@@ -42,7 +44,7 @@ class BroadcastManager implements FactoryContract
|
||||
/**
|
||||
* Create a new manager instance.
|
||||
*
|
||||
* @param \Illuminate\Foundation\Application $app
|
||||
* @param \Illuminate\Contracts\Container\Container $app
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($app)
|
||||
@@ -58,7 +60,7 @@ class BroadcastManager implements FactoryContract
|
||||
*/
|
||||
public function routes(array $attributes = null)
|
||||
{
|
||||
if ($this->app->routesAreCached()) {
|
||||
if ($this->app instanceof CachesRoutes && $this->app->routesAreCached()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -93,7 +95,7 @@ class BroadcastManager implements FactoryContract
|
||||
* Begin broadcasting an event.
|
||||
*
|
||||
* @param mixed|null $event
|
||||
* @return \Illuminate\Broadcasting\PendingBroadcast|void
|
||||
* @return \Illuminate\Broadcasting\PendingBroadcast
|
||||
*/
|
||||
public function event($event = null)
|
||||
{
|
||||
@@ -108,10 +110,8 @@ class BroadcastManager implements FactoryContract
|
||||
*/
|
||||
public function queue($event)
|
||||
{
|
||||
$connection = $event instanceof ShouldBroadcastNow ? 'sync' : null;
|
||||
|
||||
if (is_null($connection) && isset($event->connection)) {
|
||||
$connection = $event->connection;
|
||||
if ($event instanceof ShouldBroadcastNow) {
|
||||
return $this->app->make(BusDispatcherContract::class)->dispatchNow(new BroadcastEvent(clone $event));
|
||||
}
|
||||
|
||||
$queue = null;
|
||||
@@ -124,7 +124,7 @@ class BroadcastManager implements FactoryContract
|
||||
$queue = $event->queue;
|
||||
}
|
||||
|
||||
$this->app->make('queue')->connection($connection)->pushOn(
|
||||
$this->app->make('queue')->connection($event->connection ?? null)->pushOn(
|
||||
$queue, new BroadcastEvent(clone $event)
|
||||
);
|
||||
}
|
||||
@@ -132,7 +132,7 @@ class BroadcastManager implements FactoryContract
|
||||
/**
|
||||
* Get a driver instance.
|
||||
*
|
||||
* @param string $driver
|
||||
* @param string|null $driver
|
||||
* @return mixed
|
||||
*/
|
||||
public function connection($driver = null)
|
||||
@@ -165,7 +165,7 @@ class BroadcastManager implements FactoryContract
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the given store.
|
||||
* Resolve the given broadcaster.
|
||||
*
|
||||
* @param string $name
|
||||
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
|
||||
@@ -229,7 +229,8 @@ class BroadcastManager implements FactoryContract
|
||||
protected function createRedisDriver(array $config)
|
||||
{
|
||||
return new RedisBroadcaster(
|
||||
$this->app->make('redis'), $config['connection'] ?? null
|
||||
$this->app->make('redis'), $config['connection'] ?? null,
|
||||
$this->app['config']->get('database.redis.options.prefix', '')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -296,7 +297,7 @@ class BroadcastManager implements FactoryContract
|
||||
/**
|
||||
* Register a custom driver creator Closure.
|
||||
*
|
||||
* @param string $driver
|
||||
* @param string $driver
|
||||
* @param \Closure $callback
|
||||
* @return $this
|
||||
*/
|
||||
@@ -311,7 +312,7 @@ class BroadcastManager implements FactoryContract
|
||||
* Dynamically call the default driver instance.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
|
||||
@@ -2,19 +2,13 @@
|
||||
|
||||
namespace Illuminate\Broadcasting;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Contracts\Broadcasting\Factory as BroadcastingFactory;
|
||||
use Illuminate\Contracts\Broadcasting\Broadcaster as BroadcasterContract;
|
||||
use Illuminate\Contracts\Broadcasting\Factory as BroadcastingFactory;
|
||||
use Illuminate\Contracts\Support\DeferrableProvider;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BroadcastServiceProvider extends ServiceProvider
|
||||
class BroadcastServiceProvider extends ServiceProvider implements DeferrableProvider
|
||||
{
|
||||
/**
|
||||
* Indicates if loading of the provider is deferred.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $defer = true;
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
|
||||
@@ -3,14 +3,16 @@
|
||||
namespace Illuminate\Broadcasting\Broadcasters;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Contracts\Broadcasting\Broadcaster as BroadcasterContract;
|
||||
use Illuminate\Contracts\Routing\BindingRegistrar;
|
||||
use Illuminate\Contracts\Routing\UrlRoutable;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Reflector;
|
||||
use Illuminate\Support\Str;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Contracts\Routing\UrlRoutable;
|
||||
use Illuminate\Contracts\Routing\BindingRegistrar;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Illuminate\Contracts\Broadcasting\Broadcaster as BroadcasterContract;
|
||||
|
||||
abstract class Broadcaster implements BroadcasterContract
|
||||
{
|
||||
@@ -21,6 +23,13 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
*/
|
||||
protected $channels = [];
|
||||
|
||||
/**
|
||||
* The registered channel options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $channelOptions = [];
|
||||
|
||||
/**
|
||||
* The binding registrar instance.
|
||||
*
|
||||
@@ -33,12 +42,15 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
*
|
||||
* @param string $channel
|
||||
* @param callable|string $callback
|
||||
* @param array $options
|
||||
* @return $this
|
||||
*/
|
||||
public function channel($channel, $callback)
|
||||
public function channel($channel, $callback, $options = [])
|
||||
{
|
||||
$this->channels[$channel] = $callback;
|
||||
|
||||
$this->channelOptions[$channel] = $options;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -54,7 +66,7 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
protected function verifyUserCanAccessChannel($request, $channel)
|
||||
{
|
||||
foreach ($this->channels as $pattern => $callback) {
|
||||
if (! Str::is(preg_replace('/\{(.*?)\}/', '*', $pattern), $channel)) {
|
||||
if (! $this->channelNameMatchesPattern($channel, $pattern)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -62,7 +74,7 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
|
||||
$handler = $this->normalizeChannelHandlerToCallable($callback);
|
||||
|
||||
if ($result = $handler($request->user(), ...$parameters)) {
|
||||
if ($result = $handler($this->retrieveUser($request, $channel), ...$parameters)) {
|
||||
return $this->validAuthenticationResponse($request, $result);
|
||||
}
|
||||
}
|
||||
@@ -193,9 +205,9 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
continue;
|
||||
}
|
||||
|
||||
$instance = $parameter->getClass()->newInstance();
|
||||
$className = Reflector::getParameterClassName($parameter);
|
||||
|
||||
if (! $model = $instance->resolveRouteBinding($value)) {
|
||||
if (is_null($model = (new $className)->resolveRouteBinding($value))) {
|
||||
throw new AccessDeniedHttpException;
|
||||
}
|
||||
|
||||
@@ -214,8 +226,8 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
*/
|
||||
protected function isImplicitlyBindable($key, $parameter)
|
||||
{
|
||||
return $parameter->name === $key && $parameter->getClass() &&
|
||||
$parameter->getClass()->isSubclassOf(UrlRoutable::class);
|
||||
return $parameter->getName() === $key &&
|
||||
Reflector::isParameterSubclassOf($parameter, UrlRoutable::class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,7 +262,7 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
* Normalize the given callback into a callable.
|
||||
*
|
||||
* @param mixed $callback
|
||||
* @return callable|\Closure
|
||||
* @return callable
|
||||
*/
|
||||
protected function normalizeChannelHandlerToCallable($callback)
|
||||
{
|
||||
@@ -260,4 +272,59 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
->join(...$args);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the authenticated user using the configured guard (if any).
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $channel
|
||||
* @return mixed
|
||||
*/
|
||||
protected function retrieveUser($request, $channel)
|
||||
{
|
||||
$options = $this->retrieveChannelOptions($channel);
|
||||
|
||||
$guards = $options['guards'] ?? null;
|
||||
|
||||
if (is_null($guards)) {
|
||||
return $request->user();
|
||||
}
|
||||
|
||||
foreach (Arr::wrap($guards) as $guard) {
|
||||
if ($user = $request->user($guard)) {
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve options for a certain channel.
|
||||
*
|
||||
* @param string $channel
|
||||
* @return array
|
||||
*/
|
||||
protected function retrieveChannelOptions($channel)
|
||||
{
|
||||
foreach ($this->channelOptions as $pattern => $options) {
|
||||
if (! $this->channelNameMatchesPattern($channel, $pattern)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if channel name from request match a pattern from registered channels.
|
||||
*
|
||||
* @param string $channel
|
||||
* @param string $pattern
|
||||
* @return bool
|
||||
*/
|
||||
protected function channelNameMatchesPattern($channel, $pattern)
|
||||
{
|
||||
return Str::is(preg_replace('/\{(.*?)\}/', '*', $pattern), $channel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,16 @@
|
||||
|
||||
namespace Illuminate\Broadcasting\Broadcasters;
|
||||
|
||||
use Pusher\Pusher;
|
||||
use Illuminate\Broadcasting\BroadcastException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Broadcasting\BroadcastException;
|
||||
use Pusher\Pusher;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
|
||||
class PusherBroadcaster extends Broadcaster
|
||||
{
|
||||
use UsePusherChannelConventions;
|
||||
|
||||
/**
|
||||
* The Pusher SDK instance.
|
||||
*
|
||||
@@ -38,15 +40,13 @@ class PusherBroadcaster extends Broadcaster
|
||||
*/
|
||||
public function auth($request)
|
||||
{
|
||||
if (Str::startsWith($request->channel_name, ['private-', 'presence-']) &&
|
||||
! $request->user()) {
|
||||
$channelName = $this->normalizeChannelName($request->channel_name);
|
||||
|
||||
if ($this->isGuardedChannel($request->channel_name) &&
|
||||
! $this->retrieveUser($request, $channelName)) {
|
||||
throw new AccessDeniedHttpException;
|
||||
}
|
||||
|
||||
$channelName = Str::startsWith($request->channel_name, 'private-')
|
||||
? Str::replaceFirst('private-', '', $request->channel_name)
|
||||
: Str::replaceFirst('presence-', '', $request->channel_name);
|
||||
|
||||
return parent::verifyUserCanAccessChannel(
|
||||
$request, $channelName
|
||||
);
|
||||
@@ -67,11 +67,13 @@ class PusherBroadcaster extends Broadcaster
|
||||
);
|
||||
}
|
||||
|
||||
$channelName = $this->normalizeChannelName($request->channel_name);
|
||||
|
||||
return $this->decodePusherResponse(
|
||||
$request,
|
||||
$this->pusher->presence_auth(
|
||||
$request->channel_name, $request->socket_id,
|
||||
$request->user()->getAuthIdentifier(), $result
|
||||
$this->retrieveUser($request, $channelName)->getAuthIdentifier(), $result
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -100,6 +102,8 @@ class PusherBroadcaster extends Broadcaster
|
||||
* @param string $event
|
||||
* @param array $payload
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Broadcasting\BroadcastException
|
||||
*/
|
||||
public function broadcast(array $channels, $event, array $payload = [])
|
||||
{
|
||||
@@ -115,7 +119,9 @@ class PusherBroadcaster extends Broadcaster
|
||||
}
|
||||
|
||||
throw new BroadcastException(
|
||||
is_bool($response) ? 'Failed to connect to Pusher.' : $response['body']
|
||||
! empty($response['body'])
|
||||
? sprintf('Pusher error: %s.', $response['body'])
|
||||
: 'Failed to connect to Pusher.'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
|
||||
namespace Illuminate\Broadcasting\Broadcasters;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Contracts\Redis\Factory as Redis;
|
||||
use Illuminate\Support\Arr;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
|
||||
class RedisBroadcaster extends Broadcaster
|
||||
{
|
||||
use UsePusherChannelConventions;
|
||||
|
||||
/**
|
||||
* The Redis instance.
|
||||
*
|
||||
@@ -23,16 +24,25 @@ class RedisBroadcaster extends Broadcaster
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* The Redis key prefix.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* Create a new broadcaster instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Redis\Factory $redis
|
||||
* @param string|null $connection
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Redis $redis, $connection = null)
|
||||
public function __construct(Redis $redis, $connection = null, $prefix = '')
|
||||
{
|
||||
$this->redis = $redis;
|
||||
$this->prefix = $prefix;
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
@@ -46,15 +56,15 @@ class RedisBroadcaster extends Broadcaster
|
||||
*/
|
||||
public function auth($request)
|
||||
{
|
||||
if (Str::startsWith($request->channel_name, ['private-', 'presence-']) &&
|
||||
! $request->user()) {
|
||||
$channelName = $this->normalizeChannelName(
|
||||
str_replace($this->prefix, '', $request->channel_name)
|
||||
);
|
||||
|
||||
if ($this->isGuardedChannel($request->channel_name) &&
|
||||
! $this->retrieveUser($request, $channelName)) {
|
||||
throw new AccessDeniedHttpException;
|
||||
}
|
||||
|
||||
$channelName = Str::startsWith($request->channel_name, 'private-')
|
||||
? Str::replaceFirst('private-', '', $request->channel_name)
|
||||
: Str::replaceFirst('presence-', '', $request->channel_name);
|
||||
|
||||
return parent::verifyUserCanAccessChannel(
|
||||
$request, $channelName
|
||||
);
|
||||
@@ -73,8 +83,10 @@ class RedisBroadcaster extends Broadcaster
|
||||
return json_encode($result);
|
||||
}
|
||||
|
||||
$channelName = $this->normalizeChannelName($request->channel_name);
|
||||
|
||||
return json_encode(['channel_data' => [
|
||||
'user_id' => $request->user()->getAuthIdentifier(),
|
||||
'user_id' => $this->retrieveUser($request, $channelName)->getAuthIdentifier(),
|
||||
'user_info' => $result,
|
||||
]]);
|
||||
}
|
||||
@@ -89,6 +101,10 @@ class RedisBroadcaster extends Broadcaster
|
||||
*/
|
||||
public function broadcast(array $channels, $event, array $payload = [])
|
||||
{
|
||||
if (empty($channels)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$connection = $this->redis->connection($this->connection);
|
||||
|
||||
$payload = json_encode([
|
||||
@@ -97,8 +113,39 @@ class RedisBroadcaster extends Broadcaster
|
||||
'socket' => Arr::pull($payload, 'socket'),
|
||||
]);
|
||||
|
||||
foreach ($this->formatChannels($channels) as $channel) {
|
||||
$connection->publish($channel, $payload);
|
||||
}
|
||||
$connection->eval(
|
||||
$this->broadcastMultipleChannelsScript(),
|
||||
0, $payload, ...$this->formatChannels($channels)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Lua script for broadcasting to multiple channels.
|
||||
*
|
||||
* ARGV[1] - The payload
|
||||
* ARGV[2...] - The channels
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function broadcastMultipleChannelsScript()
|
||||
{
|
||||
return <<<'LUA'
|
||||
for i = 2, #ARGV do
|
||||
redis.call('publish', ARGV[i], ARGV[1])
|
||||
end
|
||||
LUA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the channel array into an array of strings.
|
||||
*
|
||||
* @param array $channels
|
||||
* @return array
|
||||
*/
|
||||
protected function formatChannels(array $channels)
|
||||
{
|
||||
return array_map(function ($channel) {
|
||||
return $this->prefix.$channel;
|
||||
}, parent::formatChannels($channels));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Broadcasting\Broadcasters;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait UsePusherChannelConventions
|
||||
{
|
||||
/**
|
||||
* Return true if channel is protected by authentication.
|
||||
*
|
||||
* @param string $channel
|
||||
* @return bool
|
||||
*/
|
||||
public function isGuardedChannel($channel)
|
||||
{
|
||||
return Str::startsWith($channel, ['private-', 'presence-']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove prefix from channel name.
|
||||
*
|
||||
* @param string $channel
|
||||
* @return string
|
||||
*/
|
||||
public function normalizeChannelName($channel)
|
||||
{
|
||||
foreach (['private-encrypted-', 'private-', 'presence-'] as $prefix) {
|
||||
if (Str::startsWith($channel, $prefix)) {
|
||||
return Str::replaceFirst($prefix, '', $channel);
|
||||
}
|
||||
}
|
||||
|
||||
return $channel;
|
||||
}
|
||||
}
|
||||
17
vendor/laravel/framework/src/Illuminate/Broadcasting/EncryptedPrivateChannel.php
vendored
Normal file
17
vendor/laravel/framework/src/Illuminate/Broadcasting/EncryptedPrivateChannel.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Broadcasting;
|
||||
|
||||
class EncryptedPrivateChannel extends Channel
|
||||
{
|
||||
/**
|
||||
* Create a new channel instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
parent::__construct('private-encrypted-'.$name);
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,13 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"php": "^7.2.5|^8.0",
|
||||
"ext-json": "*",
|
||||
"psr/log": "^1.0",
|
||||
"illuminate/bus": "5.7.*",
|
||||
"illuminate/contracts": "5.7.*",
|
||||
"illuminate/queue": "5.7.*",
|
||||
"illuminate/support": "5.7.*"
|
||||
"illuminate/bus": "^7.0",
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/queue": "^7.0",
|
||||
"illuminate/support": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -28,11 +29,11 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.7-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^3.0)."
|
||||
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^4.0)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
|
||||
@@ -2,20 +2,14 @@
|
||||
|
||||
namespace Illuminate\Bus;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Contracts\Bus\Dispatcher as DispatcherContract;
|
||||
use Illuminate\Contracts\Queue\Factory as QueueFactoryContract;
|
||||
use Illuminate\Contracts\Bus\QueueingDispatcher as QueueingDispatcherContract;
|
||||
use Illuminate\Contracts\Queue\Factory as QueueFactoryContract;
|
||||
use Illuminate\Contracts\Support\DeferrableProvider;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BusServiceProvider extends ServiceProvider
|
||||
class BusServiceProvider extends ServiceProvider implements DeferrableProvider
|
||||
{
|
||||
/**
|
||||
* Indicates if loading of the provider is deferred.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $defer = true;
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
namespace Illuminate\Bus;
|
||||
|
||||
use Closure;
|
||||
use RuntimeException;
|
||||
use Illuminate\Pipeline\Pipeline;
|
||||
use Illuminate\Contracts\Bus\QueueingDispatcher;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\Queue\Queue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\Bus\QueueingDispatcher;
|
||||
use Illuminate\Pipeline\Pipeline;
|
||||
use RuntimeException;
|
||||
|
||||
class Dispatcher implements QueueingDispatcher
|
||||
{
|
||||
@@ -140,8 +140,6 @@ class Dispatcher implements QueueingDispatcher
|
||||
*
|
||||
* @param mixed $command
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function dispatchToQueue($command)
|
||||
{
|
||||
@@ -184,6 +182,20 @@ class Dispatcher implements QueueingDispatcher
|
||||
return $queue->push($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch a command to its appropriate handler after the current process.
|
||||
*
|
||||
* @param mixed $command
|
||||
* @param mixed $handler
|
||||
* @return void
|
||||
*/
|
||||
public function dispatchAfterResponse($command, $handler = null)
|
||||
{
|
||||
$this->container->terminating(function () use ($command, $handler) {
|
||||
$this->dispatchNow($command, $handler);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pipes through which commands should be piped before dispatching.
|
||||
*
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
namespace Illuminate\Bus;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Queue\CallQueuedClosure;
|
||||
use Illuminate\Support\Arr;
|
||||
use RuntimeException;
|
||||
|
||||
trait Queueable
|
||||
{
|
||||
/**
|
||||
@@ -39,6 +44,13 @@ trait Queueable
|
||||
*/
|
||||
public $delay;
|
||||
|
||||
/**
|
||||
* The middleware the job should be dispatched through.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $middleware = [];
|
||||
|
||||
/**
|
||||
* The jobs that should run if this job is successful.
|
||||
*
|
||||
@@ -113,6 +125,19 @@ trait Queueable
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the middleware the job should be dispatched through.
|
||||
*
|
||||
* @param array|object $middleware
|
||||
* @return $this
|
||||
*/
|
||||
public function through($middleware)
|
||||
{
|
||||
$this->middleware = Arr::wrap($middleware);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the jobs that should run if this job is successful.
|
||||
*
|
||||
@@ -122,12 +147,33 @@ trait Queueable
|
||||
public function chain($chain)
|
||||
{
|
||||
$this->chained = collect($chain)->map(function ($job) {
|
||||
return serialize($job);
|
||||
return $this->serializeJob($job);
|
||||
})->all();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize a job for queuing.
|
||||
*
|
||||
* @param mixed $job
|
||||
* @return string
|
||||
*/
|
||||
protected function serializeJob($job)
|
||||
{
|
||||
if ($job instanceof Closure) {
|
||||
if (! class_exists(CallQueuedClosure::class)) {
|
||||
throw new RuntimeException(
|
||||
'To enable support for closure jobs, please install the illuminate/queue package.'
|
||||
);
|
||||
}
|
||||
|
||||
$job = CallQueuedClosure::create($job);
|
||||
}
|
||||
|
||||
return serialize($job);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the next job on the chain.
|
||||
*
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.7.*",
|
||||
"illuminate/pipeline": "5.7.*",
|
||||
"illuminate/support": "5.7.*"
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/pipeline": "^7.0",
|
||||
"illuminate/support": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -26,9 +26,12 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.7-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/queue": "Required to use closures when chaining jobs (^7.0)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
|
||||
class ApcStore extends TaggableStore implements Store
|
||||
class ApcStore extends TaggableStore
|
||||
{
|
||||
use RetrievesMultipleKeys;
|
||||
|
||||
@@ -51,23 +49,23 @@ class ApcStore extends TaggableStore implements Store
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache for a given number of minutes.
|
||||
* Store an item in the cache for a given number of seconds.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
public function put($key, $value, $seconds)
|
||||
{
|
||||
$this->apc->put($this->prefix.$key, $value, (int) ($minutes * 60));
|
||||
return $this->apc->put($this->prefix.$key, $value, $seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
@@ -79,7 +77,7 @@ class ApcStore extends TaggableStore implements Store
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
@@ -91,12 +89,12 @@ class ApcStore extends TaggableStore implements Store
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
$this->put($key, $value, 0);
|
||||
return $this->put($key, $value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,8 +36,8 @@ class ApcWrapper
|
||||
* Store an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return array|bool
|
||||
*/
|
||||
public function put($key, $value, $seconds)
|
||||
@@ -49,7 +49,7 @@ class ApcWrapper
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function increment($key, $value)
|
||||
@@ -61,7 +61,7 @@ class ApcWrapper
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function decrement($key, $value)
|
||||
|
||||
102
vendor/laravel/framework/src/Illuminate/Cache/ArrayLock.php
vendored
Normal file
102
vendor/laravel/framework/src/Illuminate/Cache/ArrayLock.php
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class ArrayLock extends Lock
|
||||
{
|
||||
/**
|
||||
* The parent array cache store.
|
||||
*
|
||||
* @var \Illuminate\Cache\ArrayStore
|
||||
*/
|
||||
protected $store;
|
||||
|
||||
/**
|
||||
* Create a new lock instance.
|
||||
*
|
||||
* @param \Illuminate\Cache\ArrayStore $store
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($store, $name, $seconds, $owner = null)
|
||||
{
|
||||
parent::__construct($name, $seconds, $owner);
|
||||
|
||||
$this->store = $store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to acquire the lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function acquire()
|
||||
{
|
||||
$expiration = $this->store->locks[$this->name]['expiresAt'] ?? Carbon::now()->addSecond();
|
||||
|
||||
if ($this->exists() && $expiration->isFuture()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->store->locks[$this->name] = [
|
||||
'owner' => $this->owner,
|
||||
'expiresAt' => $this->seconds === 0 ? null : Carbon::now()->addSeconds($this->seconds),
|
||||
];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the current lock exists.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function exists()
|
||||
{
|
||||
return isset($this->store->locks[$this->name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function release()
|
||||
{
|
||||
if (! $this->exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->isOwnedByCurrentProcess()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->forceRelease();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner value written into the driver for this lock.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getCurrentOwner()
|
||||
{
|
||||
return $this->store->locks[$this->name]['owner'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases this lock in disregard of ownership.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function forceRelease()
|
||||
{
|
||||
unset($this->store->locks[$this->name]);
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Contracts\Cache\LockProvider;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
|
||||
class ArrayStore extends TaggableStore implements Store
|
||||
class ArrayStore extends TaggableStore implements LockProvider
|
||||
{
|
||||
use RetrievesMultipleKeys;
|
||||
use InteractsWithTime, RetrievesMultipleKeys;
|
||||
|
||||
/**
|
||||
* The array of stored values.
|
||||
@@ -15,6 +16,31 @@ class ArrayStore extends TaggableStore implements Store
|
||||
*/
|
||||
protected $storage = [];
|
||||
|
||||
/**
|
||||
* The array of locks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $locks = [];
|
||||
|
||||
/**
|
||||
* Indicates if values are serialized within the store.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $serializesValues;
|
||||
|
||||
/**
|
||||
* Create a new Array store.
|
||||
*
|
||||
* @param bool $serializesValues
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($serializesValues = false)
|
||||
{
|
||||
$this->serializesValues = $serializesValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an item from the cache by key.
|
||||
*
|
||||
@@ -23,42 +49,68 @@ class ArrayStore extends TaggableStore implements Store
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
return $this->storage[$key] ?? null;
|
||||
if (! isset($this->storage[$key])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$item = $this->storage[$key];
|
||||
|
||||
$expiresAt = $item['expiresAt'] ?? 0;
|
||||
|
||||
if ($expiresAt !== 0 && $this->currentTime() > $expiresAt) {
|
||||
$this->forget($key);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->serializesValues ? unserialize($item['value']) : $item['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache for a given number of minutes.
|
||||
* Store an item in the cache for a given number of seconds.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
public function put($key, $value, $seconds)
|
||||
{
|
||||
$this->storage[$key] = $value;
|
||||
$this->storage[$key] = [
|
||||
'value' => $this->serializesValues ? serialize($value) : $value,
|
||||
'expiresAt' => $this->calculateExpiration($seconds),
|
||||
];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
{
|
||||
$this->storage[$key] = ! isset($this->storage[$key])
|
||||
? $value : ((int) $this->storage[$key]) + $value;
|
||||
if (! is_null($existing = $this->get($key))) {
|
||||
return tap(((int) $existing) + $value, function ($incremented) use ($key) {
|
||||
$value = $this->serializesValues ? serialize($incremented) : $incremented;
|
||||
|
||||
return $this->storage[$key];
|
||||
$this->storage[$key]['value'] = $value;
|
||||
});
|
||||
}
|
||||
|
||||
$this->forever($key, $value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
@@ -70,12 +122,12 @@ class ArrayStore extends TaggableStore implements Store
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
$this->put($key, $value, 0);
|
||||
return $this->put($key, $value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,9 +138,13 @@ class ArrayStore extends TaggableStore implements Store
|
||||
*/
|
||||
public function forget($key)
|
||||
{
|
||||
unset($this->storage[$key]);
|
||||
if (array_key_exists($key, $this->storage)) {
|
||||
unset($this->storage[$key]);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,4 +168,51 @@ class ArrayStore extends TaggableStore implements Store
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the expiration time of the key.
|
||||
*
|
||||
* @param int $seconds
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateExpiration($seconds)
|
||||
{
|
||||
return $this->toTimestamp($seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UNIX timestamp for the given number of seconds.
|
||||
*
|
||||
* @param int $seconds
|
||||
* @return int
|
||||
*/
|
||||
protected function toTimestamp($seconds)
|
||||
{
|
||||
return $seconds > 0 ? $this->availableAt($seconds) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a lock instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function lock($name, $seconds = 0, $owner = null)
|
||||
{
|
||||
return new ArrayLock($this, $name, $seconds, $owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a lock instance using the owner identifier.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function restoreLock($name, $owner)
|
||||
{
|
||||
return $this->lock($name, 0, $owner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Aws\DynamoDb\DynamoDbClient;
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Contracts\Cache\Factory as FactoryContract;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
|
||||
use Illuminate\Support\Arr;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @mixin \Illuminate\Contracts\Cache\Repository
|
||||
@@ -16,7 +18,7 @@ class CacheManager implements FactoryContract
|
||||
/**
|
||||
* The application instance.
|
||||
*
|
||||
* @var \Illuminate\Foundation\Application
|
||||
* @var \Illuminate\Contracts\Foundation\Application
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
@@ -37,7 +39,7 @@ class CacheManager implements FactoryContract
|
||||
/**
|
||||
* Create a new Cache manager instance.
|
||||
*
|
||||
* @param \Illuminate\Foundation\Application $app
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($app)
|
||||
@@ -136,11 +138,12 @@ class CacheManager implements FactoryContract
|
||||
/**
|
||||
* Create an instance of the array cache driver.
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Illuminate\Cache\Repository
|
||||
*/
|
||||
protected function createArrayDriver()
|
||||
protected function createArrayDriver(array $config)
|
||||
{
|
||||
return $this->repository(new ArrayStore);
|
||||
return $this->repository(new ArrayStore($config['serialize'] ?? false));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,7 +154,7 @@ class CacheManager implements FactoryContract
|
||||
*/
|
||||
protected function createFileDriver(array $config)
|
||||
{
|
||||
return $this->repository(new FileStore($this->app['files'], $config['path']));
|
||||
return $this->repository(new FileStore($this->app['files'], $config['path'], $config['permission'] ?? null));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,7 +214,43 @@ class CacheManager implements FactoryContract
|
||||
|
||||
return $this->repository(
|
||||
new DatabaseStore(
|
||||
$connection, $config['table'], $this->getPrefix($config)
|
||||
$connection,
|
||||
$config['table'],
|
||||
$this->getPrefix($config),
|
||||
$config['lock_table'] ?? 'cache_locks',
|
||||
$config['lock_lottery'] ?? [2, 100]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of the DynamoDB cache driver.
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Illuminate\Cache\Repository
|
||||
*/
|
||||
protected function createDynamodbDriver(array $config)
|
||||
{
|
||||
$dynamoConfig = [
|
||||
'region' => $config['region'],
|
||||
'version' => 'latest',
|
||||
'endpoint' => $config['endpoint'] ?? null,
|
||||
];
|
||||
|
||||
if ($config['key'] && $config['secret']) {
|
||||
$dynamoConfig['credentials'] = Arr::only(
|
||||
$config, ['key', 'secret', 'token']
|
||||
);
|
||||
}
|
||||
|
||||
return $this->repository(
|
||||
new DynamoDbStore(
|
||||
new DynamoDbClient($dynamoConfig),
|
||||
$config['table'],
|
||||
$config['attributes']['key'] ?? 'key',
|
||||
$config['attributes']['value'] ?? 'value',
|
||||
$config['attributes']['expiration'] ?? 'expires_at',
|
||||
$this->getPrefix($config)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -224,15 +263,36 @@ class CacheManager implements FactoryContract
|
||||
*/
|
||||
public function repository(Store $store)
|
||||
{
|
||||
$repository = new Repository($store);
|
||||
return tap(new Repository($store), function ($repository) {
|
||||
$this->setEventDispatcher($repository);
|
||||
});
|
||||
}
|
||||
|
||||
if ($this->app->bound(DispatcherContract::class)) {
|
||||
$repository->setEventDispatcher(
|
||||
$this->app[DispatcherContract::class]
|
||||
);
|
||||
/**
|
||||
* Set the event dispatcher on the given repository instance.
|
||||
*
|
||||
* @param \Illuminate\Cache\Repository $repository
|
||||
* @return void
|
||||
*/
|
||||
protected function setEventDispatcher(Repository $repository)
|
||||
{
|
||||
if (! $this->app->bound(DispatcherContract::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $repository;
|
||||
$repository->setEventDispatcher(
|
||||
$this->app[DispatcherContract::class]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-set the event dispatcher on all resolved cache repositories.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function refreshEventDispatcher()
|
||||
{
|
||||
array_map([$this, 'setEventDispatcher'], $this->stores);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,17 +2,12 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Contracts\Support\DeferrableProvider;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Symfony\Component\Cache\Adapter\Psr16Adapter;
|
||||
|
||||
class CacheServiceProvider extends ServiceProvider
|
||||
class CacheServiceProvider extends ServiceProvider implements DeferrableProvider
|
||||
{
|
||||
/**
|
||||
* Indicates if loading of the provider is deferred.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $defer = true;
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
@@ -28,6 +23,10 @@ class CacheServiceProvider extends ServiceProvider
|
||||
return $app['cache']->driver();
|
||||
});
|
||||
|
||||
$this->app->singleton('cache.psr6', function ($app) {
|
||||
return new Psr16Adapter($app['cache.store']);
|
||||
});
|
||||
|
||||
$this->app->singleton('memcached.connector', function () {
|
||||
return new MemcachedConnector;
|
||||
});
|
||||
@@ -41,7 +40,7 @@ class CacheServiceProvider extends ServiceProvider
|
||||
public function provides()
|
||||
{
|
||||
return [
|
||||
'cache', 'cache.store', 'memcached.connector',
|
||||
'cache', 'cache.store', 'cache.psr6', 'memcached.connector',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
namespace Illuminate\Cache\Console;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Composer;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Composer;
|
||||
|
||||
class CacheTableCommand extends Command
|
||||
{
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
namespace Illuminate\Cache\Console;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Cache\CacheManager;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
class ClearCommand extends Command
|
||||
{
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Illuminate\Cache\Console;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Cache\CacheManager;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class ForgetCommand extends Command
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateCacheTable extends Migration
|
||||
{
|
||||
|
||||
139
vendor/laravel/framework/src/Illuminate/Cache/DatabaseLock.php
vendored
Normal file
139
vendor/laravel/framework/src/Illuminate/Cache/DatabaseLock.php
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class DatabaseLock extends Lock
|
||||
{
|
||||
/**
|
||||
* The database connection instance.
|
||||
*
|
||||
* @var \Illuminate\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* The database table name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table;
|
||||
|
||||
/**
|
||||
* The prune probability odds.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $lottery;
|
||||
|
||||
/**
|
||||
* Create a new lock instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @param string $table
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @param array $lottery
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Connection $connection, $table, $name, $seconds, $owner = null, $lottery = [2, 100])
|
||||
{
|
||||
parent::__construct($name, $seconds, $owner);
|
||||
|
||||
$this->connection = $connection;
|
||||
$this->table = $table;
|
||||
$this->lottery = $lottery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to acquire the lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function acquire()
|
||||
{
|
||||
$acquired = false;
|
||||
|
||||
try {
|
||||
$this->connection->table($this->table)->insert([
|
||||
'key' => $this->name,
|
||||
'owner' => $this->owner,
|
||||
'expiration' => $this->expiresAt(),
|
||||
]);
|
||||
|
||||
$acquired = true;
|
||||
} catch (QueryException $e) {
|
||||
$updated = $this->connection->table($this->table)
|
||||
->where('key', $this->name)
|
||||
->where(function ($query) {
|
||||
return $query->where('owner', $this->owner)->orWhere('expiration', '<=', time());
|
||||
})->update([
|
||||
'owner' => $this->owner,
|
||||
'expiration' => $this->expiresAt(),
|
||||
]);
|
||||
|
||||
$acquired = $updated >= 1;
|
||||
}
|
||||
|
||||
if (random_int(1, $this->lottery[1]) <= $this->lottery[0]) {
|
||||
$this->connection->table($this->table)->where('expiration', '<=', time())->delete();
|
||||
}
|
||||
|
||||
return $acquired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UNIX timestamp indicating when the lock should expire.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function expiresAt()
|
||||
{
|
||||
return $this->seconds > 0 ? time() + $this->seconds : Carbon::now()->addDays(1)->getTimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function release()
|
||||
{
|
||||
if ($this->isOwnedByCurrentProcess()) {
|
||||
$this->connection->table($this->table)
|
||||
->where('key', $this->name)
|
||||
->where('owner', $this->owner)
|
||||
->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases this lock in disregard of ownership.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function forceRelease()
|
||||
{
|
||||
$this->connection->table($this->table)
|
||||
->where('key', $this->name)
|
||||
->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner value written into the driver for this lock.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getCurrentOwner()
|
||||
{
|
||||
return optional($this->connection->table($this->table)->where('key', $this->name)->first())->owner;
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,15 @@ namespace Illuminate\Cache;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Contracts\Cache\LockProvider;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Database\PostgresConnection;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Database\PostgresConnection;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DatabaseStore implements Store
|
||||
class DatabaseStore implements LockProvider, Store
|
||||
{
|
||||
use InteractsWithTime, RetrievesMultipleKeys;
|
||||
|
||||
@@ -35,19 +37,41 @@ class DatabaseStore implements Store
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* The name of the cache locks table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $lockTable;
|
||||
|
||||
/**
|
||||
* An array representation of the lock lottery odds.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $lockLottery;
|
||||
|
||||
/**
|
||||
* Create a new database store.
|
||||
*
|
||||
* @param \Illuminate\Database\ConnectionInterface $connection
|
||||
* @param string $table
|
||||
* @param string $prefix
|
||||
* @param string $lockTable
|
||||
* @param array $lockLottery
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ConnectionInterface $connection, $table, $prefix = '')
|
||||
public function __construct(ConnectionInterface $connection,
|
||||
$table,
|
||||
$prefix = '',
|
||||
$lockTable = 'cache_locks',
|
||||
$lockLottery = [2, 100])
|
||||
{
|
||||
$this->table = $table;
|
||||
$this->prefix = $prefix;
|
||||
$this->connection = $connection;
|
||||
$this->lockTable = $lockTable;
|
||||
$this->lockLottery = $lockLottery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,33 +108,62 @@ class DatabaseStore implements Store
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache for a given number of minutes.
|
||||
* Store an item in the cache for a given number of seconds.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
public function put($key, $value, $seconds)
|
||||
{
|
||||
$key = $this->prefix.$key;
|
||||
|
||||
$value = $this->serialize($value);
|
||||
|
||||
$expiration = $this->getTime() + (int) ($minutes * 60);
|
||||
$expiration = $this->getTime() + $seconds;
|
||||
|
||||
try {
|
||||
$this->table()->insert(compact('key', 'value', 'expiration'));
|
||||
return $this->table()->insert(compact('key', 'value', 'expiration'));
|
||||
} catch (Exception $e) {
|
||||
$this->table()->where('key', $key)->update(compact('value', 'expiration'));
|
||||
$result = $this->table()->where('key', $key)->update(compact('value', 'expiration'));
|
||||
|
||||
return $result > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache if the key doesn't exist.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function add($key, $value, $seconds)
|
||||
{
|
||||
$key = $this->prefix.$key;
|
||||
$value = $this->serialize($value);
|
||||
$expiration = $this->getTime() + $seconds;
|
||||
|
||||
try {
|
||||
return $this->table()->insert(compact('key', 'value', 'expiration'));
|
||||
} catch (QueryException $e) {
|
||||
return $this->table()
|
||||
->where('key', $key)
|
||||
->where('expiration', '<=', $this->getTime())
|
||||
->update([
|
||||
'value' => $value,
|
||||
'expiration' => $expiration,
|
||||
]) >= 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
@@ -124,7 +177,7 @@ class DatabaseStore implements Store
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
@@ -195,12 +248,44 @@ class DatabaseStore implements Store
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
$this->put($key, $value, 5256000);
|
||||
return $this->put($key, $value, 315360000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a lock instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function lock($name, $seconds = 0, $owner = null)
|
||||
{
|
||||
return new DatabaseLock(
|
||||
$this->connection,
|
||||
$this->lockTable,
|
||||
$this->prefix.$name,
|
||||
$seconds,
|
||||
$owner,
|
||||
$this->lockLottery
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a lock instance using the owner identifier.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function restoreLock($name, $owner)
|
||||
{
|
||||
return $this->lock($name, 0, $owner);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
75
vendor/laravel/framework/src/Illuminate/Cache/DynamoDbLock.php
vendored
Normal file
75
vendor/laravel/framework/src/Illuminate/Cache/DynamoDbLock.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
class DynamoDbLock extends Lock
|
||||
{
|
||||
/**
|
||||
* The DynamoDB client instance.
|
||||
*
|
||||
* @var \Illuminate\Cache\DynamoDbStore
|
||||
*/
|
||||
protected $dynamo;
|
||||
|
||||
/**
|
||||
* Create a new lock instance.
|
||||
*
|
||||
* @param \Illuminate\Cache\DynamoDbStore $dynamo
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(DynamoDbStore $dynamo, $name, $seconds, $owner = null)
|
||||
{
|
||||
parent::__construct($name, $seconds, $owner);
|
||||
|
||||
$this->dynamo = $dynamo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to acquire the lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function acquire()
|
||||
{
|
||||
return $this->dynamo->add(
|
||||
$this->name, $this->owner, $this->seconds
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function release()
|
||||
{
|
||||
if ($this->isOwnedByCurrentProcess()) {
|
||||
return $this->dynamo->forget($this->name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release this lock in disregard of ownership.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function forceRelease()
|
||||
{
|
||||
$this->dynamo->forget($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner value written into the driver for this lock.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getCurrentOwner()
|
||||
{
|
||||
return $this->dynamo->get($this->name);
|
||||
}
|
||||
}
|
||||
528
vendor/laravel/framework/src/Illuminate/Cache/DynamoDbStore.php
vendored
Normal file
528
vendor/laravel/framework/src/Illuminate/Cache/DynamoDbStore.php
vendored
Normal file
@@ -0,0 +1,528 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Aws\DynamoDb\DynamoDbClient;
|
||||
use Aws\DynamoDb\Exception\DynamoDbException;
|
||||
use Illuminate\Contracts\Cache\LockProvider;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Support\Str;
|
||||
use RuntimeException;
|
||||
|
||||
class DynamoDbStore implements LockProvider, Store
|
||||
{
|
||||
use InteractsWithTime;
|
||||
|
||||
/**
|
||||
* The DynamoDB client instance.
|
||||
*
|
||||
* @var \Aws\DynamoDb\DynamoDbClient
|
||||
*/
|
||||
protected $dynamo;
|
||||
|
||||
/**
|
||||
* The table name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table;
|
||||
|
||||
/**
|
||||
* The name of the attribute that should hold the key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $keyAttribute;
|
||||
|
||||
/**
|
||||
* The name of the attribute that should hold the value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $valueAttribute;
|
||||
|
||||
/**
|
||||
* The name of the attribute that should hold the expiration timestamp.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $expirationAttribute;
|
||||
|
||||
/**
|
||||
* A string that should be prepended to keys.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* Create a new store instance.
|
||||
*
|
||||
* @param \Aws\DynamoDb\DynamoDbClient $dynamo
|
||||
* @param string $table
|
||||
* @param string $keyAttribute
|
||||
* @param string $valueAttribute
|
||||
* @param string $expirationAttribute
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(DynamoDbClient $dynamo,
|
||||
$table,
|
||||
$keyAttribute = 'key',
|
||||
$valueAttribute = 'value',
|
||||
$expirationAttribute = 'expires_at',
|
||||
$prefix = '')
|
||||
{
|
||||
$this->table = $table;
|
||||
$this->dynamo = $dynamo;
|
||||
$this->keyAttribute = $keyAttribute;
|
||||
$this->valueAttribute = $valueAttribute;
|
||||
$this->expirationAttribute = $expirationAttribute;
|
||||
|
||||
$this->setPrefix($prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an item from the cache by key.
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
$response = $this->dynamo->getItem([
|
||||
'TableName' => $this->table,
|
||||
'ConsistentRead' => false,
|
||||
'Key' => [
|
||||
$this->keyAttribute => [
|
||||
'S' => $this->prefix.$key,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
if (! isset($response['Item'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->isExpired($response['Item'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($response['Item'][$this->valueAttribute])) {
|
||||
return $this->unserialize(
|
||||
$response['Item'][$this->valueAttribute]['S'] ??
|
||||
$response['Item'][$this->valueAttribute]['N'] ??
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
$response = $this->dynamo->batchGetItem([
|
||||
'RequestItems' => [
|
||||
$this->table => [
|
||||
'ConsistentRead' => false,
|
||||
'Keys' => collect($prefixedKeys)->map(function ($key) {
|
||||
return [
|
||||
$this->keyAttribute => [
|
||||
'S' => $key,
|
||||
],
|
||||
];
|
||||
})->all(),
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$now = Carbon::now();
|
||||
|
||||
return array_merge(collect(array_flip($keys))->map(function () {
|
||||
//
|
||||
})->all(), collect($response['Responses'][$this->table])->mapWithKeys(function ($response) use ($now) {
|
||||
if ($this->isExpired($response, $now)) {
|
||||
$value = null;
|
||||
} else {
|
||||
$value = $this->unserialize(
|
||||
$response[$this->valueAttribute]['S'] ??
|
||||
$response[$this->valueAttribute]['N'] ??
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
return [Str::replaceFirst($this->prefix, '', $response[$this->keyAttribute]['S']) => $value];
|
||||
})->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given item is expired.
|
||||
*
|
||||
* @param array $item
|
||||
* @param \DateTimeInterface|null $expiration
|
||||
* @return bool
|
||||
*/
|
||||
protected function isExpired(array $item, $expiration = null)
|
||||
{
|
||||
$expiration = $expiration ?: Carbon::now();
|
||||
|
||||
return isset($item[$this->expirationAttribute]) &&
|
||||
$expiration->getTimestamp() >= $item[$this->expirationAttribute]['N'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache for a given number of seconds.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function put($key, $value, $seconds)
|
||||
{
|
||||
$this->dynamo->putItem([
|
||||
'TableName' => $this->table,
|
||||
'Item' => [
|
||||
$this->keyAttribute => [
|
||||
'S' => $this->prefix.$key,
|
||||
],
|
||||
$this->valueAttribute => [
|
||||
$this->type($value) => $this->serialize($value),
|
||||
],
|
||||
$this->expirationAttribute => [
|
||||
'N' => (string) $this->toTimestamp($seconds),
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store multiple items in the cache for a given number of $seconds.
|
||||
*
|
||||
* @param array $values
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function putMany(array $values, $seconds)
|
||||
{
|
||||
$expiration = $this->toTimestamp($seconds);
|
||||
|
||||
$this->dynamo->batchWriteItem([
|
||||
'RequestItems' => [
|
||||
$this->table => collect($values)->map(function ($value, $key) use ($expiration) {
|
||||
return [
|
||||
'PutRequest' => [
|
||||
'Item' => [
|
||||
$this->keyAttribute => [
|
||||
'S' => $this->prefix.$key,
|
||||
],
|
||||
$this->valueAttribute => [
|
||||
$this->type($value) => $this->serialize($value),
|
||||
],
|
||||
$this->expirationAttribute => [
|
||||
'N' => (string) $expiration,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
})->values()->all(),
|
||||
],
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache if the key doesn't exist.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function add($key, $value, $seconds)
|
||||
{
|
||||
try {
|
||||
$this->dynamo->putItem([
|
||||
'TableName' => $this->table,
|
||||
'Item' => [
|
||||
$this->keyAttribute => [
|
||||
'S' => $this->prefix.$key,
|
||||
],
|
||||
$this->valueAttribute => [
|
||||
$this->type($value) => $this->serialize($value),
|
||||
],
|
||||
$this->expirationAttribute => [
|
||||
'N' => (string) $this->toTimestamp($seconds),
|
||||
],
|
||||
],
|
||||
'ConditionExpression' => 'attribute_not_exists(#key) OR #expires_at < :now',
|
||||
'ExpressionAttributeNames' => [
|
||||
'#key' => $this->keyAttribute,
|
||||
'#expires_at' => $this->expirationAttribute,
|
||||
],
|
||||
'ExpressionAttributeValues' => [
|
||||
':now' => [
|
||||
'N' => (string) Carbon::now()->getTimestamp(),
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
return true;
|
||||
} catch (DynamoDbException $e) {
|
||||
if (Str::contains($e->getMessage(), 'ConditionalCheckFailed')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
{
|
||||
try {
|
||||
$response = $this->dynamo->updateItem([
|
||||
'TableName' => $this->table,
|
||||
'Key' => [
|
||||
$this->keyAttribute => [
|
||||
'S' => $this->prefix.$key,
|
||||
],
|
||||
],
|
||||
'ConditionExpression' => 'attribute_exists(#key) AND #expires_at > :now',
|
||||
'UpdateExpression' => 'SET #value = #value + :amount',
|
||||
'ExpressionAttributeNames' => [
|
||||
'#key' => $this->keyAttribute,
|
||||
'#value' => $this->valueAttribute,
|
||||
'#expires_at' => $this->expirationAttribute,
|
||||
],
|
||||
'ExpressionAttributeValues' => [
|
||||
':now' => [
|
||||
'N' => (string) Carbon::now()->getTimestamp(),
|
||||
],
|
||||
':amount' => [
|
||||
'N' => (string) $value,
|
||||
],
|
||||
],
|
||||
'ReturnValues' => 'UPDATED_NEW',
|
||||
]);
|
||||
|
||||
return (int) $response['Attributes'][$this->valueAttribute]['N'];
|
||||
} catch (DynamoDbException $e) {
|
||||
if (Str::contains($e->getMessage(), 'ConditionalCheckFailed')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
{
|
||||
try {
|
||||
$response = $this->dynamo->updateItem([
|
||||
'TableName' => $this->table,
|
||||
'Key' => [
|
||||
$this->keyAttribute => [
|
||||
'S' => $this->prefix.$key,
|
||||
],
|
||||
],
|
||||
'ConditionExpression' => 'attribute_exists(#key) AND #expires_at > :now',
|
||||
'UpdateExpression' => 'SET #value = #value - :amount',
|
||||
'ExpressionAttributeNames' => [
|
||||
'#key' => $this->keyAttribute,
|
||||
'#value' => $this->valueAttribute,
|
||||
'#expires_at' => $this->expirationAttribute,
|
||||
],
|
||||
'ExpressionAttributeValues' => [
|
||||
':now' => [
|
||||
'N' => (string) Carbon::now()->getTimestamp(),
|
||||
],
|
||||
':amount' => [
|
||||
'N' => (string) $value,
|
||||
],
|
||||
],
|
||||
'ReturnValues' => 'UPDATED_NEW',
|
||||
]);
|
||||
|
||||
return (int) $response['Attributes'][$this->valueAttribute]['N'];
|
||||
} catch (DynamoDbException $e) {
|
||||
if (Str::contains($e->getMessage(), 'ConditionalCheckFailed')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
return $this->put($key, $value, Carbon::now()->addYears(5)->getTimestamp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a lock instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function lock($name, $seconds = 0, $owner = null)
|
||||
{
|
||||
return new DynamoDbLock($this, $this->prefix.$name, $seconds, $owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a lock instance using the owner identifier.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function restoreLock($name, $owner)
|
||||
{
|
||||
return $this->lock($name, 0, $owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function forget($key)
|
||||
{
|
||||
$this->dynamo->deleteItem([
|
||||
'TableName' => $this->table,
|
||||
'Key' => [
|
||||
$this->keyAttribute => [
|
||||
'S' => $this->prefix.$key,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all items from the cache.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
throw new RuntimeException('DynamoDb does not support flushing an entire table. Please create a new table.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UNIX timestamp for the given number of seconds.
|
||||
*
|
||||
* @param int $seconds
|
||||
* @return int
|
||||
*/
|
||||
protected function toTimestamp($seconds)
|
||||
{
|
||||
return $seconds > 0
|
||||
? $this->availableAt($seconds)
|
||||
: Carbon::now()->getTimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function serialize($value)
|
||||
{
|
||||
return is_numeric($value) ? (string) $value : serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserialize the value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function unserialize($value)
|
||||
{
|
||||
if (filter_var($value, FILTER_VALIDATE_INT) !== false) {
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
if (is_numeric($value)) {
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
return unserialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DynamoDB type for the given value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
protected function type($value)
|
||||
{
|
||||
return is_numeric($value) ? 'N' : 'S';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.':' : '';
|
||||
}
|
||||
}
|
||||
@@ -12,26 +12,26 @@ class KeyWritten extends CacheEvent
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* The number of minutes the key should be valid.
|
||||
* The number of seconds the key should be valid.
|
||||
*
|
||||
* @var int
|
||||
* @var int|null
|
||||
*/
|
||||
public $minutes;
|
||||
public $seconds;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @param int|null $seconds
|
||||
* @param array $tags
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($key, $value, $minutes, $tags = [])
|
||||
public function __construct($key, $value, $seconds = null, $tags = [])
|
||||
{
|
||||
parent::__construct($key, $tags);
|
||||
|
||||
$this->value = $value;
|
||||
$this->minutes = $minutes;
|
||||
$this->seconds = $seconds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,17 +25,26 @@ class FileStore implements Store
|
||||
*/
|
||||
protected $directory;
|
||||
|
||||
/**
|
||||
* Octal representation of the cache file permissions.
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
protected $filePermission;
|
||||
|
||||
/**
|
||||
* Create a new file cache store instance.
|
||||
*
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @param string $directory
|
||||
* @param int|null $filePermission
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Filesystem $files, $directory)
|
||||
public function __construct(Filesystem $files, $directory, $filePermission = null)
|
||||
{
|
||||
$this->files = $files;
|
||||
$this->directory = $directory;
|
||||
$this->filePermission = $filePermission;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,20 +59,28 @@ class FileStore implements Store
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache for a given number of minutes.
|
||||
* Store an item in the cache for a given number of seconds.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
public function put($key, $value, $seconds)
|
||||
{
|
||||
$this->ensureCacheDirectoryExists($path = $this->path($key));
|
||||
|
||||
$this->files->put(
|
||||
$path, $this->expiration($minutes).serialize($value), true
|
||||
$result = $this->files->put(
|
||||
$path, $this->expiration($seconds).serialize($value), true
|
||||
);
|
||||
|
||||
if ($result !== false && $result > 0) {
|
||||
$this->ensureFileHasCorrectPermissions($path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,11 +96,27 @@ class FileStore implements Store
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the cache file has the correct permissions.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
protected function ensureFileHasCorrectPermissions($path)
|
||||
{
|
||||
if (is_null($this->filePermission) ||
|
||||
intval($this->files->chmod($path), 8) == $this->filePermission) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->files->chmod($path, $this->filePermission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
@@ -99,7 +132,7 @@ class FileStore implements Store
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
@@ -111,12 +144,12 @@ class FileStore implements Store
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
$this->put($key, $value, 0);
|
||||
return $this->put($key, $value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,7 +179,9 @@ class FileStore implements Store
|
||||
}
|
||||
|
||||
foreach ($this->files->directories($this->directory) as $directory) {
|
||||
if (! $this->files->deleteDirectory($directory)) {
|
||||
$deleted = $this->files->deleteDirectory($directory);
|
||||
|
||||
if (! $deleted || $this->files->exists($directory)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -184,12 +219,18 @@ class FileStore implements Store
|
||||
return $this->emptyPayload();
|
||||
}
|
||||
|
||||
$data = unserialize(substr($contents, 10));
|
||||
try {
|
||||
$data = unserialize(substr($contents, 10));
|
||||
} catch (Exception $e) {
|
||||
$this->forget($key);
|
||||
|
||||
// Next, we'll extract the number of minutes that are remaining for a cache
|
||||
return $this->emptyPayload();
|
||||
}
|
||||
|
||||
// Next, we'll extract the number of seconds 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 this cache on a later operation.
|
||||
$time = ($expire - $this->currentTime()) / 60;
|
||||
$time = $expire - $this->currentTime();
|
||||
|
||||
return compact('data', 'time');
|
||||
}
|
||||
@@ -218,16 +259,16 @@ class FileStore implements Store
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the expiration time based on the given minutes.
|
||||
* Get the expiration time based on the given seconds.
|
||||
*
|
||||
* @param float|int $minutes
|
||||
* @param int $seconds
|
||||
* @return int
|
||||
*/
|
||||
protected function expiration($minutes)
|
||||
protected function expiration($seconds)
|
||||
{
|
||||
$time = $this->availableAt((int) ($minutes * 60));
|
||||
$time = $this->availableAt($seconds);
|
||||
|
||||
return $minutes === 0 || $time > 9999999999 ? 9999999999 : (int) $time;
|
||||
return $seconds === 0 || $time > 9999999999 ? 9999999999 : $time;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Contracts\Cache\Lock as LockContract;
|
||||
use Illuminate\Contracts\Cache\LockTimeoutException;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
abstract class Lock implements LockContract
|
||||
{
|
||||
@@ -24,16 +25,36 @@ abstract class Lock implements LockContract
|
||||
*/
|
||||
protected $seconds;
|
||||
|
||||
/**
|
||||
* The scope identifier of this lock.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $owner;
|
||||
|
||||
/**
|
||||
* The number of milliseconds to wait before re-attempting to acquire a lock while blocking.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $sleepMilliseconds = 250;
|
||||
|
||||
/**
|
||||
* Create a new lock instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($name, $seconds)
|
||||
public function __construct($name, $seconds, $owner = null)
|
||||
{
|
||||
if (is_null($owner)) {
|
||||
$owner = Str::random();
|
||||
}
|
||||
|
||||
$this->name = $name;
|
||||
$this->owner = $owner;
|
||||
$this->seconds = $seconds;
|
||||
}
|
||||
|
||||
@@ -47,24 +68,33 @@ abstract class Lock implements LockContract
|
||||
/**
|
||||
* Release the lock.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function release();
|
||||
|
||||
/**
|
||||
* Returns the owner value written into the driver for this lock.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getCurrentOwner();
|
||||
|
||||
/**
|
||||
* Attempt to acquire the lock.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @return bool
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($callback = null)
|
||||
{
|
||||
$result = $this->acquire();
|
||||
|
||||
if ($result && is_callable($callback)) {
|
||||
return tap($callback(), function () {
|
||||
try {
|
||||
return $callback();
|
||||
} finally {
|
||||
$this->release();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
@@ -84,7 +114,7 @@ abstract class Lock implements LockContract
|
||||
$starting = $this->currentTime();
|
||||
|
||||
while (! $this->acquire()) {
|
||||
usleep(250 * 1000);
|
||||
usleep($this->sleepMilliseconds * 1000);
|
||||
|
||||
if ($this->currentTime() - $seconds >= $starting) {
|
||||
throw new LockTimeoutException;
|
||||
@@ -92,11 +122,46 @@ abstract class Lock implements LockContract
|
||||
}
|
||||
|
||||
if (is_callable($callback)) {
|
||||
return tap($callback(), function () {
|
||||
try {
|
||||
return $callback();
|
||||
} finally {
|
||||
$this->release();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current owner of the lock.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function owner()
|
||||
{
|
||||
return $this->owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this lock is allowed to release the lock in the driver.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isOwnedByCurrentProcess()
|
||||
{
|
||||
return $this->getCurrentOwner() === $this->owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the number of milliseconds to sleep in between blocked lock aquisition attempts.
|
||||
*
|
||||
* @param int $milliseconds
|
||||
* @return $this
|
||||
*/
|
||||
public function betweenBlockedAttemptsSleepFor($milliseconds)
|
||||
{
|
||||
$this->sleepMilliseconds = $milliseconds;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
25
vendor/laravel/framework/src/Illuminate/Cache/LuaScripts.php
vendored
Normal file
25
vendor/laravel/framework/src/Illuminate/Cache/LuaScripts.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
class LuaScripts
|
||||
{
|
||||
/**
|
||||
* Get the Lua script to atomically release a lock.
|
||||
*
|
||||
* KEYS[1] - The name of the lock
|
||||
* ARGV[1] - The owner key of the lock instance trying to release it
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function releaseLock()
|
||||
{
|
||||
return <<<'LUA'
|
||||
if redis.call("get",KEYS[1]) == ARGV[1] then
|
||||
return redis.call("del",KEYS[1])
|
||||
else
|
||||
return 0
|
||||
end
|
||||
LUA;
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,12 @@ class MemcachedLock extends Lock
|
||||
* @param \Memcached $memcached
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($memcached, $name, $seconds)
|
||||
public function __construct($memcached, $name, $seconds, $owner = null)
|
||||
{
|
||||
parent::__construct($name, $seconds);
|
||||
parent::__construct($name, $seconds, $owner);
|
||||
|
||||
$this->memcached = $memcached;
|
||||
}
|
||||
@@ -34,17 +35,41 @@ class MemcachedLock extends Lock
|
||||
public function acquire()
|
||||
{
|
||||
return $this->memcached->add(
|
||||
$this->name, 1, $this->seconds
|
||||
$this->name, $this->owner, $this->seconds
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the lock.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function release()
|
||||
{
|
||||
if ($this->isOwnedByCurrentProcess()) {
|
||||
return $this->memcached->delete($this->name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases this lock in disregard of ownership.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function forceRelease()
|
||||
{
|
||||
$this->memcached->delete($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner value written into the driver for this lock.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getCurrentOwner()
|
||||
{
|
||||
return $this->memcached->get($this->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,23 +2,15 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Contracts\Cache\LockProvider;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Memcached;
|
||||
use ReflectionMethod;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Contracts\Cache\LockProvider;
|
||||
|
||||
class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
class MemcachedStore extends TaggableStore implements LockProvider
|
||||
{
|
||||
use InteractsWithTime;
|
||||
|
||||
/**
|
||||
* The maximum value that can be specified as an expiration delta.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const REALTIME_MAXDELTA_IN_MINUTES = 43200;
|
||||
|
||||
/**
|
||||
* The Memcached instance.
|
||||
*
|
||||
@@ -44,7 +36,7 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
* Create a new Memcached store.
|
||||
*
|
||||
* @param \Memcached $memcached
|
||||
* @param string $prefix
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($memcached, $prefix = '')
|
||||
@@ -101,28 +93,28 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache for a given number of minutes.
|
||||
* Store an item in the cache for a given number of seconds.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
public function put($key, $value, $seconds)
|
||||
{
|
||||
$this->memcached->set(
|
||||
$this->prefix.$key, $value, $this->calculateExpiration($minutes)
|
||||
return $this->memcached->set(
|
||||
$this->prefix.$key, $value, $this->calculateExpiration($seconds)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store multiple items in the cache for a given number of minutes.
|
||||
* Store multiple items in the cache for a given number of seconds.
|
||||
*
|
||||
* @param array $values
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function putMany(array $values, $minutes)
|
||||
public function putMany(array $values, $seconds)
|
||||
{
|
||||
$prefixedValues = [];
|
||||
|
||||
@@ -130,8 +122,8 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
$prefixedValues[$this->prefix.$key] = $value;
|
||||
}
|
||||
|
||||
$this->memcached->setMulti(
|
||||
$prefixedValues, $this->calculateExpiration($minutes)
|
||||
return $this->memcached->setMulti(
|
||||
$prefixedValues, $this->calculateExpiration($seconds)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -139,14 +131,14 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
* Store an item in the cache if the key doesn't exist.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param float|int $minutes
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function add($key, $value, $minutes)
|
||||
public function add($key, $value, $seconds)
|
||||
{
|
||||
return $this->memcached->add(
|
||||
$this->prefix.$key, $value, $this->calculateExpiration($minutes)
|
||||
$this->prefix.$key, $value, $this->calculateExpiration($seconds)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -154,7 +146,7 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
@@ -166,7 +158,7 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
@@ -178,12 +170,12 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
$this->put($key, $value, 0);
|
||||
return $this->put($key, $value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,11 +183,24 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function lock($name, $seconds = 0)
|
||||
public function lock($name, $seconds = 0, $owner = null)
|
||||
{
|
||||
return new MemcachedLock($this->memcached, $this->prefix.$name, $seconds);
|
||||
return new MemcachedLock($this->memcached, $this->prefix.$name, $seconds, $owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a lock instance using the owner identifier.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function restoreLock($name, $owner)
|
||||
{
|
||||
return $this->lock($name, 0, $owner);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,23 +227,23 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
/**
|
||||
* Get the expiration time of the key.
|
||||
*
|
||||
* @param int $minutes
|
||||
* @param int $seconds
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateExpiration($minutes)
|
||||
protected function calculateExpiration($seconds)
|
||||
{
|
||||
return $this->toTimestamp($minutes);
|
||||
return $this->toTimestamp($seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UNIX timestamp for the given number of minutes.
|
||||
* Get the UNIX timestamp for the given number of seconds.
|
||||
*
|
||||
* @param int $minutes
|
||||
* @param int $seconds
|
||||
* @return int
|
||||
*/
|
||||
protected function toTimestamp($minutes)
|
||||
protected function toTimestamp($seconds)
|
||||
{
|
||||
return $minutes > 0 ? $this->availableAt($minutes * 60) : 0;
|
||||
return $seconds > 0 ? $this->availableAt($seconds) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,19 +2,10 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
|
||||
class NullStore extends TaggableStore implements Store
|
||||
class NullStore extends TaggableStore
|
||||
{
|
||||
use RetrievesMultipleKeys;
|
||||
|
||||
/**
|
||||
* The array of stored values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $storage = [];
|
||||
|
||||
/**
|
||||
* Retrieve an item from the cache by key.
|
||||
*
|
||||
@@ -27,63 +18,63 @@ class NullStore extends TaggableStore implements Store
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache for a given number of minutes.
|
||||
* Store an item in the cache for a given number of seconds.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
public function put($key, $value, $seconds)
|
||||
{
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
{
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
{
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function forget($key)
|
||||
{
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
|
||||
class RateLimiter
|
||||
{
|
||||
@@ -51,21 +51,21 @@ class RateLimiter
|
||||
* Increment the counter for a given key for a given decay time.
|
||||
*
|
||||
* @param string $key
|
||||
* @param float|int $decayMinutes
|
||||
* @param int $decaySeconds
|
||||
* @return int
|
||||
*/
|
||||
public function hit($key, $decayMinutes = 1)
|
||||
public function hit($key, $decaySeconds = 60)
|
||||
{
|
||||
$this->cache->add(
|
||||
$key.':timer', $this->availableAt($decayMinutes * 60), $decayMinutes
|
||||
$key.':timer', $this->availableAt($decaySeconds), $decaySeconds
|
||||
);
|
||||
|
||||
$added = $this->cache->add($key, 0, $decayMinutes);
|
||||
$added = $this->cache->add($key, 0, $decaySeconds);
|
||||
|
||||
$hits = (int) $this->cache->increment($key);
|
||||
|
||||
if (! $added && $hits == 1) {
|
||||
$this->cache->put($key, 1, $decayMinutes);
|
||||
$this->cache->put($key, 1, $decaySeconds);
|
||||
}
|
||||
|
||||
return $hits;
|
||||
|
||||
@@ -17,11 +17,12 @@ class RedisLock extends Lock
|
||||
* @param \Illuminate\Redis\Connections\Connection $redis
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($redis, $name, $seconds)
|
||||
public function __construct($redis, $name, $seconds, $owner = null)
|
||||
{
|
||||
parent::__construct($name, $seconds);
|
||||
parent::__construct($name, $seconds, $owner);
|
||||
|
||||
$this->redis = $redis;
|
||||
}
|
||||
@@ -33,22 +34,40 @@ class RedisLock extends Lock
|
||||
*/
|
||||
public function acquire()
|
||||
{
|
||||
$result = $this->redis->setnx($this->name, 1);
|
||||
|
||||
if ($result === 1 && $this->seconds > 0) {
|
||||
$this->redis->expire($this->name, $this->seconds);
|
||||
if ($this->seconds > 0) {
|
||||
return $this->redis->set($this->name, $this->owner, 'EX', $this->seconds, 'NX') == true;
|
||||
} else {
|
||||
return $this->redis->setnx($this->name, $this->owner) === 1;
|
||||
}
|
||||
|
||||
return $result === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the lock.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function release()
|
||||
{
|
||||
return (bool) $this->redis->eval(LuaScripts::releaseLock(), 1, $this->name, $this->owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases this lock in disregard of ownership.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function forceRelease()
|
||||
{
|
||||
$this->redis->del($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner value written into the driver for this lock.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getCurrentOwner()
|
||||
{
|
||||
return $this->redis->get($this->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Contracts\Cache\LockProvider;
|
||||
use Illuminate\Contracts\Redis\Factory as Redis;
|
||||
|
||||
class RedisStore extends TaggableStore implements Store
|
||||
class RedisStore extends TaggableStore implements LockProvider
|
||||
{
|
||||
/**
|
||||
* The Redis factory implementation.
|
||||
@@ -80,52 +80,58 @@ class RedisStore extends TaggableStore implements Store
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache for a given number of minutes.
|
||||
* Store an item in the cache for a given number of seconds.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
public function put($key, $value, $seconds)
|
||||
{
|
||||
$this->connection()->setex(
|
||||
$this->prefix.$key, (int) max(1, $minutes * 60), $this->serialize($value)
|
||||
return (bool) $this->connection()->setex(
|
||||
$this->prefix.$key, (int) max(1, $seconds), $this->serialize($value)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store multiple items in the cache for a given number of minutes.
|
||||
* Store multiple items in the cache for a given number of seconds.
|
||||
*
|
||||
* @param array $values
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function putMany(array $values, $minutes)
|
||||
public function putMany(array $values, $seconds)
|
||||
{
|
||||
$this->connection()->multi();
|
||||
|
||||
$manyResult = null;
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$this->put($key, $value, $minutes);
|
||||
$result = $this->put($key, $value, $seconds);
|
||||
|
||||
$manyResult = is_null($manyResult) ? $result : $result && $manyResult;
|
||||
}
|
||||
|
||||
$this->connection()->exec();
|
||||
|
||||
return $manyResult ?: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache if the key doesn't exist.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param float|int $minutes
|
||||
* @param mixed $value
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function add($key, $value, $minutes)
|
||||
public function add($key, $value, $seconds)
|
||||
{
|
||||
$lua = "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])";
|
||||
|
||||
return (bool) $this->connection()->eval(
|
||||
$lua, 1, $this->prefix.$key, $this->serialize($value), (int) max(1, $minutes * 60)
|
||||
$lua, 1, $this->prefix.$key, $this->serialize($value), (int) max(1, $seconds)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -133,7 +139,7 @@ class RedisStore extends TaggableStore implements Store
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
@@ -145,7 +151,7 @@ class RedisStore extends TaggableStore implements Store
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
@@ -157,12 +163,12 @@ class RedisStore extends TaggableStore implements Store
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
$this->connection()->set($this->prefix.$key, $this->serialize($value));
|
||||
return (bool) $this->connection()->set($this->prefix.$key, $this->serialize($value));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,11 +176,24 @@ class RedisStore extends TaggableStore implements Store
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function lock($name, $seconds = 0)
|
||||
public function lock($name, $seconds = 0, $owner = null)
|
||||
{
|
||||
return new RedisLock($this->connection(), $this->prefix.$name, $seconds);
|
||||
return new RedisLock($this->connection(), $this->prefix.$name, $seconds, $owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a lock instance using the owner identifier.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function restoreLock($name, $owner)
|
||||
{
|
||||
return $this->lock($name, 0, $owner);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,7 +235,7 @@ class RedisStore extends TaggableStore implements Store
|
||||
/**
|
||||
* Get the Redis connection instance.
|
||||
*
|
||||
* @return \Predis\ClientInterface
|
||||
* @return \Illuminate\Redis\Connections\Connection
|
||||
*/
|
||||
public function connection()
|
||||
{
|
||||
@@ -273,7 +292,7 @@ class RedisStore extends TaggableStore implements Store
|
||||
*/
|
||||
protected function serialize($value)
|
||||
{
|
||||
return is_numeric($value) ? $value : serialize($value);
|
||||
return is_numeric($value) && ! in_array($value, [INF, -INF]) && ! is_nan($value) ? $value : serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,22 +21,26 @@ class RedisTaggedCache extends TaggedCache
|
||||
* Store an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTime|float|int|null $minutes
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @param \DateTimeInterface|\DateInterval|int|null $ttl
|
||||
* @return bool
|
||||
*/
|
||||
public function put($key, $value, $minutes = null)
|
||||
public function put($key, $value, $ttl = null)
|
||||
{
|
||||
if ($ttl === null) {
|
||||
return $this->forever($key, $value);
|
||||
}
|
||||
|
||||
$this->pushStandardKeys($this->tags->getNamespace(), $key);
|
||||
|
||||
parent::put($key, $value, $minutes);
|
||||
return parent::put($key, $value, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
@@ -50,7 +54,7 @@ class RedisTaggedCache extends TaggedCache
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
@@ -64,14 +68,14 @@ class RedisTaggedCache extends TaggedCache
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
$this->pushForeverKeys($this->tags->getNamespace(), $key);
|
||||
|
||||
parent::forever($key, $value);
|
||||
return parent::forever($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,7 +179,7 @@ class RedisTaggedCache extends TaggedCache
|
||||
|
||||
if (count($values) > 0) {
|
||||
foreach (array_chunk($values, 1000) as $valuesChunk) {
|
||||
call_user_func_array([$this->store->connection(), 'del'], $valuesChunk);
|
||||
$this->store->connection()->del(...$valuesChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Closure;
|
||||
use ArrayAccess;
|
||||
use DateTimeInterface;
|
||||
use BadMethodCallException;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Closure;
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Cache\Events\CacheHit;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Cache\Events\KeyWritten;
|
||||
use Illuminate\Cache\Events\CacheMissed;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Cache\Events\KeyForgotten;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Cache\Events\KeyWritten;
|
||||
use Illuminate\Contracts\Cache\Repository as CacheContract;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
|
||||
/**
|
||||
* @mixin \Illuminate\Contracts\Cache\Store
|
||||
*/
|
||||
class Repository implements CacheContract, ArrayAccess
|
||||
class Repository implements ArrayAccess, CacheContract
|
||||
{
|
||||
use InteractsWithTime;
|
||||
use Macroable {
|
||||
@@ -42,11 +42,11 @@ class Repository implements CacheContract, ArrayAccess
|
||||
protected $events;
|
||||
|
||||
/**
|
||||
* The default number of minutes to store items.
|
||||
* The default number of seconds to store items.
|
||||
*
|
||||
* @var float|int
|
||||
* @var int|null
|
||||
*/
|
||||
protected $default = 60;
|
||||
protected $default = 3600;
|
||||
|
||||
/**
|
||||
* Create a new cache repository instance.
|
||||
@@ -85,7 +85,7 @@ class Repository implements CacheContract, ArrayAccess
|
||||
* Retrieve an item from the cache by key.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
@@ -134,17 +134,13 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
if (is_null($default)) {
|
||||
return $this->many($keys);
|
||||
}
|
||||
$defaults = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (! isset($default[$key])) {
|
||||
$default[$key] = null;
|
||||
}
|
||||
$defaults[$key] = $default;
|
||||
}
|
||||
|
||||
return $this->many($default);
|
||||
return $this->many($defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +174,7 @@ class Repository implements CacheContract, ArrayAccess
|
||||
* Retrieve an item from the cache and delete it.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function pull($key, $default = null)
|
||||
@@ -192,23 +188,33 @@ class Repository implements CacheContract, ArrayAccess
|
||||
* Store an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTimeInterface|\DateInterval|float|int|null $minutes
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @param \DateTimeInterface|\DateInterval|int|null $ttl
|
||||
* @return bool
|
||||
*/
|
||||
public function put($key, $value, $minutes = null)
|
||||
public function put($key, $value, $ttl = null)
|
||||
{
|
||||
if (is_array($key)) {
|
||||
$this->putMany($key, $value);
|
||||
|
||||
return;
|
||||
return $this->putMany($key, $value);
|
||||
}
|
||||
|
||||
if (! is_null($minutes = $this->getMinutes($minutes))) {
|
||||
$this->store->put($this->itemKey($key), $value, $minutes);
|
||||
|
||||
$this->event(new KeyWritten($key, $value, $minutes));
|
||||
if ($ttl === null) {
|
||||
return $this->forever($key, $value);
|
||||
}
|
||||
|
||||
$seconds = $this->getSeconds($ttl);
|
||||
|
||||
if ($seconds <= 0) {
|
||||
return $this->forget($key);
|
||||
}
|
||||
|
||||
$result = $this->store->put($this->itemKey($key), $value, $seconds);
|
||||
|
||||
if ($result) {
|
||||
$this->event(new KeyWritten($key, $value, $seconds));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,25 +222,56 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$this->put($key, $value, $ttl);
|
||||
return $this->put($key, $value, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store multiple items in the cache for a given number of minutes.
|
||||
* Store multiple items in the cache for a given number of seconds.
|
||||
*
|
||||
* @param array $values
|
||||
* @param \DateTimeInterface|\DateInterval|float|int $minutes
|
||||
* @return void
|
||||
* @param \DateTimeInterface|\DateInterval|int|null $ttl
|
||||
* @return bool
|
||||
*/
|
||||
public function putMany(array $values, $minutes)
|
||||
public function putMany(array $values, $ttl = null)
|
||||
{
|
||||
if (! is_null($minutes = $this->getMinutes($minutes))) {
|
||||
$this->store->putMany($values, $minutes);
|
||||
if ($ttl === null) {
|
||||
return $this->putManyForever($values);
|
||||
}
|
||||
|
||||
$seconds = $this->getSeconds($ttl);
|
||||
|
||||
if ($seconds <= 0) {
|
||||
return $this->deleteMultiple(array_keys($values));
|
||||
}
|
||||
|
||||
$result = $this->store->putMany($values, $seconds);
|
||||
|
||||
if ($result) {
|
||||
foreach ($values as $key => $value) {
|
||||
$this->event(new KeyWritten($key, $value, $minutes));
|
||||
$this->event(new KeyWritten($key, $value, $seconds));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store multiple items in the cache indefinitely.
|
||||
*
|
||||
* @param array $values
|
||||
* @return bool
|
||||
*/
|
||||
protected function putManyForever(array $values)
|
||||
{
|
||||
$result = true;
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
if (! $this->forever($key, $value)) {
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,39 +279,41 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$this->putMany($values, $ttl);
|
||||
return $this->putMany(is_array($values) ? $values : iterator_to_array($values), $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache if the key does not exist.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTimeInterface|\DateInterval|float|int $minutes
|
||||
* @param mixed $value
|
||||
* @param \DateTimeInterface|\DateInterval|int|null $ttl
|
||||
* @return bool
|
||||
*/
|
||||
public function add($key, $value, $minutes)
|
||||
public function add($key, $value, $ttl = null)
|
||||
{
|
||||
if (is_null($minutes = $this->getMinutes($minutes))) {
|
||||
return false;
|
||||
}
|
||||
if ($ttl !== null) {
|
||||
if ($this->getSeconds($ttl) <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the store has an "add" method we will call the method on the store so it
|
||||
// has a chance to override this logic. Some drivers better support the way
|
||||
// this operation should work with a total "atomic" implementation of it.
|
||||
if (method_exists($this->store, 'add')) {
|
||||
return $this->store->add(
|
||||
$this->itemKey($key), $value, $minutes
|
||||
);
|
||||
// If the store has an "add" method we will call the method on the store so it
|
||||
// has a chance to override this logic. Some drivers better support the way
|
||||
// this operation should work with a total "atomic" implementation of it.
|
||||
if (method_exists($this->store, 'add')) {
|
||||
$seconds = $this->getSeconds($ttl);
|
||||
|
||||
return $this->store->add(
|
||||
$this->itemKey($key), $value, $seconds
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// If the value did not exist in the cache, we will put the value in the cache
|
||||
// so it exists for subsequent requests. Then, we will return true so it is
|
||||
// easy to know if the value gets added. Otherwise, we will return false.
|
||||
if (is_null($this->get($key))) {
|
||||
$this->put($key, $value, $minutes);
|
||||
|
||||
return true;
|
||||
return $this->put($key, $value, $ttl);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -308,36 +347,40 @@ class Repository implements CacheContract, ArrayAccess
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
$this->store->forever($this->itemKey($key), $value);
|
||||
$result = $this->store->forever($this->itemKey($key), $value);
|
||||
|
||||
$this->event(new KeyWritten($key, $value, 0));
|
||||
if ($result) {
|
||||
$this->event(new KeyWritten($key, $value));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from the cache, or execute the given Closure and store the result.
|
||||
*
|
||||
* @param string $key
|
||||
* @param \DateTimeInterface|\DateInterval|float|int $minutes
|
||||
* @param \DateTimeInterface|\DateInterval|int|null $ttl
|
||||
* @param \Closure $callback
|
||||
* @return mixed
|
||||
*/
|
||||
public function remember($key, $minutes, Closure $callback)
|
||||
public function remember($key, $ttl, Closure $callback)
|
||||
{
|
||||
$value = $this->get($key);
|
||||
|
||||
// If the item exists in the cache we will just return this immediately and if
|
||||
// not we will execute the given Closure and cache the result of that for a
|
||||
// given number of minutes so it's available for all subsequent requests.
|
||||
// given number of seconds so it's available for all subsequent requests.
|
||||
if (! is_null($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$this->put($key, $value = $callback(), $minutes);
|
||||
$this->put($key, $value = $callback(), $ttl);
|
||||
|
||||
return $value;
|
||||
}
|
||||
@@ -365,9 +408,9 @@ class Repository implements CacheContract, ArrayAccess
|
||||
{
|
||||
$value = $this->get($key);
|
||||
|
||||
// If the item exists in the cache we will just return this immediately and if
|
||||
// not we will execute the given Closure and cache the result of that for a
|
||||
// given number of minutes so it's available for all subsequent requests.
|
||||
// If the item exists in the cache we will just return this immediately
|
||||
// and if not we will execute the given Closure and cache the result
|
||||
// of that forever so it is available for all subsequent requests.
|
||||
if (! is_null($value)) {
|
||||
return $value;
|
||||
}
|
||||
@@ -385,8 +428,10 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*/
|
||||
public function forget($key)
|
||||
{
|
||||
return tap($this->store->forget($this->itemKey($key)), function () use ($key) {
|
||||
$this->event(new KeyForgotten($key));
|
||||
return tap($this->store->forget($this->itemKey($key)), function ($result) use ($key) {
|
||||
if ($result) {
|
||||
$this->event(new KeyForgotten($key));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -403,11 +448,15 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
$result = true;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$this->forget($key);
|
||||
if (! $this->forget($key)) {
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -455,7 +504,7 @@ class Repository implements CacheContract, ArrayAccess
|
||||
/**
|
||||
* Get the default cache time.
|
||||
*
|
||||
* @return float|int
|
||||
* @return int|null
|
||||
*/
|
||||
public function getDefaultCacheTime()
|
||||
{
|
||||
@@ -463,14 +512,14 @@ class Repository implements CacheContract, ArrayAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default cache time in minutes.
|
||||
* Set the default cache time in seconds.
|
||||
*
|
||||
* @param float|int $minutes
|
||||
* @param int|null $seconds
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultCacheTime($minutes)
|
||||
public function setDefaultCacheTime($seconds)
|
||||
{
|
||||
$this->default = $minutes;
|
||||
$this->default = $seconds;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -498,6 +547,16 @@ class Repository implements CacheContract, ArrayAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the event dispatcher instance.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Events\Dispatcher
|
||||
*/
|
||||
public function getEventDispatcher()
|
||||
{
|
||||
return $this->events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the event dispatcher instance.
|
||||
*
|
||||
@@ -535,7 +594,7 @@ class Repository implements CacheContract, ArrayAccess
|
||||
* Store an item in the cache for the default time.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($key, $value)
|
||||
@@ -555,27 +614,27 @@ class Repository implements CacheContract, ArrayAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the number of minutes with the given duration.
|
||||
* Calculate the number of seconds for the given TTL.
|
||||
*
|
||||
* @param \DateTimeInterface|\DateInterval|float|int $duration
|
||||
* @return float|int|null
|
||||
* @param \DateTimeInterface|\DateInterval|int $ttl
|
||||
* @return int
|
||||
*/
|
||||
protected function getMinutes($duration)
|
||||
protected function getSeconds($ttl)
|
||||
{
|
||||
$duration = $this->parseDateInterval($duration);
|
||||
$duration = $this->parseDateInterval($ttl);
|
||||
|
||||
if ($duration instanceof DateTimeInterface) {
|
||||
$duration = Carbon::now()->diffInRealSeconds($duration, false) / 60;
|
||||
$duration = Carbon::now()->diffInRealSeconds($duration, false);
|
||||
}
|
||||
|
||||
return (int) ($duration * 60) > 0 ? $duration : null;
|
||||
return (int) $duration > 0 ? $duration : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle dynamic calls into macros or pass missing methods to the store.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
|
||||
@@ -24,16 +24,22 @@ trait RetrievesMultipleKeys
|
||||
}
|
||||
|
||||
/**
|
||||
* Store multiple items in the cache for a given number of minutes.
|
||||
* Store multiple items in the cache for a given number of seconds.
|
||||
*
|
||||
* @param array $values
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
* @param int $seconds
|
||||
* @return bool
|
||||
*/
|
||||
public function putMany(array $values, $minutes)
|
||||
public function putMany(array $values, $seconds)
|
||||
{
|
||||
$manyResult = null;
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$this->put($key, $value, $minutes);
|
||||
$result = $this->put($key, $value, $seconds);
|
||||
|
||||
$manyResult = is_null($manyResult) ? $result : $result && $manyResult;
|
||||
}
|
||||
|
||||
return $manyResult ?: false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
abstract class TaggableStore
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
|
||||
abstract class TaggableStore implements Store
|
||||
{
|
||||
/**
|
||||
* Begin executing a new tags operation.
|
||||
|
||||
@@ -6,7 +6,9 @@ use Illuminate\Contracts\Cache\Store;
|
||||
|
||||
class TaggedCache extends Repository
|
||||
{
|
||||
use RetrievesMultipleKeys;
|
||||
use RetrievesMultipleKeys {
|
||||
putMany as putManyAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* The tag set instance.
|
||||
@@ -29,11 +31,27 @@ class TaggedCache extends Repository
|
||||
$this->tags = $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store multiple items in the cache for a given number of seconds.
|
||||
*
|
||||
* @param array $values
|
||||
* @param int|null $ttl
|
||||
* @return bool
|
||||
*/
|
||||
public function putMany(array $values, $ttl = null)
|
||||
{
|
||||
if ($ttl === null) {
|
||||
return $this->putManyForever($values);
|
||||
}
|
||||
|
||||
return $this->putManyAlias($values, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
@@ -45,7 +63,7 @@ class TaggedCache extends Repository
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.7.*",
|
||||
"illuminate/support": "5.7.*"
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/support": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -25,13 +25,15 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.7-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/database": "Required to use the database cache driver (5.7.*).",
|
||||
"illuminate/filesystem": "Required to use the file cache driver (5.7.*).",
|
||||
"illuminate/redis": "Required to use the redis cache driver (5.7.*)."
|
||||
"ext-memcached": "Required to use the memcache cache driver.",
|
||||
"illuminate/database": "Required to use the database cache driver (^7.0).",
|
||||
"illuminate/filesystem": "Required to use the file cache driver (^7.0).",
|
||||
"illuminate/redis": "Required to use the redis cache driver (^7.0).",
|
||||
"symfony/cache": "Required to PSR-6 cache bridge (^5.0)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
namespace Illuminate\Config;
|
||||
|
||||
use ArrayAccess;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Contracts\Config\Repository as ConfigContract;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class Repository implements ArrayAccess, ConfigContract
|
||||
{
|
||||
@@ -41,7 +41,7 @@ class Repository implements ArrayAccess, ConfigContract
|
||||
* Get the specified configuration value.
|
||||
*
|
||||
* @param array|string $key
|
||||
* @param mixed $default
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
@@ -78,7 +78,7 @@ class Repository implements ArrayAccess, ConfigContract
|
||||
* Set a given configuration value.
|
||||
*
|
||||
* @param array|string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function set($key, $value = null)
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.7.*",
|
||||
"illuminate/support": "5.7.*"
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/support": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.7-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
||||
@@ -3,21 +3,25 @@
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\ProcessUtils;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Console\Events\ArtisanStarting;
|
||||
use Illuminate\Console\Events\CommandFinished;
|
||||
use Illuminate\Console\Events\CommandStarting;
|
||||
use Illuminate\Contracts\Console\Application as ApplicationContract;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Process\PhpExecutableFinder;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
use Symfony\Component\Console\Output\BufferedOutput;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\ProcessUtils;
|
||||
use Symfony\Component\Console\Application as SymfonyApplication;
|
||||
use Symfony\Component\Console\Command\Command as SymfonyCommand;
|
||||
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||
use Illuminate\Contracts\Console\Application as ApplicationContract;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\StringInput;
|
||||
use Symfony\Component\Console\Output\BufferedOutput;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Process\PhpExecutableFinder;
|
||||
|
||||
class Application extends SymfonyApplication implements ApplicationContract
|
||||
{
|
||||
@@ -66,7 +70,7 @@ class Application extends SymfonyApplication implements ApplicationContract
|
||||
$this->setAutoExit(false);
|
||||
$this->setCatchExceptions(false);
|
||||
|
||||
$this->events->dispatch(new Events\ArtisanStarting($this));
|
||||
$this->events->dispatch(new ArtisanStarting($this));
|
||||
|
||||
$this->bootstrap();
|
||||
}
|
||||
@@ -81,7 +85,7 @@ class Application extends SymfonyApplication implements ApplicationContract
|
||||
);
|
||||
|
||||
$this->events->dispatch(
|
||||
new Events\CommandStarting(
|
||||
new CommandStarting(
|
||||
$commandName, $input, $output = $output ?: new ConsoleOutput
|
||||
)
|
||||
);
|
||||
@@ -89,7 +93,7 @@ class Application extends SymfonyApplication implements ApplicationContract
|
||||
$exitCode = parent::run($input, $output);
|
||||
|
||||
$this->events->dispatch(
|
||||
new Events\CommandFinished($commandName, $input, $output, $exitCode)
|
||||
new CommandFinished($commandName, $input, $output, $exitCode)
|
||||
);
|
||||
|
||||
return $exitCode;
|
||||
@@ -171,25 +175,41 @@ class Application extends SymfonyApplication implements ApplicationContract
|
||||
*/
|
||||
public function call($command, array $parameters = [], $outputBuffer = null)
|
||||
{
|
||||
if (is_subclass_of($command, SymfonyCommand::class)) {
|
||||
$command = $this->laravel->make($command)->getName();
|
||||
}
|
||||
[$command, $input] = $this->parseCommand($command, $parameters);
|
||||
|
||||
if (! $this->has($command)) {
|
||||
throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $command));
|
||||
}
|
||||
|
||||
array_unshift($parameters, $command);
|
||||
return $this->run(
|
||||
$input, $this->lastOutput = $outputBuffer ?: new BufferedOutput
|
||||
);
|
||||
}
|
||||
|
||||
$this->lastOutput = $outputBuffer ?: new BufferedOutput;
|
||||
/**
|
||||
* Parse the incoming Artisan command and its input.
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function parseCommand($command, $parameters)
|
||||
{
|
||||
if (is_subclass_of($command, SymfonyCommand::class)) {
|
||||
$callingClass = true;
|
||||
|
||||
$this->setCatchExceptions(false);
|
||||
$command = $this->laravel->make($command)->getName();
|
||||
}
|
||||
|
||||
$result = $this->run(new ArrayInput($parameters), $this->lastOutput);
|
||||
if (! isset($callingClass) && empty($parameters)) {
|
||||
$command = $this->getCommandName($input = new StringInput($command));
|
||||
} else {
|
||||
array_unshift($parameters, $command);
|
||||
|
||||
$this->setCatchExceptions(true);
|
||||
$input = new ArrayInput($parameters);
|
||||
}
|
||||
|
||||
return $result;
|
||||
return [$command, $input ?? null];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,22 +2,17 @@
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
use Symfony\Component\Console\Command\Command as SymfonyCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Command\Command as SymfonyCommand;
|
||||
|
||||
class Command extends SymfonyCommand
|
||||
{
|
||||
use Macroable;
|
||||
use Concerns\CallsCommands,
|
||||
Concerns\HasParameters,
|
||||
Concerns\InteractsWithIO,
|
||||
Macroable;
|
||||
|
||||
/**
|
||||
* The Laravel application instance.
|
||||
@@ -26,20 +21,6 @@ class Command extends SymfonyCommand
|
||||
*/
|
||||
protected $laravel;
|
||||
|
||||
/**
|
||||
* The input interface implementation.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Input\InputInterface
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* The output interface implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\OutputStyle
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
@@ -57,10 +38,17 @@ class Command extends SymfonyCommand
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
* @var string|null
|
||||
*/
|
||||
protected $description;
|
||||
|
||||
/**
|
||||
* The console command help text.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $help;
|
||||
|
||||
/**
|
||||
* Indicates whether the command should be shown in the Artisan command list.
|
||||
*
|
||||
@@ -68,26 +56,6 @@ class Command extends SymfonyCommand
|
||||
*/
|
||||
protected $hidden = false;
|
||||
|
||||
/**
|
||||
* The default verbosity of output commands.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $verbosity = OutputInterface::VERBOSITY_NORMAL;
|
||||
|
||||
/**
|
||||
* 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,
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new console command instance.
|
||||
*
|
||||
@@ -107,7 +75,9 @@ class Command extends SymfonyCommand
|
||||
// Once we have constructed the command, we'll set the description and other
|
||||
// related properties of the command. If a signature wasn't used to build
|
||||
// the command we'll set the arguments and the options on this command.
|
||||
$this->setDescription($this->description);
|
||||
$this->setDescription((string) $this->description);
|
||||
|
||||
$this->setHelp((string) $this->help);
|
||||
|
||||
$this->setHidden($this->isHidden());
|
||||
|
||||
@@ -134,25 +104,6 @@ class Command extends SymfonyCommand
|
||||
$this->getDefinition()->addOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
foreach ($this->getOptions() as $options) {
|
||||
call_user_func_array([$this, 'addOption'], $options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the console command.
|
||||
*
|
||||
@@ -176,389 +127,36 @@ class Command extends SymfonyCommand
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return mixed
|
||||
* @return int
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
return $this->laravel->call([$this, 'handle']);
|
||||
return (int) $this->laravel->call([$this, 'handle']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call another console command.
|
||||
* Resolve the console command instance for the given command.
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $arguments
|
||||
* @return int
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @return \Symfony\Component\Console\Command\Command
|
||||
*/
|
||||
public function call($command, array $arguments = [])
|
||||
protected function resolveCommand($command)
|
||||
{
|
||||
$arguments['command'] = $command;
|
||||
|
||||
return $this->getApplication()->find($command)->run(
|
||||
$this->createInputFromArguments($arguments), $this->output
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call another console command silently.
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $arguments
|
||||
* @return int
|
||||
*/
|
||||
public function callSilent($command, array $arguments = [])
|
||||
{
|
||||
$arguments['command'] = $command;
|
||||
|
||||
return $this->getApplication()->find($command)->run(
|
||||
$this->createInputFromArguments($arguments), new NullOutput
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an input instance from the given arguments.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return \Symfony\Component\Console\Input\ArrayInput
|
||||
*/
|
||||
protected function createInputFromArguments(array $arguments)
|
||||
{
|
||||
return tap(new ArrayInput(array_merge($this->context(), $arguments)), function ($input) {
|
||||
if ($input->hasParameterOption(['--no-interaction'], true)) {
|
||||
$input->setInteractive(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the context passed to the command.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function context()
|
||||
{
|
||||
return collect($this->option())->only([
|
||||
'ansi',
|
||||
'no-ansi',
|
||||
'no-interaction',
|
||||
'quiet',
|
||||
'verbose',
|
||||
])->filter()->mapWithKeys(function ($value, $key) {
|
||||
return ["--{$key}" => $value];
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given argument is present.
|
||||
*
|
||||
* @param string|int $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasArgument($name)
|
||||
{
|
||||
return $this->input->hasArgument($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a command argument.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @return string|array|null
|
||||
*/
|
||||
public function argument($key = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return $this->input->getArguments();
|
||||
if (! class_exists($command)) {
|
||||
return $this->getApplication()->find($command);
|
||||
}
|
||||
|
||||
return $this->input->getArgument($key);
|
||||
}
|
||||
$command = $this->laravel->make($command);
|
||||
|
||||
/**
|
||||
* Get all of the arguments passed to the command.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function arguments()
|
||||
{
|
||||
return $this->argument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given option is present.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOption($name)
|
||||
{
|
||||
return $this->input->hasOption($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a command option.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @return string|array|bool|null
|
||||
*/
|
||||
public function option($key = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return $this->input->getOptions();
|
||||
if ($command instanceof SymfonyCommand) {
|
||||
$command->setApplication($this->getApplication());
|
||||
}
|
||||
|
||||
return $this->input->getOption($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the options passed to the command.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function options()
|
||||
{
|
||||
return $this->option();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input.
|
||||
*
|
||||
* @param string $question
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function ask($question, $default = null)
|
||||
{
|
||||
return $this->output->ask($question, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input with auto completion.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array $choices
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function anticipate($question, array $choices, $default = null)
|
||||
{
|
||||
return $this->askWithCompletion($question, $choices, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input with auto completion.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array $choices
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function askWithCompletion($question, array $choices, $default = null)
|
||||
{
|
||||
$question = new Question($question, $default);
|
||||
|
||||
$question->setAutocompleterValues($choices);
|
||||
|
||||
return $this->output->askQuestion($question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input but hide the answer from the console.
|
||||
*
|
||||
* @param string $question
|
||||
* @param bool $fallback
|
||||
* @return mixed
|
||||
*/
|
||||
public function secret($question, $fallback = true)
|
||||
{
|
||||
$question = new Question($question);
|
||||
|
||||
$question->setHidden(true)->setHiddenFallback($fallback);
|
||||
|
||||
return $this->output->askQuestion($question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the user a single choice from an array of answers.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array $choices
|
||||
* @param string|null $default
|
||||
* @param mixed|null $attempts
|
||||
* @param bool|null $multiple
|
||||
* @return string
|
||||
*/
|
||||
public function choice($question, array $choices, $default = null, $attempts = null, $multiple = null)
|
||||
{
|
||||
$question = new ChoiceQuestion($question, $choices, $default);
|
||||
|
||||
$question->setMaxAttempts($attempts)->setMultiselect($multiple);
|
||||
|
||||
return $this->output->askQuestion($question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format input to textual table.
|
||||
*
|
||||
* @param array $headers
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $rows
|
||||
* @param string $tableStyle
|
||||
* @param array $columnStyles
|
||||
* @return void
|
||||
*/
|
||||
public function table($headers, $rows, $tableStyle = 'default', array $columnStyles = [])
|
||||
{
|
||||
$table = new Table($this->output);
|
||||
|
||||
if ($rows instanceof Arrayable) {
|
||||
$rows = $rows->toArray();
|
||||
if ($command instanceof self) {
|
||||
$command->setLaravel($this->getLaravel());
|
||||
}
|
||||
|
||||
$table->setHeaders((array) $headers)->setRows($rows)->setStyle($tableStyle);
|
||||
|
||||
foreach ($columnStyles as $columnIndex => $columnStyle) {
|
||||
$table->setColumnStyle($columnIndex, $columnStyle);
|
||||
}
|
||||
|
||||
$table->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as information output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function info($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'info', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as standard output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $style
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function line($string, $style = null, $verbosity = null)
|
||||
{
|
||||
$styled = $style ? "<$style>$string</$style>" : $string;
|
||||
|
||||
$this->output->writeln($styled, $this->parseVerbosity($verbosity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as comment output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function comment($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'comment', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as question output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function question($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'question', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as error output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function error($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'error', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as warning output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string in an alert box.
|
||||
*
|
||||
* @param string $string
|
||||
* @return void
|
||||
*/
|
||||
public function alert($string)
|
||||
{
|
||||
$length = Str::length(strip_tags($string)) + 12;
|
||||
|
||||
$this->comment(str_repeat('*', $length));
|
||||
$this->comment('* '.$string.' *');
|
||||
$this->comment(str_repeat('*', $length));
|
||||
|
||||
$this->output->newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the verbosity level.
|
||||
*
|
||||
* @param string|int $level
|
||||
* @return void
|
||||
*/
|
||||
protected function setVerbosity($level)
|
||||
{
|
||||
$this->verbosity = $this->parseVerbosity($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the verbosity level in terms of Symfony's OutputInterface level.
|
||||
*
|
||||
* @param string|int|null $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;
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -572,43 +170,13 @@ class Command extends SymfonyCommand
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setHidden($hidden)
|
||||
public function setHidden(bool $hidden)
|
||||
{
|
||||
parent::setHidden($this->hidden = $hidden);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 \Illuminate\Console\OutputStyle
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Laravel application instance.
|
||||
*
|
||||
|
||||
92
vendor/laravel/framework/src/Illuminate/Console/Concerns/CallsCommands.php
vendored
Normal file
92
vendor/laravel/framework/src/Illuminate/Console/Concerns/CallsCommands.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
trait CallsCommands
|
||||
{
|
||||
/**
|
||||
* Resolve the console command instance for the given command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @return \Symfony\Component\Console\Command\Command
|
||||
*/
|
||||
abstract protected function resolveCommand($command);
|
||||
|
||||
/**
|
||||
* Call another console command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @param array $arguments
|
||||
* @return int
|
||||
*/
|
||||
public function call($command, array $arguments = [])
|
||||
{
|
||||
return $this->runCommand($command, $arguments, $this->output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call another console command silently.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @param array $arguments
|
||||
* @return int
|
||||
*/
|
||||
public function callSilent($command, array $arguments = [])
|
||||
{
|
||||
return $this->runCommand($command, $arguments, new NullOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the given the console command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @param array $arguments
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return int
|
||||
*/
|
||||
protected function runCommand($command, array $arguments, OutputInterface $output)
|
||||
{
|
||||
$arguments['command'] = $command;
|
||||
|
||||
return $this->resolveCommand($command)->run(
|
||||
$this->createInputFromArguments($arguments), $output
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an input instance from the given arguments.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return \Symfony\Component\Console\Input\ArrayInput
|
||||
*/
|
||||
protected function createInputFromArguments(array $arguments)
|
||||
{
|
||||
return tap(new ArrayInput(array_merge($this->context(), $arguments)), function ($input) {
|
||||
if ($input->getParameterOption('--no-interaction')) {
|
||||
$input->setInteractive(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the context passed to the command.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function context()
|
||||
{
|
||||
return collect($this->option())->only([
|
||||
'ansi',
|
||||
'no-ansi',
|
||||
'no-interaction',
|
||||
'quiet',
|
||||
'verbose',
|
||||
])->filter()->mapWithKeys(function ($value, $key) {
|
||||
return ["--{$key}" => $value];
|
||||
})->all();
|
||||
}
|
||||
}
|
||||
56
vendor/laravel/framework/src/Illuminate/Console/Concerns/HasParameters.php
vendored
Normal file
56
vendor/laravel/framework/src/Illuminate/Console/Concerns/HasParameters.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
trait HasParameters
|
||||
{
|
||||
/**
|
||||
* 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) {
|
||||
if ($arguments instanceof InputArgument) {
|
||||
$this->getDefinition()->addArgument($arguments);
|
||||
} else {
|
||||
$this->addArgument(...array_values($arguments));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->getOptions() as $options) {
|
||||
if ($options instanceof InputOption) {
|
||||
$this->getDefinition()->addOption($options);
|
||||
} else {
|
||||
$this->addOption(...array_values($options));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command arguments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getArguments()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
397
vendor/laravel/framework/src/Illuminate/Console/Concerns/InteractsWithIO.php
vendored
Normal file
397
vendor/laravel/framework/src/Illuminate/Console/Concerns/InteractsWithIO.php
vendored
Normal file
@@ -0,0 +1,397 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Illuminate\Console\OutputStyle;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
|
||||
trait InteractsWithIO
|
||||
{
|
||||
/**
|
||||
* The input interface implementation.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Input\InputInterface
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* The output interface implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\OutputStyle
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* The default verbosity of output commands.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $verbosity = OutputInterface::VERBOSITY_NORMAL;
|
||||
|
||||
/**
|
||||
* 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,
|
||||
];
|
||||
|
||||
/**
|
||||
* Determine if the given argument is present.
|
||||
*
|
||||
* @param string|int $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasArgument($name)
|
||||
{
|
||||
return $this->input->hasArgument($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a command argument.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @return string|array|null
|
||||
*/
|
||||
public function argument($key = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return $this->input->getArguments();
|
||||
}
|
||||
|
||||
return $this->input->getArgument($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the arguments passed to the command.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function arguments()
|
||||
{
|
||||
return $this->argument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given option is present.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOption($name)
|
||||
{
|
||||
return $this->input->hasOption($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a command option.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @return string|array|bool|null
|
||||
*/
|
||||
public function option($key = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return $this->input->getOptions();
|
||||
}
|
||||
|
||||
return $this->input->getOption($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the options passed to the command.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function options()
|
||||
{
|
||||
return $this->option();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input.
|
||||
*
|
||||
* @param string $question
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function ask($question, $default = null)
|
||||
{
|
||||
return $this->output->ask($question, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input with auto completion.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array|callable $choices
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function anticipate($question, $choices, $default = null)
|
||||
{
|
||||
return $this->askWithCompletion($question, $choices, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input with auto completion.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array|callable $choices
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function askWithCompletion($question, $choices, $default = null)
|
||||
{
|
||||
$question = new Question($question, $default);
|
||||
|
||||
is_callable($choices)
|
||||
? $question->setAutocompleterCallback($choices)
|
||||
: $question->setAutocompleterValues($choices);
|
||||
|
||||
return $this->output->askQuestion($question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input but hide the answer from the console.
|
||||
*
|
||||
* @param string $question
|
||||
* @param bool $fallback
|
||||
* @return mixed
|
||||
*/
|
||||
public function secret($question, $fallback = true)
|
||||
{
|
||||
$question = new Question($question);
|
||||
|
||||
$question->setHidden(true)->setHiddenFallback($fallback);
|
||||
|
||||
return $this->output->askQuestion($question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the user a single choice from an array of answers.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array $choices
|
||||
* @param string|null $default
|
||||
* @param mixed|null $attempts
|
||||
* @param bool $multiple
|
||||
* @return string|array
|
||||
*/
|
||||
public function choice($question, array $choices, $default = null, $attempts = null, $multiple = false)
|
||||
{
|
||||
$question = new ChoiceQuestion($question, $choices, $default);
|
||||
|
||||
$question->setMaxAttempts($attempts)->setMultiselect($multiple);
|
||||
|
||||
return $this->output->askQuestion($question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format input to textual table.
|
||||
*
|
||||
* @param array $headers
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $rows
|
||||
* @param string $tableStyle
|
||||
* @param array $columnStyles
|
||||
* @return void
|
||||
*/
|
||||
public function table($headers, $rows, $tableStyle = 'default', array $columnStyles = [])
|
||||
{
|
||||
$table = new Table($this->output);
|
||||
|
||||
if ($rows instanceof Arrayable) {
|
||||
$rows = $rows->toArray();
|
||||
}
|
||||
|
||||
$table->setHeaders((array) $headers)->setRows($rows)->setStyle($tableStyle);
|
||||
|
||||
foreach ($columnStyles as $columnIndex => $columnStyle) {
|
||||
$table->setColumnStyle($columnIndex, $columnStyle);
|
||||
}
|
||||
|
||||
$table->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as information output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function info($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'info', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as standard output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string|null $style
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function line($string, $style = null, $verbosity = null)
|
||||
{
|
||||
$styled = $style ? "<$style>$string</$style>" : $string;
|
||||
|
||||
$this->output->writeln($styled, $this->parseVerbosity($verbosity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as comment output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function comment($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'comment', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as question output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function question($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'question', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as error output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function error($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'error', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as warning output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string in an alert box.
|
||||
*
|
||||
* @param string $string
|
||||
* @return void
|
||||
*/
|
||||
public function alert($string)
|
||||
{
|
||||
$length = Str::length(strip_tags($string)) + 12;
|
||||
|
||||
$this->comment(str_repeat('*', $length));
|
||||
$this->comment('* '.$string.' *');
|
||||
$this->comment(str_repeat('*', $length));
|
||||
|
||||
$this->output->newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input interface implementation.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @return void
|
||||
*/
|
||||
public function setInput(InputInterface $input)
|
||||
{
|
||||
$this->input = $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output interface implementation.
|
||||
*
|
||||
* @param \Illuminate\Console\OutputStyle $output
|
||||
* @return void
|
||||
*/
|
||||
public function setOutput(OutputStyle $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the verbosity level.
|
||||
*
|
||||
* @param string|int $level
|
||||
* @return void
|
||||
*/
|
||||
protected function setVerbosity($level)
|
||||
{
|
||||
$this->verbosity = $this->parseVerbosity($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the verbosity level in terms of Symfony's OutputInterface level.
|
||||
*
|
||||
* @param string|int|null $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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the output implementation.
|
||||
*
|
||||
* @return \Illuminate\Console\OutputStyle
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait ConfirmableTrait
|
||||
{
|
||||
/**
|
||||
@@ -19,10 +17,10 @@ trait ConfirmableTrait
|
||||
{
|
||||
$callback = is_null($callback) ? $this->getDefaultConfirmCallback() : $callback;
|
||||
|
||||
$shouldConfirm = $callback instanceof Closure ? call_user_func($callback) : $callback;
|
||||
$shouldConfirm = value($callback);
|
||||
|
||||
if ($shouldConfirm) {
|
||||
if ($this->option('force')) {
|
||||
if ($this->hasOption('force') && $this->option('force')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -31,7 +29,7 @@ trait ConfirmableTrait
|
||||
$confirmed = $this->confirm('Do you really wish to run this command?');
|
||||
|
||||
if (! $confirmed) {
|
||||
$this->comment('Command Cancelled!');
|
||||
$this->comment('Command Canceled!');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
|
||||
trait DetectsApplicationNamespace
|
||||
{
|
||||
/**
|
||||
* Get the application namespace.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAppNamespace()
|
||||
{
|
||||
return Container::getInstance()->getNamespace();
|
||||
}
|
||||
}
|
||||
35
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskFailed.php
vendored
Normal file
35
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskFailed.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Illuminate\Console\Scheduling\Event;
|
||||
use Throwable;
|
||||
|
||||
class ScheduledTaskFailed
|
||||
{
|
||||
/**
|
||||
* The scheduled event that failed.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public $task;
|
||||
|
||||
/**
|
||||
* The exception that was thrown.
|
||||
*
|
||||
* @var \Throwable
|
||||
*/
|
||||
public $exception;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $task
|
||||
* @param \Throwable $exception
|
||||
*/
|
||||
public function __construct(Event $task, Throwable $exception)
|
||||
{
|
||||
$this->task = $task;
|
||||
$this->exception = $exception;
|
||||
}
|
||||
}
|
||||
35
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskFinished.php
vendored
Normal file
35
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskFinished.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Illuminate\Console\Scheduling\Event;
|
||||
|
||||
class ScheduledTaskFinished
|
||||
{
|
||||
/**
|
||||
* The scheduled event that ran.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public $task;
|
||||
|
||||
/**
|
||||
* The runtime of the scheduled event.
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $runtime;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $task
|
||||
* @param float $runtime
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Event $task, $runtime)
|
||||
{
|
||||
$this->task = $task;
|
||||
$this->runtime = $runtime;
|
||||
}
|
||||
}
|
||||
26
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskSkipped.php
vendored
Normal file
26
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskSkipped.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Illuminate\Console\Scheduling\Event;
|
||||
|
||||
class ScheduledTaskSkipped
|
||||
{
|
||||
/**
|
||||
* The scheduled event being run.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public $task;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $task
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Event $task)
|
||||
{
|
||||
$this->task = $task;
|
||||
}
|
||||
}
|
||||
26
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskStarting.php
vendored
Normal file
26
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskStarting.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Illuminate\Console\Scheduling\Event;
|
||||
|
||||
class ScheduledTaskStarting
|
||||
{
|
||||
/**
|
||||
* The scheduled event being run.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public $task;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $task
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Event $task)
|
||||
{
|
||||
$this->task = $task;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user