upgraded dependencies
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
namespace Illuminate\Auth\Access;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class AuthorizationException extends Exception
|
||||
{
|
||||
@@ -18,10 +19,10 @@ class AuthorizationException extends Exception
|
||||
*
|
||||
* @param string|null $message
|
||||
* @param mixed $code
|
||||
* @param \Exception|null $previous
|
||||
* @param \Throwable|null $previous
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($message = null, $code = null, Exception $previous = null)
|
||||
public function __construct($message = null, $code = null, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message ?? 'This action is unauthorized.', 0, $previous);
|
||||
|
||||
|
@@ -126,6 +126,10 @@ 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)) {
|
||||
|
@@ -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.
|
||||
|
@@ -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,14 +63,34 @@ 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::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(route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false)))
|
||||
->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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback that should be used when building the notification mail message.
|
||||
*
|
||||
|
@@ -55,8 +55,7 @@ class PasswordBroker implements PasswordBrokerContract
|
||||
return static::INVALID_USER;
|
||||
}
|
||||
|
||||
if (method_exists($this->tokens, 'recentlyCreatedToken') &&
|
||||
$this->tokens->recentlyCreatedToken($user)) {
|
||||
if ($this->tokens->recentlyCreatedToken($user)) {
|
||||
return static::RESET_THROTTLED;
|
||||
}
|
||||
|
||||
|
@@ -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.
|
||||
*
|
||||
|
@@ -199,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()
|
||||
{
|
||||
@@ -632,7 +632,8 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
/**
|
||||
* Fires the validated event if the dispatcher is set.
|
||||
*
|
||||
* @param $user
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
||||
* @return void
|
||||
*/
|
||||
protected function fireValidatedEvent($user)
|
||||
{
|
||||
|
@@ -15,10 +15,10 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^6.0",
|
||||
"illuminate/http": "^6.0",
|
||||
"illuminate/queue": "^6.0",
|
||||
"illuminate/support": "^6.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": "6.x-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/console": "Required to use the auth:clear-resets command (^6.0).",
|
||||
"illuminate/queue": "Required to fire login / logout events (^6.0).",
|
||||
"illuminate/session": "Required to use the session based guard (^6.0)."
|
||||
"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
|
||||
|
@@ -10,6 +10,7 @@ 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;
|
||||
@@ -22,7 +23,7 @@ class BroadcastManager implements FactoryContract
|
||||
/**
|
||||
* The application instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Foundation\Application
|
||||
* @var \Illuminate\Contracts\Container\Container
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
@@ -43,7 +44,7 @@ class BroadcastManager implements FactoryContract
|
||||
/**
|
||||
* Create a new manager instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @param \Illuminate\Contracts\Container\Container $app
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($app)
|
||||
@@ -59,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;
|
||||
}
|
||||
|
||||
|
@@ -262,7 +262,7 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
* Normalize the given callback into a callable.
|
||||
*
|
||||
* @param mixed $callback
|
||||
* @return \Closure|callable
|
||||
* @return callable
|
||||
*/
|
||||
protected function normalizeChannelHandlerToCallable($callback)
|
||||
{
|
||||
|
@@ -17,10 +17,10 @@
|
||||
"php": "^7.2.5|^8.0",
|
||||
"ext-json": "*",
|
||||
"psr/log": "^1.0",
|
||||
"illuminate/bus": "^6.0",
|
||||
"illuminate/contracts": "^6.0",
|
||||
"illuminate/queue": "^6.0",
|
||||
"illuminate/support": "^6.0"
|
||||
"illuminate/bus": "^7.0",
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/queue": "^7.0",
|
||||
"illuminate/support": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.x-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
|
@@ -2,7 +2,10 @@
|
||||
|
||||
namespace Illuminate\Bus;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Queue\CallQueuedClosure;
|
||||
use Illuminate\Support\Arr;
|
||||
use RuntimeException;
|
||||
|
||||
trait Queueable
|
||||
{
|
||||
@@ -43,6 +46,8 @@ trait Queueable
|
||||
|
||||
/**
|
||||
* The middleware the job should be dispatched through.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $middleware = [];
|
||||
|
||||
@@ -120,16 +125,6 @@ trait Queueable
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the middleware the job should be dispatched through.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function middleware()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the middleware the job should be dispatched through.
|
||||
*
|
||||
@@ -152,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.
|
||||
*
|
||||
|
@@ -15,9 +15,9 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^6.0",
|
||||
"illuminate/pipeline": "^6.0",
|
||||
"illuminate/support": "^6.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": "6.x-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/queue": "Required to use closures when chaining jobs (^7.0)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class ArrayLock extends Lock
|
||||
{
|
||||
|
@@ -23,6 +23,24 @@ class ArrayStore extends TaggableStore implements LockProvider
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@@ -45,7 +63,7 @@ class ArrayStore extends TaggableStore implements LockProvider
|
||||
return;
|
||||
}
|
||||
|
||||
return $item['value'];
|
||||
return $this->serializesValues ? unserialize($item['value']) : $item['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +77,7 @@ class ArrayStore extends TaggableStore implements LockProvider
|
||||
public function put($key, $value, $seconds)
|
||||
{
|
||||
$this->storage[$key] = [
|
||||
'value' => $value,
|
||||
'value' => $this->serializesValues ? serialize($value) : $value,
|
||||
'expiresAt' => $this->calculateExpiration($seconds),
|
||||
];
|
||||
|
||||
@@ -75,15 +93,17 @@ class ArrayStore extends TaggableStore implements LockProvider
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
{
|
||||
if (! isset($this->storage[$key])) {
|
||||
$this->forever($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]['value'];
|
||||
$this->storage[$key]['value'] = $value;
|
||||
});
|
||||
}
|
||||
|
||||
$this->storage[$key]['value'] = ((int) $this->storage[$key]['value']) + $value;
|
||||
$this->forever($key, $value);
|
||||
|
||||
return $this->storage[$key]['value'];
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -138,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));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,7 +214,11 @@ 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]
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -226,11 +231,21 @@ class CacheManager implements FactoryContract
|
||||
*/
|
||||
protected function createDynamodbDriver(array $config)
|
||||
{
|
||||
$client = $this->newDynamodbClient($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(
|
||||
$client,
|
||||
new DynamoDbClient($dynamoConfig),
|
||||
$config['table'],
|
||||
$config['attributes']['key'] ?? 'key',
|
||||
$config['attributes']['value'] ?? 'value',
|
||||
@@ -240,28 +255,6 @@ class CacheManager implements FactoryContract
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new DynamoDb Client instance.
|
||||
*
|
||||
* @return DynamoDbClient
|
||||
*/
|
||||
protected function newDynamodbClient(array $config)
|
||||
{
|
||||
$dynamoConfig = [
|
||||
'region' => $config['region'],
|
||||
'version' => 'latest',
|
||||
'endpoint' => $config['endpoint'] ?? null,
|
||||
];
|
||||
|
||||
if (isset($config['key']) && isset($config['secret'])) {
|
||||
$dynamoConfig['credentials'] = Arr::only(
|
||||
$config, ['key', 'secret', 'token']
|
||||
);
|
||||
}
|
||||
|
||||
return new DynamoDbClient($dynamoConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new cache repository with the given implementation.
|
||||
*
|
||||
|
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\Contracts\Cache\LockProvider;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,9 +118,7 @@ class DatabaseStore implements Store
|
||||
public function put($key, $value, $seconds)
|
||||
{
|
||||
$key = $this->prefix.$key;
|
||||
|
||||
$value = $this->serialize($value);
|
||||
|
||||
$expiration = $this->getTime() + $seconds;
|
||||
|
||||
try {
|
||||
@@ -108,6 +130,35 @@ class DatabaseStore implements Store
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -205,6 +256,38 @@ class DatabaseStore implements Store
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the cache.
|
||||
*
|
||||
|
@@ -525,14 +525,4 @@ class DynamoDbStore implements LockProvider, Store
|
||||
{
|
||||
$this->prefix = ! empty($prefix) ? $prefix.':' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DynamoDb Client instance.
|
||||
*
|
||||
* @return DynamoDbClient
|
||||
*/
|
||||
public function getClient()
|
||||
{
|
||||
return $this->dynamo;
|
||||
}
|
||||
}
|
||||
|
@@ -32,6 +32,13 @@ abstract class Lock implements LockContract
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@@ -98,7 +105,7 @@ abstract class Lock implements LockContract
|
||||
*
|
||||
* @param int $seconds
|
||||
* @param callable|null $callback
|
||||
* @return mixed
|
||||
* @return bool
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Cache\LockTimeoutException
|
||||
*/
|
||||
@@ -107,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;
|
||||
@@ -144,4 +151,17 @@ abstract class Lock implements LockContract
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -36,8 +36,6 @@ class RateLimiter
|
||||
*/
|
||||
public function tooManyAttempts($key, $maxAttempts)
|
||||
{
|
||||
$key = $this->cleanRateLimiterKey($key);
|
||||
|
||||
if ($this->attempts($key) >= $maxAttempts) {
|
||||
if ($this->cache->has($key.':timer')) {
|
||||
return true;
|
||||
@@ -58,8 +56,6 @@ class RateLimiter
|
||||
*/
|
||||
public function hit($key, $decaySeconds = 60)
|
||||
{
|
||||
$key = $this->cleanRateLimiterKey($key);
|
||||
|
||||
$this->cache->add(
|
||||
$key.':timer', $this->availableAt($decaySeconds), $decaySeconds
|
||||
);
|
||||
@@ -83,8 +79,6 @@ class RateLimiter
|
||||
*/
|
||||
public function attempts($key)
|
||||
{
|
||||
$key = $this->cleanRateLimiterKey($key);
|
||||
|
||||
return $this->cache->get($key, 0);
|
||||
}
|
||||
|
||||
@@ -96,8 +90,6 @@ class RateLimiter
|
||||
*/
|
||||
public function resetAttempts($key)
|
||||
{
|
||||
$key = $this->cleanRateLimiterKey($key);
|
||||
|
||||
return $this->cache->forget($key);
|
||||
}
|
||||
|
||||
@@ -110,8 +102,6 @@ class RateLimiter
|
||||
*/
|
||||
public function retriesLeft($key, $maxAttempts)
|
||||
{
|
||||
$key = $this->cleanRateLimiterKey($key);
|
||||
|
||||
$attempts = $this->attempts($key);
|
||||
|
||||
return $maxAttempts - $attempts;
|
||||
@@ -125,8 +115,6 @@ class RateLimiter
|
||||
*/
|
||||
public function clear($key)
|
||||
{
|
||||
$key = $this->cleanRateLimiterKey($key);
|
||||
|
||||
$this->resetAttempts($key);
|
||||
|
||||
$this->cache->forget($key.':timer');
|
||||
@@ -140,19 +128,6 @@ class RateLimiter
|
||||
*/
|
||||
public function availableIn($key)
|
||||
{
|
||||
$key = $this->cleanRateLimiterKey($key);
|
||||
|
||||
return $this->cache->get($key.':timer') - $this->currentTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the rate limiter key from unicode characters.
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function cleanRateLimiterKey($key)
|
||||
{
|
||||
return preg_replace('/&([a-z])[a-z]+;/i', '$1', htmlentities($key));
|
||||
}
|
||||
}
|
||||
|
@@ -15,8 +15,8 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^6.0",
|
||||
"illuminate/support": "^6.0"
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/support": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -25,15 +25,15 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.x-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-memcached": "Required to use the memcache cache driver.",
|
||||
"illuminate/database": "Required to use the database cache driver (^6.0).",
|
||||
"illuminate/filesystem": "Required to use the file cache driver (^6.0).",
|
||||
"illuminate/redis": "Required to use the redis cache driver (^6.0).",
|
||||
"symfony/cache": "Required to PSR-6 cache bridge (^4.3.4)."
|
||||
"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
|
||||
|
@@ -15,8 +15,8 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^6.0",
|
||||
"illuminate/support": "^6.0"
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/support": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.x-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@@ -116,7 +116,7 @@ class Application extends SymfonyApplication implements ApplicationContract
|
||||
*/
|
||||
public static function artisanBinary()
|
||||
{
|
||||
return ProcessUtils::escapeArgument(defined('ARTISAN_BINARY') ? ARTISAN_BINARY : 'artisan');
|
||||
return defined('ARTISAN_BINARY') ? ProcessUtils::escapeArgument(ARTISAN_BINARY) : 'artisan';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -127,11 +127,11 @@ 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']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,7 +170,7 @@ class Command extends SymfonyCommand
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setHidden($hidden)
|
||||
public function setHidden(bool $hidden)
|
||||
{
|
||||
parent::setHidden($this->hidden = $hidden);
|
||||
|
||||
|
@@ -199,10 +199,10 @@ trait InteractsWithIO
|
||||
* @param array $choices
|
||||
* @param string|null $default
|
||||
* @param mixed|null $attempts
|
||||
* @param bool|null $multiple
|
||||
* @return string
|
||||
* @param bool $multiple
|
||||
* @return string|array
|
||||
*/
|
||||
public function choice($question, array $choices, $default = null, $attempts = null, $multiple = null)
|
||||
public function choice($question, array $choices, $default = null, $attempts = null, $multiple = false)
|
||||
{
|
||||
$question = new ChoiceQuestion($question, $choices, $default);
|
||||
|
||||
|
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
|
||||
/**
|
||||
* @deprecated Usage of this trait is deprecated and it will be removed in Laravel 7.0.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@@ -22,6 +22,82 @@ abstract class GeneratorCommand extends Command
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Reserved names that cannot be used for generation.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $reservedNames = [
|
||||
'__halt_compiler',
|
||||
'abstract',
|
||||
'and',
|
||||
'array',
|
||||
'as',
|
||||
'break',
|
||||
'callable',
|
||||
'case',
|
||||
'catch',
|
||||
'class',
|
||||
'clone',
|
||||
'const',
|
||||
'continue',
|
||||
'declare',
|
||||
'default',
|
||||
'die',
|
||||
'do',
|
||||
'echo',
|
||||
'else',
|
||||
'elseif',
|
||||
'empty',
|
||||
'enddeclare',
|
||||
'endfor',
|
||||
'endforeach',
|
||||
'endif',
|
||||
'endswitch',
|
||||
'endwhile',
|
||||
'eval',
|
||||
'exit',
|
||||
'extends',
|
||||
'final',
|
||||
'finally',
|
||||
'fn',
|
||||
'for',
|
||||
'foreach',
|
||||
'function',
|
||||
'global',
|
||||
'goto',
|
||||
'if',
|
||||
'implements',
|
||||
'include',
|
||||
'include_once',
|
||||
'instanceof',
|
||||
'insteadof',
|
||||
'interface',
|
||||
'isset',
|
||||
'list',
|
||||
'namespace',
|
||||
'new',
|
||||
'or',
|
||||
'print',
|
||||
'private',
|
||||
'protected',
|
||||
'public',
|
||||
'require',
|
||||
'require_once',
|
||||
'return',
|
||||
'static',
|
||||
'switch',
|
||||
'throw',
|
||||
'trait',
|
||||
'try',
|
||||
'unset',
|
||||
'use',
|
||||
'var',
|
||||
'while',
|
||||
'xor',
|
||||
'yield',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new controller creator command instance.
|
||||
*
|
||||
@@ -51,11 +127,20 @@ abstract class GeneratorCommand extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// First we need to ensure that the given name is not a reserved word within the PHP
|
||||
// language and that the class name will actually be valid. If it is not valid we
|
||||
// can error now and prevent from polluting the filesystem using invalid files.
|
||||
if ($this->isReservedName($this->getNameInput())) {
|
||||
$this->error('The name "'.$this->getNameInput().'" is reserved by PHP.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $this->qualifyClass($this->getNameInput());
|
||||
|
||||
$path = $this->getPath($name);
|
||||
|
||||
// First we will check to see if the class already exists. If it does, we don't want
|
||||
// Next, We will check to see if the class already exists. If it does, we don't want
|
||||
// to create the class and overwrite the user's code. So, we will bail out so the
|
||||
// code is untouched. Otherwise, we will continue generating this class' files.
|
||||
if ((! $this->hasOption('force') ||
|
||||
@@ -173,11 +258,19 @@ abstract class GeneratorCommand extends Command
|
||||
*/
|
||||
protected function replaceNamespace(&$stub, $name)
|
||||
{
|
||||
$stub = str_replace(
|
||||
$searches = [
|
||||
['DummyNamespace', 'DummyRootNamespace', 'NamespacedDummyUserModel'],
|
||||
[$this->getNamespace($name), $this->rootNamespace(), $this->userProviderModel()],
|
||||
$stub
|
||||
);
|
||||
['{{ namespace }}', '{{ rootNamespace }}', '{{ namespacedUserModel }}'],
|
||||
['{{namespace}}', '{{rootNamespace}}', '{{namespacedUserModel}}'],
|
||||
];
|
||||
|
||||
foreach ($searches as $search) {
|
||||
$stub = str_replace(
|
||||
$search,
|
||||
[$this->getNamespace($name), $this->rootNamespace(), $this->userProviderModel()],
|
||||
$stub
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -204,7 +297,7 @@ abstract class GeneratorCommand extends Command
|
||||
{
|
||||
$class = str_replace($this->getNamespace($name).'\\', '', $name);
|
||||
|
||||
return str_replace('DummyClass', $class, $stub);
|
||||
return str_replace(['DummyClass', '{{ class }}', '{{class}}'], $class, $stub);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,6 +353,32 @@ abstract class GeneratorCommand extends Command
|
||||
return $config->get("auth.providers.{$provider}.model");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given name is reserved.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
protected function isReservedName($name)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
return in_array($name, $this->reservedNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first view directory path from the application configuration.
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
protected function viewPath($path = '')
|
||||
{
|
||||
$views = $this->laravel['config']['view.paths'][0] ?? resource_path('views');
|
||||
|
||||
return $views.($path ? DIRECTORY_SEPARATOR.$path : $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command arguments.
|
||||
*
|
||||
|
14
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheAware.php
vendored
Normal file
14
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheAware.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
interface CacheAware
|
||||
{
|
||||
/**
|
||||
* Specify the cache store that should be used.
|
||||
*
|
||||
* @param string $store
|
||||
* @return $this
|
||||
*/
|
||||
public function useStore($store);
|
||||
}
|
@@ -4,7 +4,7 @@ namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Contracts\Cache\Factory as Cache;
|
||||
|
||||
class CacheEventMutex implements EventMutex
|
||||
class CacheEventMutex implements EventMutex, CacheAware
|
||||
{
|
||||
/**
|
||||
* The cache repository implementation.
|
||||
|
@@ -5,7 +5,7 @@ namespace Illuminate\Console\Scheduling;
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Contracts\Cache\Factory as Cache;
|
||||
|
||||
class CacheSchedulingMutex implements SchedulingMutex
|
||||
class CacheSchedulingMutex implements SchedulingMutex, CacheAware
|
||||
{
|
||||
/**
|
||||
* The cache factory implementation.
|
||||
|
@@ -10,15 +10,17 @@ use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\Debug\ExceptionHandler;
|
||||
use Illuminate\Contracts\Mail\Mailer;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Illuminate\Support\Reflector;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Support\Traits\ReflectsClosures;
|
||||
use Psr\Http\Client\ClientExceptionInterface;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
class Event
|
||||
{
|
||||
use Macroable, ManagesFrequencies;
|
||||
use Macroable, ManagesFrequencies, ReflectsClosures;
|
||||
|
||||
/**
|
||||
* The command string.
|
||||
@@ -319,10 +321,10 @@ class Event
|
||||
*/
|
||||
protected function expressionPasses()
|
||||
{
|
||||
$date = Date::now();
|
||||
$date = Carbon::now();
|
||||
|
||||
if ($this->timezone) {
|
||||
$date = $date->setTimezone($this->timezone);
|
||||
$date->setTimezone($this->timezone);
|
||||
}
|
||||
|
||||
return CronExpression::factory($this->expression)->isDue($date->toDateTimeString());
|
||||
@@ -576,7 +578,7 @@ class Event
|
||||
{
|
||||
return function (Container $container, HttpClient $http) use ($url) {
|
||||
try {
|
||||
$http->get($url);
|
||||
$http->request('GET', $url);
|
||||
} catch (ClientExceptionInterface|TransferException $e) {
|
||||
$container->make(ExceptionHandler::class)->report($e);
|
||||
}
|
||||
@@ -731,6 +733,20 @@ class Event
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback that uses the output after the job runs.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $onlyIfOutputExists
|
||||
* @return $this
|
||||
*/
|
||||
public function thenWithOutput(Closure $callback, $onlyIfOutputExists = false)
|
||||
{
|
||||
$this->ensureOutputIsBeingCaptured();
|
||||
|
||||
return $this->then($this->withOutputCallback($callback, $onlyIfOutputExists));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be called if the operation succeeds.
|
||||
*
|
||||
@@ -746,6 +762,20 @@ class Event
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback that uses the output if the operation succeeds.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $onlyIfOutputExists
|
||||
* @return $this
|
||||
*/
|
||||
public function onSuccessWithOutput(Closure $callback, $onlyIfOutputExists = false)
|
||||
{
|
||||
$this->ensureOutputIsBeingCaptured();
|
||||
|
||||
return $this->onSuccess($this->withOutputCallback($callback, $onlyIfOutputExists));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be called if the operation fails.
|
||||
*
|
||||
@@ -761,6 +791,38 @@ class Event
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback that uses the output if the operation fails.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $onlyIfOutputExists
|
||||
* @return $this
|
||||
*/
|
||||
public function onFailureWithOutput(Closure $callback, $onlyIfOutputExists = false)
|
||||
{
|
||||
$this->ensureOutputIsBeingCaptured();
|
||||
|
||||
return $this->onFailure($this->withOutputCallback($callback, $onlyIfOutputExists));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a callback that provides output.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $onlyIfOutputExists
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function withOutputCallback(Closure $callback, $onlyIfOutputExists = false)
|
||||
{
|
||||
return function (Container $container) use ($callback, $onlyIfOutputExists) {
|
||||
$output = $this->output && file_exists($this->output) ? file_get_contents($this->output) : '';
|
||||
|
||||
return $onlyIfOutputExists && empty($output)
|
||||
? null
|
||||
: $container->call($callback, ['output' => $output]);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the human-friendly description of the event.
|
||||
*
|
||||
|
@@ -81,6 +81,36 @@ trait ManagesFrequencies
|
||||
return $this->spliceIntoPosition(1, '*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every two minutes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyTwoMinutes()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*/2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every three minutes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyThreeMinutes()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*/3');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every four minutes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyFourMinutes()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*/4');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every five minutes.
|
||||
*
|
||||
@@ -144,6 +174,50 @@ trait ManagesFrequencies
|
||||
return $this->spliceIntoPosition(1, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every two hours.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyTwoHours()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, 0)
|
||||
->spliceIntoPosition(2, '*/2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every three hours.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyThreeHours()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, 0)
|
||||
->spliceIntoPosition(2, '*/3');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every four hours.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyFourHours()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, 0)
|
||||
->spliceIntoPosition(2, '*/4');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every six hours.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everySixHours()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, 0)
|
||||
->spliceIntoPosition(2, '*/6');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run daily.
|
||||
*
|
||||
@@ -338,21 +412,37 @@ trait ManagesFrequencies
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run twice monthly.
|
||||
* Schedule the event to run twice monthly at a given time.
|
||||
*
|
||||
* @param int $first
|
||||
* @param int $second
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function twiceMonthly($first = 1, $second = 16)
|
||||
public function twiceMonthly($first = 1, $second = 16, $time = '0:0')
|
||||
{
|
||||
$days = $first.','.$second;
|
||||
|
||||
$this->dailyAt($time);
|
||||
|
||||
return $this->spliceIntoPosition(1, 0)
|
||||
->spliceIntoPosition(2, 0)
|
||||
->spliceIntoPosition(3, $days);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run on the last day of the month.
|
||||
*
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function lastDayOfMonth($time = '0:0')
|
||||
{
|
||||
$this->dailyAt($time);
|
||||
|
||||
return $this->spliceIntoPosition(3, Carbon::now()->endOfMonth()->day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run quarterly.
|
||||
*
|
||||
|
@@ -278,11 +278,11 @@ class Schedule
|
||||
*/
|
||||
public function useCache($store)
|
||||
{
|
||||
if ($this->eventMutex instanceof CacheEventMutex) {
|
||||
if ($this->eventMutex instanceof CacheAware) {
|
||||
$this->eventMutex->useStore($store);
|
||||
}
|
||||
|
||||
if ($this->schedulingMutex instanceof CacheSchedulingMutex) {
|
||||
if ($this->schedulingMutex instanceof CacheAware) {
|
||||
$this->schedulingMutex->useStore($store);
|
||||
}
|
||||
|
||||
|
@@ -3,11 +3,14 @@
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Console\Events\ScheduledTaskFailed;
|
||||
use Illuminate\Console\Events\ScheduledTaskFinished;
|
||||
use Illuminate\Console\Events\ScheduledTaskSkipped;
|
||||
use Illuminate\Console\Events\ScheduledTaskStarting;
|
||||
use Illuminate\Contracts\Debug\ExceptionHandler;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Throwable;
|
||||
|
||||
class ScheduleRunCommand extends Command
|
||||
{
|
||||
@@ -53,6 +56,13 @@ class ScheduleRunCommand extends Command
|
||||
*/
|
||||
protected $dispatcher;
|
||||
|
||||
/**
|
||||
* The exception handler.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Debug\ExceptionHandler
|
||||
*/
|
||||
protected $handler;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
@@ -70,12 +80,14 @@ class ScheduleRunCommand extends Command
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $dispatcher
|
||||
* @param \Illuminate\Contracts\Debug\ExceptionHandler $handler
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Schedule $schedule, Dispatcher $dispatcher)
|
||||
public function handle(Schedule $schedule, Dispatcher $dispatcher, ExceptionHandler $handler)
|
||||
{
|
||||
$this->schedule = $schedule;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->handler = $handler;
|
||||
|
||||
foreach ($this->schedule->dueEvents($this->laravel) as $event) {
|
||||
if (! $event->filtersPass($this->laravel)) {
|
||||
@@ -127,13 +139,19 @@ class ScheduleRunCommand extends Command
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
$event->run($this->laravel);
|
||||
try {
|
||||
$event->run($this->laravel);
|
||||
|
||||
$this->dispatcher->dispatch(new ScheduledTaskFinished(
|
||||
$event,
|
||||
round(microtime(true) - $start, 2)
|
||||
));
|
||||
$this->dispatcher->dispatch(new ScheduledTaskFinished(
|
||||
$event,
|
||||
round(microtime(true) - $start, 2)
|
||||
));
|
||||
|
||||
$this->eventsRan = true;
|
||||
$this->eventsRan = true;
|
||||
} catch (Throwable $e) {
|
||||
$this->dispatcher->dispatch(new ScheduledTaskFailed($event, $e));
|
||||
|
||||
$this->handler->report($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,10 +15,10 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^6.0",
|
||||
"illuminate/support": "^6.0",
|
||||
"symfony/console": "^4.3.4",
|
||||
"symfony/process": "^4.3.4"
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/support": "^7.0",
|
||||
"symfony/console": "^5.0",
|
||||
"symfony/process": "^5.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -27,16 +27,16 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.x-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"dragonmantank/cron-expression": "Required to use scheduler (^2.3.1).",
|
||||
"guzzlehttp/guzzle": "Required to use the ping methods on schedules (^6.3.1|^7.0.1).",
|
||||
"illuminate/bus": "Required to use the scheduled job dispatcher (^6.0)",
|
||||
"illuminate/container": "Required to use the scheduler (^6.0)",
|
||||
"illuminate/filesystem": "Required to use the generator command (^6.0)",
|
||||
"illuminate/queue": "Required to use closures for scheduled jobs (^6.0)"
|
||||
"illuminate/bus": "Required to use the scheduled job dispatcher (^7.0).",
|
||||
"illuminate/container": "Required to use the scheduler (^7.0).",
|
||||
"illuminate/filesystem": "Required to use the generator command (^7.0).",
|
||||
"illuminate/queue": "Required to use closures for scheduled jobs (^7.0)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
|
@@ -234,6 +234,10 @@ class Container implements ArrayAccess, ContainerContract
|
||||
// bound into this container to the abstract type and we will just wrap it
|
||||
// up inside its own Closure to give us more convenience when extending.
|
||||
if (! $concrete instanceof Closure) {
|
||||
if (! is_string($concrete)) {
|
||||
throw new \TypeError(self::class.'::bind(): Argument #2 ($concrete) must be of type Closure|string|null');
|
||||
}
|
||||
|
||||
$concrete = $this->getClosure($abstract, $concrete);
|
||||
}
|
||||
|
||||
@@ -581,9 +585,11 @@ class Container implements ArrayAccess, ContainerContract
|
||||
* Call the given Closure / class@method and inject its dependencies.
|
||||
*
|
||||
* @param callable|string $callback
|
||||
* @param array $parameters
|
||||
* @param array<string, mixed> $parameters
|
||||
* @param string|null $defaultMethod
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function call($callback, array $parameters = [], $defaultMethod = null)
|
||||
{
|
||||
@@ -609,6 +615,8 @@ class Container implements ArrayAccess, ContainerContract
|
||||
* @param string $abstract
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function makeWith($abstract, array $parameters = [])
|
||||
{
|
||||
@@ -659,9 +667,9 @@ class Container implements ArrayAccess, ContainerContract
|
||||
{
|
||||
$abstract = $this->getAlias($abstract);
|
||||
|
||||
$needsContextualBuild = ! empty($parameters) || ! is_null(
|
||||
$this->getContextualConcrete($abstract)
|
||||
);
|
||||
$concrete = $this->getContextualConcrete($abstract);
|
||||
|
||||
$needsContextualBuild = ! empty($parameters) || ! is_null($concrete);
|
||||
|
||||
// If an instance of the type is currently being managed as a singleton we'll
|
||||
// just return an existing instance instead of instantiating new instances
|
||||
@@ -672,7 +680,9 @@ class Container implements ArrayAccess, ContainerContract
|
||||
|
||||
$this->with[] = $parameters;
|
||||
|
||||
$concrete = $this->getConcrete($abstract);
|
||||
if (is_null($concrete)) {
|
||||
$concrete = $this->getConcrete($abstract);
|
||||
}
|
||||
|
||||
// We're ready to instantiate an instance of the concrete type registered for
|
||||
// the binding. This will instantiate the types, as well as resolve any of
|
||||
@@ -719,10 +729,6 @@ class Container implements ArrayAccess, ContainerContract
|
||||
*/
|
||||
protected function getConcrete($abstract)
|
||||
{
|
||||
if (! is_null($concrete = $this->getContextualConcrete($abstract))) {
|
||||
return $concrete;
|
||||
}
|
||||
|
||||
// If we don't have a registered resolver or concrete for the type, we'll just
|
||||
// assume each type is a concrete name and will attempt to resolve it as is
|
||||
// since the container should be able to resolve concretes automatically.
|
||||
@@ -737,7 +743,7 @@ class Container implements ArrayAccess, ContainerContract
|
||||
* Get the contextual concrete binding for the given abstract.
|
||||
*
|
||||
* @param string $abstract
|
||||
* @return \Closure|string|null
|
||||
* @return \Closure|string|array|null
|
||||
*/
|
||||
protected function getContextualConcrete($abstract)
|
||||
{
|
||||
@@ -785,7 +791,7 @@ class Container implements ArrayAccess, ContainerContract
|
||||
/**
|
||||
* Instantiate a concrete instance of the given type.
|
||||
*
|
||||
* @param string $concrete
|
||||
* @param \Closure|string $concrete
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
@@ -856,7 +862,7 @@ class Container implements ArrayAccess, ContainerContract
|
||||
$results = [];
|
||||
|
||||
foreach ($dependencies as $dependency) {
|
||||
// If this dependency has a override for this particular build we will use
|
||||
// If the dependency has an override for this particular build we will use
|
||||
// that instead as the value. Otherwise, we will continue with this run
|
||||
// of resolutions and let reflection attempt to determine the result.
|
||||
if ($this->hasParameterOverride($dependency)) {
|
||||
@@ -868,9 +874,15 @@ class Container implements ArrayAccess, ContainerContract
|
||||
// If the class is null, it means the dependency is a string or some other
|
||||
// primitive type which we can not resolve since it is not a class and
|
||||
// we will just bomb out with an error since we have no-where to go.
|
||||
$results[] = is_null(Util::getParameterClassName($dependency))
|
||||
$result = is_null(Util::getParameterClassName($dependency))
|
||||
? $this->resolvePrimitive($dependency)
|
||||
: $this->resolveClass($dependency);
|
||||
|
||||
if ($dependency->isVariadic()) {
|
||||
$results = array_merge($results, $result);
|
||||
} else {
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
@@ -942,21 +954,48 @@ class Container implements ArrayAccess, ContainerContract
|
||||
protected function resolveClass(ReflectionParameter $parameter)
|
||||
{
|
||||
try {
|
||||
return $this->make(Util::getParameterClassName($parameter));
|
||||
return $parameter->isVariadic()
|
||||
? $this->resolveVariadicClass($parameter)
|
||||
: $this->make(Util::getParameterClassName($parameter));
|
||||
}
|
||||
|
||||
// If we can not resolve the class instance, we will check to see if the value
|
||||
// is optional, and if it is we will return the optional parameter value as
|
||||
// the value of the dependency, similarly to how we do this with scalars.
|
||||
catch (BindingResolutionException $e) {
|
||||
if ($parameter->isOptional()) {
|
||||
if ($parameter->isDefaultValueAvailable()) {
|
||||
return $parameter->getDefaultValue();
|
||||
}
|
||||
|
||||
if ($parameter->isVariadic()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a class based variadic dependency from the container.
|
||||
*
|
||||
* @param \ReflectionParameter $parameter
|
||||
* @return mixed
|
||||
*/
|
||||
protected function resolveVariadicClass(ReflectionParameter $parameter)
|
||||
{
|
||||
$className = Util::getParameterClassName($parameter);
|
||||
|
||||
$abstract = $this->getAlias($className);
|
||||
|
||||
if (! is_array($concrete = $this->getContextualConcrete($abstract))) {
|
||||
return $this->make($className);
|
||||
}
|
||||
|
||||
return array_map(function ($abstract) {
|
||||
return $this->resolve($abstract);
|
||||
}, $concrete);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw an exception that the concrete is not instantiable.
|
||||
*
|
||||
|
@@ -57,7 +57,7 @@ class ContextualBindingBuilder implements ContextualBindingBuilderContract
|
||||
/**
|
||||
* Define the implementation for the contextual binding.
|
||||
*
|
||||
* @param \Closure|string $implementation
|
||||
* @param \Closure|string|array $implementation
|
||||
* @return void
|
||||
*/
|
||||
public function give($implementation)
|
||||
@@ -66,4 +66,19 @@ class ContextualBindingBuilder implements ContextualBindingBuilderContract
|
||||
$this->container->addContextualBinding($concrete, $this->needs, $implementation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define tagged services to be used as the implementation for the contextual binding.
|
||||
*
|
||||
* @param string $tag
|
||||
* @return void
|
||||
*/
|
||||
public function giveTagged($tag)
|
||||
{
|
||||
$this->give(function ($container) use ($tag) {
|
||||
$taggedServices = $container->tagged($tag);
|
||||
|
||||
return is_array($taggedServices) ? $taggedServices : iterator_to_array($taggedServices);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -15,9 +15,12 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^6.0",
|
||||
"illuminate/contracts": "^7.0",
|
||||
"psr/container": "^1.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/container-implementation": "1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Container\\": ""
|
||||
@@ -25,7 +28,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.x-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@@ -7,9 +7,9 @@ interface Authorizable
|
||||
/**
|
||||
* Determine if the entity has a given ability.
|
||||
*
|
||||
* @param string $ability
|
||||
* @param iterable|string $abilities
|
||||
* @param array|mixed $arguments
|
||||
* @return bool
|
||||
*/
|
||||
public function can($ability, $arguments = []);
|
||||
public function can($abilities, $arguments = []);
|
||||
}
|
||||
|
8
vendor/laravel/framework/src/Illuminate/Contracts/Auth/Middleware/AuthenticatesRequests.php
vendored
Normal file
8
vendor/laravel/framework/src/Illuminate/Contracts/Auth/Middleware/AuthenticatesRequests.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Auth\Middleware;
|
||||
|
||||
interface AuthenticatesRequests
|
||||
{
|
||||
//
|
||||
}
|
@@ -43,7 +43,7 @@ interface StatefulGuard extends Guard
|
||||
* Log the given user ID into the application without sessions or cookies.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @return bool
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|bool
|
||||
*/
|
||||
public function onceUsingId($id);
|
||||
|
||||
|
@@ -8,7 +8,7 @@ interface Factory
|
||||
* Get a broadcaster implementation by name.
|
||||
*
|
||||
* @param string|null $name
|
||||
* @return void
|
||||
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
|
||||
*/
|
||||
public function connection($name = null);
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ interface Lock
|
||||
*
|
||||
* @param int $seconds
|
||||
* @param callable|null $callback
|
||||
* @return mixed
|
||||
* @return bool
|
||||
*/
|
||||
public function block($seconds, $callback = null);
|
||||
|
||||
|
13
vendor/laravel/framework/src/Illuminate/Contracts/Database/Eloquent/Castable.php
vendored
Normal file
13
vendor/laravel/framework/src/Illuminate/Contracts/Database/Eloquent/Castable.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Database\Eloquent;
|
||||
|
||||
interface Castable
|
||||
{
|
||||
/**
|
||||
* Get the name of the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @return string|\Illuminate\Contracts\Database\Eloquent\CastsAttributes|\Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes
|
||||
*/
|
||||
public static function castUsing();
|
||||
}
|
28
vendor/laravel/framework/src/Illuminate/Contracts/Database/Eloquent/CastsAttributes.php
vendored
Normal file
28
vendor/laravel/framework/src/Illuminate/Contracts/Database/Eloquent/CastsAttributes.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Database\Eloquent;
|
||||
|
||||
interface CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Transform the attribute from the underlying model values.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($model, string $key, $value, array $attributes);
|
||||
|
||||
/**
|
||||
* Transform the attribute to its underlying model values.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return mixed
|
||||
*/
|
||||
public function set($model, string $key, $value, array $attributes);
|
||||
}
|
17
vendor/laravel/framework/src/Illuminate/Contracts/Database/Eloquent/CastsInboundAttributes.php
vendored
Normal file
17
vendor/laravel/framework/src/Illuminate/Contracts/Database/Eloquent/CastsInboundAttributes.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Database\Eloquent;
|
||||
|
||||
interface CastsInboundAttributes
|
||||
{
|
||||
/**
|
||||
* Transform the attribute to its underlying model values.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return mixed
|
||||
*/
|
||||
public function set($model, string $key, $value, array $attributes);
|
||||
}
|
@@ -2,45 +2,45 @@
|
||||
|
||||
namespace Illuminate\Contracts\Debug;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
interface ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* Report or log an exception.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function report(Exception $e);
|
||||
public function report(Throwable $e);
|
||||
|
||||
/**
|
||||
* Determine if the exception should be reported.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldReport(Exception $e);
|
||||
public function shouldReport(Throwable $e);
|
||||
|
||||
/**
|
||||
* Render an exception into an HTTP response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function render($request, Exception $e);
|
||||
public function render($request, Throwable $e);
|
||||
|
||||
/**
|
||||
* Render an exception to the console.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @return void
|
||||
*/
|
||||
public function renderForConsole($output, Exception $e);
|
||||
public function renderForConsole($output, Throwable $e);
|
||||
}
|
||||
|
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Illuminate\Contracts\Foundation;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
|
||||
interface Application extends Container
|
||||
@@ -25,7 +24,7 @@ interface Application extends Container
|
||||
/**
|
||||
* Get the path to the bootstrap directory.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path Optionally, a path to append to the bootstrap path
|
||||
* @return string
|
||||
*/
|
||||
public function bootstrapPath($path = '');
|
||||
@@ -33,7 +32,7 @@ interface Application extends Container
|
||||
/**
|
||||
* Get the path to the application configuration files.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path Optionally, a path to append to the config path
|
||||
* @return string
|
||||
*/
|
||||
public function configPath($path = '');
|
||||
@@ -41,18 +40,11 @@ interface Application extends Container
|
||||
/**
|
||||
* Get the path to the database directory.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path Optionally, a path to append to the database path
|
||||
* @return string
|
||||
*/
|
||||
public function databasePath($path = '');
|
||||
|
||||
/**
|
||||
* Get the path to the environment file directory.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function environmentPath();
|
||||
|
||||
/**
|
||||
* Get the path to the resources directory.
|
||||
*
|
||||
@@ -161,63 +153,6 @@ interface Application extends Container
|
||||
*/
|
||||
public function bootstrapWith(array $bootstrappers);
|
||||
|
||||
/**
|
||||
* Determine if the application configuration is cached.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationIsCached();
|
||||
|
||||
/**
|
||||
* Detect the application's current environment.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return string
|
||||
*/
|
||||
public function detectEnvironment(Closure $callback);
|
||||
|
||||
/**
|
||||
* Get the environment file the application is using.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function environmentFile();
|
||||
|
||||
/**
|
||||
* Get the fully qualified path to the environment file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function environmentFilePath();
|
||||
|
||||
/**
|
||||
* Get the path to the configuration cache file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCachedConfigPath();
|
||||
|
||||
/**
|
||||
* Get the path to the cached services.php file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCachedServicesPath();
|
||||
|
||||
/**
|
||||
* Get the path to the cached packages.php file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCachedPackagesPath();
|
||||
|
||||
/**
|
||||
* Get the path to the routes cache file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCachedRoutesPath();
|
||||
|
||||
/**
|
||||
* Get the current application locale.
|
||||
*
|
||||
@@ -256,21 +191,6 @@ interface Application extends Container
|
||||
*/
|
||||
public function loadDeferredProviders();
|
||||
|
||||
/**
|
||||
* Set the environment file to be loaded during bootstrapping.
|
||||
*
|
||||
* @param string $file
|
||||
* @return $this
|
||||
*/
|
||||
public function loadEnvironmentFrom($file);
|
||||
|
||||
/**
|
||||
* Determine if the application routes are cached.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function routesAreCached();
|
||||
|
||||
/**
|
||||
* Set the current application locale.
|
||||
*
|
||||
|
27
vendor/laravel/framework/src/Illuminate/Contracts/Foundation/CachesConfiguration.php
vendored
Normal file
27
vendor/laravel/framework/src/Illuminate/Contracts/Foundation/CachesConfiguration.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Foundation;
|
||||
|
||||
interface CachesConfiguration
|
||||
{
|
||||
/**
|
||||
* Determine if the application configuration is cached.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationIsCached();
|
||||
|
||||
/**
|
||||
* Get the path to the configuration cache file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCachedConfigPath();
|
||||
|
||||
/**
|
||||
* Get the path to the cached services.php file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCachedServicesPath();
|
||||
}
|
20
vendor/laravel/framework/src/Illuminate/Contracts/Foundation/CachesRoutes.php
vendored
Normal file
20
vendor/laravel/framework/src/Illuminate/Contracts/Foundation/CachesRoutes.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Foundation;
|
||||
|
||||
interface CachesRoutes
|
||||
{
|
||||
/**
|
||||
* Determine if the application routes are cached.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function routesAreCached();
|
||||
|
||||
/**
|
||||
* Get the path to the routes cache file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCachedRoutesPath();
|
||||
}
|
14
vendor/laravel/framework/src/Illuminate/Contracts/Mail/Factory.php
vendored
Normal file
14
vendor/laravel/framework/src/Illuminate/Contracts/Mail/Factory.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Mail;
|
||||
|
||||
interface Factory
|
||||
{
|
||||
/**
|
||||
* Get a mailer instance by name.
|
||||
*
|
||||
* @param string|null $name
|
||||
* @return \Illuminate\Mail\Mailer
|
||||
*/
|
||||
public function mailer($name = null);
|
||||
}
|
@@ -9,10 +9,10 @@ interface Mailable
|
||||
/**
|
||||
* Send the message using the given mailer.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Mail\Mailer $mailer
|
||||
* @param \Illuminate\Contracts\Mail\Factory|\Illuminate\Contracts\Mail\Mailer $mailer
|
||||
* @return void
|
||||
*/
|
||||
public function send(Mailer $mailer);
|
||||
public function send($mailer);
|
||||
|
||||
/**
|
||||
* Queue the given message.
|
||||
@@ -30,4 +30,47 @@ interface Mailable
|
||||
* @return mixed
|
||||
*/
|
||||
public function later($delay, Queue $queue);
|
||||
|
||||
/**
|
||||
* Set the recipients of the message.
|
||||
*
|
||||
* @param object|array|string $address
|
||||
* @param string|null $name
|
||||
* @return self
|
||||
*/
|
||||
public function cc($address, $name = null);
|
||||
|
||||
/**
|
||||
* Set the recipients of the message.
|
||||
*
|
||||
* @param object|array|string $address
|
||||
* @param string|null $name
|
||||
* @return $this
|
||||
*/
|
||||
public function bcc($address, $name = null);
|
||||
|
||||
/**
|
||||
* Set the recipients of the message.
|
||||
*
|
||||
* @param object|array|string $address
|
||||
* @param string|null $name
|
||||
* @return $this
|
||||
*/
|
||||
public function to($address, $name = null);
|
||||
|
||||
/**
|
||||
* Set the locale of the message.
|
||||
*
|
||||
* @param string $locale
|
||||
* @return $this
|
||||
*/
|
||||
public function locale($locale);
|
||||
|
||||
/**
|
||||
* Set the name of the mailer that should be used to send the message.
|
||||
*
|
||||
* @param string $mailer
|
||||
* @return $this
|
||||
*/
|
||||
public function mailer($mailer);
|
||||
}
|
||||
|
@@ -4,6 +4,13 @@ namespace Illuminate\Contracts\Queue;
|
||||
|
||||
interface Job
|
||||
{
|
||||
/**
|
||||
* Get the UUID of the job.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function uuid();
|
||||
|
||||
/**
|
||||
* Get the job identifier.
|
||||
*
|
||||
@@ -99,6 +106,13 @@ interface Job
|
||||
*/
|
||||
public function maxTries();
|
||||
|
||||
/**
|
||||
* Get the maximum number of exceptions allowed, regardless of attempts.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function maxExceptions();
|
||||
|
||||
/**
|
||||
* Get the number of seconds the job can run.
|
||||
*
|
||||
|
@@ -77,7 +77,7 @@ interface Queue
|
||||
/**
|
||||
* Pop the next job off of the queue.
|
||||
*
|
||||
* @param string $queue
|
||||
* @param string|null $queue
|
||||
* @return \Illuminate\Contracts\Queue\Job|null
|
||||
*/
|
||||
public function pop($queue = null);
|
||||
|
@@ -8,7 +8,7 @@ interface Registrar
|
||||
* Register a new GET route with the router.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param \Closure|array|string|callable $action
|
||||
* @param array|string|callable $action
|
||||
* @return \Illuminate\Routing\Route
|
||||
*/
|
||||
public function get($uri, $action);
|
||||
@@ -17,7 +17,7 @@ interface Registrar
|
||||
* Register a new POST route with the router.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param \Closure|array|string|callable $action
|
||||
* @param array|string|callable $action
|
||||
* @return \Illuminate\Routing\Route
|
||||
*/
|
||||
public function post($uri, $action);
|
||||
@@ -26,7 +26,7 @@ interface Registrar
|
||||
* Register a new PUT route with the router.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param \Closure|array|string|callable $action
|
||||
* @param array|string|callable $action
|
||||
* @return \Illuminate\Routing\Route
|
||||
*/
|
||||
public function put($uri, $action);
|
||||
@@ -35,7 +35,7 @@ interface Registrar
|
||||
* Register a new DELETE route with the router.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param \Closure|array|string|callable $action
|
||||
* @param array|string|callable $action
|
||||
* @return \Illuminate\Routing\Route
|
||||
*/
|
||||
public function delete($uri, $action);
|
||||
@@ -44,7 +44,7 @@ interface Registrar
|
||||
* Register a new PATCH route with the router.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param \Closure|array|string|callable $action
|
||||
* @param array|string|callable $action
|
||||
* @return \Illuminate\Routing\Route
|
||||
*/
|
||||
public function patch($uri, $action);
|
||||
@@ -53,7 +53,7 @@ interface Registrar
|
||||
* Register a new OPTIONS route with the router.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param \Closure|array|string|callable $action
|
||||
* @param array|string|callable $action
|
||||
* @return \Illuminate\Routing\Route
|
||||
*/
|
||||
public function options($uri, $action);
|
||||
@@ -63,7 +63,7 @@ interface Registrar
|
||||
*
|
||||
* @param array|string $methods
|
||||
* @param string $uri
|
||||
* @param \Closure|array|string|callable $action
|
||||
* @param array|string|callable $action
|
||||
* @return \Illuminate\Routing\Route
|
||||
*/
|
||||
public function match($methods, $uri, $action);
|
||||
|
@@ -37,7 +37,7 @@ interface ResponseFactory
|
||||
/**
|
||||
* Create a new JSON response instance.
|
||||
*
|
||||
* @param string|array|object $data
|
||||
* @param mixed $data
|
||||
* @param int $status
|
||||
* @param array $headers
|
||||
* @param int $options
|
||||
@@ -49,7 +49,7 @@ interface ResponseFactory
|
||||
* Create a new JSONP response instance.
|
||||
*
|
||||
* @param string $callback
|
||||
* @param string|array|object $data
|
||||
* @param mixed $data
|
||||
* @param int $status
|
||||
* @param array $headers
|
||||
* @param int $options
|
||||
@@ -113,7 +113,7 @@ interface ResponseFactory
|
||||
* Create a new redirect response to a named route.
|
||||
*
|
||||
* @param string $route
|
||||
* @param array $parameters
|
||||
* @param mixed $parameters
|
||||
* @param int $status
|
||||
* @param array $headers
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
@@ -124,7 +124,7 @@ interface ResponseFactory
|
||||
* Create a new redirect response to a controller action.
|
||||
*
|
||||
* @param string $action
|
||||
* @param array $parameters
|
||||
* @param mixed $parameters
|
||||
* @param int $status
|
||||
* @param array $headers
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
|
@@ -22,7 +22,18 @@ interface UrlRoutable
|
||||
* Retrieve the model for a bound value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string|null $field
|
||||
* @return \Illuminate\Database\Eloquent\Model|null
|
||||
*/
|
||||
public function resolveRouteBinding($value);
|
||||
public function resolveRouteBinding($value, $field = null);
|
||||
|
||||
/**
|
||||
* Retrieve the child model for a bound value.
|
||||
*
|
||||
* @param string $childType
|
||||
* @param mixed $value
|
||||
* @param string|null $field
|
||||
* @return \Illuminate\Database\Eloquent\Model|null
|
||||
*/
|
||||
public function resolveChildRouteBinding($childType, $value, $field);
|
||||
}
|
||||
|
13
vendor/laravel/framework/src/Illuminate/Contracts/Support/DeferringDisplayableValue.php
vendored
Normal file
13
vendor/laravel/framework/src/Illuminate/Contracts/Support/DeferringDisplayableValue.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Support;
|
||||
|
||||
interface DeferringDisplayableValue
|
||||
{
|
||||
/**
|
||||
* Resolve the displayable value that the class is deferring.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Support\Htmlable|string
|
||||
*/
|
||||
public function resolveDisplayableValue();
|
||||
}
|
@@ -10,6 +10,8 @@ interface Validator extends MessageProvider
|
||||
* Run the validator's rules against its data.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function validate();
|
||||
|
||||
@@ -17,6 +19,8 @@ interface Validator extends MessageProvider
|
||||
* Get the attributes and values that were validated.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function validated();
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.x-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@@ -27,18 +27,18 @@ class CookieJar implements JarContract
|
||||
protected $domain;
|
||||
|
||||
/**
|
||||
* The default secure setting (defaults to false).
|
||||
* The default secure setting (defaults to null).
|
||||
*
|
||||
* @var bool
|
||||
* @var bool|null
|
||||
*/
|
||||
protected $secure = false;
|
||||
protected $secure;
|
||||
|
||||
/**
|
||||
* The default SameSite option (if specified).
|
||||
* The default SameSite option (defaults to lax).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sameSite;
|
||||
protected $sameSite = 'lax';
|
||||
|
||||
/**
|
||||
* All of the cookies queued for sending.
|
||||
@@ -119,7 +119,7 @@ class CookieJar implements JarContract
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @param string|null $path
|
||||
* @return \Symfony\Component\HttpFoundation\Cookie
|
||||
* @return \Symfony\Component\HttpFoundation\Cookie|null
|
||||
*/
|
||||
public function queued($key, $default = null, $path = null)
|
||||
{
|
||||
@@ -140,8 +140,8 @@ class CookieJar implements JarContract
|
||||
*/
|
||||
public function queue(...$parameters)
|
||||
{
|
||||
if (head($parameters) instanceof Cookie) {
|
||||
$cookie = head($parameters);
|
||||
if (isset($parameters[0]) && $parameters[0] instanceof Cookie) {
|
||||
$cookie = $parameters[0];
|
||||
} else {
|
||||
$cookie = $this->make(...array_values($parameters));
|
||||
}
|
||||
|
@@ -15,10 +15,10 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5|^8.0",
|
||||
"illuminate/contracts": "^6.0",
|
||||
"illuminate/support": "^6.0",
|
||||
"symfony/http-foundation": "^4.3.4",
|
||||
"symfony/http-kernel": "^4.3.4"
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/support": "^7.0",
|
||||
"symfony/http-foundation": "^5.0",
|
||||
"symfony/http-kernel": "^5.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -27,7 +27,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.x-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@@ -113,7 +113,7 @@ trait BuildsQueries
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback over each item while chunking by id.
|
||||
* Execute a callback over each item while chunking by ID.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param int $count
|
||||
|
@@ -3,7 +3,6 @@
|
||||
namespace Illuminate\Database\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
trait ManagesTransactions
|
||||
@@ -15,7 +14,7 @@ trait ManagesTransactions
|
||||
* @param int $attempts
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Exception|\Throwable
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function transaction(Closure $callback, $attempts = 1)
|
||||
{
|
||||
@@ -32,16 +31,12 @@ trait ManagesTransactions
|
||||
// If we catch an exception we'll rollback this transaction and try again if we
|
||||
// are not out of attempts. If we are out of attempts we will just throw the
|
||||
// exception back out and let the developer handle an uncaught exceptions.
|
||||
catch (Exception $e) {
|
||||
catch (Throwable $e) {
|
||||
$this->handleTransactionException(
|
||||
$e, $currentAttempt, $attempts
|
||||
);
|
||||
|
||||
continue;
|
||||
} catch (Throwable $e) {
|
||||
$this->rollBack();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -50,9 +45,7 @@ trait ManagesTransactions
|
||||
}
|
||||
|
||||
$this->transactions = max(0, $this->transactions - 1);
|
||||
} catch (Exception $e) {
|
||||
$commitFailed = true;
|
||||
|
||||
} catch (Throwable $e) {
|
||||
$this->handleCommitTransactionException(
|
||||
$e, $currentAttempt, $attempts
|
||||
);
|
||||
@@ -60,9 +53,7 @@ trait ManagesTransactions
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! isset($commitFailed)) {
|
||||
$this->fireConnectionEvent('committed');
|
||||
}
|
||||
$this->fireConnectionEvent('committed');
|
||||
|
||||
return $callbackResult;
|
||||
}
|
||||
@@ -71,14 +62,14 @@ trait ManagesTransactions
|
||||
/**
|
||||
* Handle an exception encountered when running a transacted statement.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @param int $currentAttempt
|
||||
* @param int $maxAttempts
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function handleTransactionException($e, $currentAttempt, $maxAttempts)
|
||||
protected function handleTransactionException(Throwable $e, $currentAttempt, $maxAttempts)
|
||||
{
|
||||
// On a deadlock, MySQL rolls back the entire transaction so we can't just
|
||||
// retry the query. We have to throw this exception all the way out and
|
||||
@@ -108,7 +99,7 @@ trait ManagesTransactions
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
@@ -123,6 +114,8 @@ trait ManagesTransactions
|
||||
* Create a transaction within the database.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function createTransaction()
|
||||
{
|
||||
@@ -131,7 +124,7 @@ trait ManagesTransactions
|
||||
|
||||
try {
|
||||
$this->getPdo()->beginTransaction();
|
||||
} catch (Exception $e) {
|
||||
} catch (Throwable $e) {
|
||||
$this->handleBeginTransactionException($e);
|
||||
}
|
||||
} elseif ($this->transactions >= 1 && $this->queryGrammar->supportsSavepoints()) {
|
||||
@@ -143,6 +136,8 @@ trait ManagesTransactions
|
||||
* Create a save point within the database.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function createSavepoint()
|
||||
{
|
||||
@@ -157,9 +152,9 @@ trait ManagesTransactions
|
||||
* @param \Throwable $e
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function handleBeginTransactionException($e)
|
||||
protected function handleBeginTransactionException(Throwable $e)
|
||||
{
|
||||
if ($this->causedByLostConnection($e)) {
|
||||
$this->reconnect();
|
||||
@@ -174,6 +169,8 @@ trait ManagesTransactions
|
||||
* Commit the active database transaction.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
@@ -189,12 +186,14 @@ trait ManagesTransactions
|
||||
/**
|
||||
* Handle an exception encountered when committing a transaction.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @param int $currentAttempt
|
||||
* @param int $maxAttempts
|
||||
* @return void
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function handleCommitTransactionException($e, $currentAttempt, $maxAttempts)
|
||||
protected function handleCommitTransactionException(Throwable $e, $currentAttempt, $maxAttempts)
|
||||
{
|
||||
$this->transactions = max(0, $this->transactions - 1);
|
||||
|
||||
@@ -216,7 +215,7 @@ trait ManagesTransactions
|
||||
* @param int|null $toLevel
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function rollBack($toLevel = null)
|
||||
{
|
||||
@@ -236,7 +235,7 @@ trait ManagesTransactions
|
||||
// level that was passed into this method so it will be right from here out.
|
||||
try {
|
||||
$this->performRollBack($toLevel);
|
||||
} catch (Exception $e) {
|
||||
} catch (Throwable $e) {
|
||||
$this->handleRollBackException($e);
|
||||
}
|
||||
|
||||
@@ -250,6 +249,8 @@ trait ManagesTransactions
|
||||
*
|
||||
* @param int $toLevel
|
||||
* @return void
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function performRollBack($toLevel)
|
||||
{
|
||||
@@ -265,12 +266,12 @@ trait ManagesTransactions
|
||||
/**
|
||||
* Handle an exception from a rollback.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function handleRollBackException($e)
|
||||
protected function handleRollBackException(Throwable $e)
|
||||
{
|
||||
if ($this->causedByLostConnection($e)) {
|
||||
$this->transactions = 0;
|
||||
|
@@ -327,8 +327,9 @@ class Connection implements ConnectionInterface
|
||||
// For select statements, we'll simply execute the query and return an array
|
||||
// of the database result set. Each element in the array will be a single
|
||||
// row from the database table, and will either be an array or objects.
|
||||
$statement = $this->prepared($this->getPdoForSelect($useReadPdo)
|
||||
->prepare($query));
|
||||
$statement = $this->prepared(
|
||||
$this->getPdoForSelect($useReadPdo)->prepare($query)
|
||||
);
|
||||
|
||||
$this->bindValues($statement, $this->prepareBindings($bindings));
|
||||
|
||||
@@ -576,7 +577,8 @@ class Connection implements ConnectionInterface
|
||||
{
|
||||
foreach ($bindings as $key => $value) {
|
||||
$statement->bindValue(
|
||||
is_string($key) ? $key : $key + 1, $value,
|
||||
is_string($key) ? $key : $key + 1,
|
||||
$value,
|
||||
is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR
|
||||
);
|
||||
}
|
||||
|
@@ -78,7 +78,7 @@ class ConnectionFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a single database connection instance.
|
||||
* Create a read / write database connection instance.
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Illuminate\Database\Connection
|
||||
@@ -115,7 +115,7 @@ class ConnectionFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the read configuration for a read / write connection.
|
||||
* Get the write configuration for a read / write connection.
|
||||
*
|
||||
* @param array $config
|
||||
* @return array
|
||||
@@ -171,6 +171,8 @@ class ConnectionFactory
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Closure
|
||||
*
|
||||
* @throws \PDOException
|
||||
*/
|
||||
protected function createPdoResolverWithHosts(array $config)
|
||||
{
|
||||
@@ -250,7 +252,7 @@ class ConnectionFactory
|
||||
return new SqlServerConnector;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]");
|
||||
throw new InvalidArgumentException("Unsupported driver [{$config['driver']}].");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,6 +284,6 @@ class ConnectionFactory
|
||||
return new SqlServerConnection($connection, $database, $prefix, $config);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Unsupported driver [{$driver}]");
|
||||
throw new InvalidArgumentException("Unsupported driver [{$driver}].");
|
||||
}
|
||||
}
|
||||
|
@@ -27,6 +27,8 @@ class MySqlConnector extends Connector implements ConnectorInterface
|
||||
$connection->exec("use `{$config['database']}`;");
|
||||
}
|
||||
|
||||
$this->configureIsolationLevel($connection, $config);
|
||||
|
||||
$this->configureEncoding($connection, $config);
|
||||
|
||||
// Next, we will check to see if a timezone has been specified in this config
|
||||
@@ -40,12 +42,30 @@ class MySqlConnector extends Connector implements ConnectorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection character set and collation.
|
||||
* Set the connection transaction isolation level.
|
||||
*
|
||||
* @param \PDO $connection
|
||||
* @param array $config
|
||||
* @return void
|
||||
*/
|
||||
protected function configureIsolationLevel($connection, array $config)
|
||||
{
|
||||
if (! isset($config['isolation_level'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$connection->prepare(
|
||||
"SET SESSION TRANSACTION ISOLATION LEVEL {$config['isolation_level']}"
|
||||
)->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection character set and collation.
|
||||
*
|
||||
* @param \PDO $connection
|
||||
* @param array $config
|
||||
* @return void|\PDO
|
||||
*/
|
||||
protected function configureEncoding($connection, array $config)
|
||||
{
|
||||
if (! isset($config['charset'])) {
|
||||
@@ -147,7 +167,7 @@ class MySqlConnector extends Connector implements ConnectorInterface
|
||||
$this->setCustomModes($connection, $config);
|
||||
} elseif (isset($config['strict'])) {
|
||||
if ($config['strict']) {
|
||||
$connection->prepare($this->strictMode($connection))->execute();
|
||||
$connection->prepare($this->strictMode($connection, $config))->execute();
|
||||
} else {
|
||||
$connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();
|
||||
}
|
||||
@@ -172,11 +192,14 @@ class MySqlConnector extends Connector implements ConnectorInterface
|
||||
* Get the query to enable strict mode.
|
||||
*
|
||||
* @param \PDO $connection
|
||||
* @param array $config
|
||||
* @return string
|
||||
*/
|
||||
protected function strictMode(PDO $connection)
|
||||
protected function strictMode(PDO $connection, $config)
|
||||
{
|
||||
if (version_compare($connection->getAttribute(PDO::ATTR_SERVER_VERSION), '8.0.11') >= 0) {
|
||||
$version = $config['version'] ?? $connection->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
|
||||
if (version_compare($version, '8.0.11') >= 0) {
|
||||
return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
|
||||
}
|
||||
|
||||
|
@@ -47,6 +47,8 @@ class PostgresConnector extends Connector implements ConnectorInterface
|
||||
// determine if the option has been specified and run a statement if so.
|
||||
$this->configureApplicationName($connection, $config);
|
||||
|
||||
$this->configureSynchronousCommit($connection, $config);
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
@@ -173,4 +175,20 @@ class PostgresConnector extends Connector implements ConnectorInterface
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the synchronous_commit setting.
|
||||
*
|
||||
* @param \PDO $connection
|
||||
* @param array $config
|
||||
* @return void
|
||||
*/
|
||||
protected function configureSynchronousCommit($connection, array $config)
|
||||
{
|
||||
if (! isset($config['synchronous_commit'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$connection->prepare("set synchronous_commit to '{$config['synchronous_commit']}'")->execute();
|
||||
}
|
||||
}
|
||||
|
@@ -156,6 +156,10 @@ class SqlServerConnector extends Connector implements ConnectorInterface
|
||||
$arguments['KeyStoreSecret'] = $config['key_store_secret'];
|
||||
}
|
||||
|
||||
if (isset($config['login_timeout'])) {
|
||||
$arguments['LoginTimeout'] = $config['login_timeout'];
|
||||
}
|
||||
|
||||
return $this->buildConnectString('sqlsrv', $arguments);
|
||||
}
|
||||
|
||||
|
@@ -35,7 +35,20 @@ class FactoryMakeCommand extends GeneratorCommand
|
||||
*/
|
||||
protected function getStub()
|
||||
{
|
||||
return __DIR__.'/stubs/factory.stub';
|
||||
return $this->resolveStubPath('/stubs/factory.stub');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the fully-qualified path to the stub.
|
||||
*
|
||||
* @param string $stub
|
||||
* @return string
|
||||
*/
|
||||
protected function resolveStubPath($stub)
|
||||
{
|
||||
return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))
|
||||
? $customPath
|
||||
: __DIR__.$stub;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,16 +65,17 @@ class FactoryMakeCommand extends GeneratorCommand
|
||||
|
||||
$model = class_basename($namespaceModel);
|
||||
|
||||
$replace = [
|
||||
'NamespacedDummyModel' => $namespaceModel,
|
||||
'{{ namespacedModel }}' => $namespaceModel,
|
||||
'{{namespacedModel}}' => $namespaceModel,
|
||||
'DummyModel' => $model,
|
||||
'{{ model }}' => $model,
|
||||
'{{model}}' => $model,
|
||||
];
|
||||
|
||||
return str_replace(
|
||||
[
|
||||
'NamespacedDummyModel',
|
||||
'DummyModel',
|
||||
],
|
||||
[
|
||||
$namespaceModel,
|
||||
$model,
|
||||
],
|
||||
parent::buildClass($name)
|
||||
array_keys($replace), array_values($replace), parent::buildClass($name)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -3,9 +3,9 @@
|
||||
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
||||
|
||||
use Faker\Generator as Faker;
|
||||
use NamespacedDummyModel;
|
||||
use {{ namespacedModel }};
|
||||
|
||||
$factory->define(DummyModel::class, function (Faker $faker) {
|
||||
$factory->define({{ model }}::class, function (Faker $faker) {
|
||||
return [
|
||||
//
|
||||
];
|
||||
|
@@ -27,12 +27,12 @@ class FreshCommand extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
$database = $this->input->getOption('database');
|
||||
@@ -55,6 +55,8 @@ class FreshCommand extends Command
|
||||
if ($this->needsSeeding()) {
|
||||
$this->runSeeder($database);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -52,31 +52,35 @@ class MigrateCommand extends BaseCommand
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->prepareDatabase();
|
||||
$this->migrator->usingConnection($this->option('database'), function () {
|
||||
$this->prepareDatabase();
|
||||
|
||||
// Next, we will check to see if a path option has been defined. If it has
|
||||
// we will use the path relative to the root of this installation folder
|
||||
// so that migrations may be run for any path within the applications.
|
||||
$this->migrator->setOutput($this->output)
|
||||
->run($this->getMigrationPaths(), [
|
||||
'pretend' => $this->option('pretend'),
|
||||
'step' => $this->option('step'),
|
||||
]);
|
||||
// Next, we will check to see if a path option has been defined. If it has
|
||||
// we will use the path relative to the root of this installation folder
|
||||
// so that migrations may be run for any path within the applications.
|
||||
$this->migrator->setOutput($this->output)
|
||||
->run($this->getMigrationPaths(), [
|
||||
'pretend' => $this->option('pretend'),
|
||||
'step' => $this->option('step'),
|
||||
]);
|
||||
|
||||
// Finally, if the "seed" option has been given, we will re-run the database
|
||||
// seed task to re-populate the database, which is convenient when adding
|
||||
// a migration and a seed at the same time, as it is only this command.
|
||||
if ($this->option('seed') && ! $this->option('pretend')) {
|
||||
$this->call('db:seed', ['--force' => true]);
|
||||
}
|
||||
// Finally, if the "seed" option has been given, we will re-run the database
|
||||
// seed task to re-populate the database, which is convenient when adding
|
||||
// a migration and a seed at the same time, as it is only this command.
|
||||
if ($this->option('seed') && ! $this->option('pretend')) {
|
||||
$this->call('db:seed', ['--force' => true]);
|
||||
}
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,8 +90,6 @@ class MigrateCommand extends BaseCommand
|
||||
*/
|
||||
protected function prepareDatabase()
|
||||
{
|
||||
$this->migrator->setConnection($this->option('database'));
|
||||
|
||||
if (! $this->migrator->repositoryExists()) {
|
||||
$this->call('migrate:install', array_filter([
|
||||
'--database' => $this->option('database'),
|
||||
|
@@ -27,12 +27,12 @@ class RefreshCommand extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Next we'll gather some of the options so that we can have the right options
|
||||
@@ -66,6 +66,8 @@ class RefreshCommand extends Command
|
||||
if ($this->needsSeeding()) {
|
||||
$this->runSeeder($database);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -47,26 +47,28 @@ class ResetCommand extends BaseCommand
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->migrator->setConnection($this->option('database'));
|
||||
return $this->migrator->usingConnection($this->option('database'), function () {
|
||||
// First, we'll make sure that the migration table actually exists before we
|
||||
// start trying to rollback and re-run all of the migrations. If it's not
|
||||
// present we'll just bail out with an info message for the developers.
|
||||
if (! $this->migrator->repositoryExists()) {
|
||||
return $this->comment('Migration table not found.');
|
||||
}
|
||||
|
||||
// First, we'll make sure that the migration table actually exists before we
|
||||
// start trying to rollback and re-run all of the migrations. If it's not
|
||||
// present we'll just bail out with an info message for the developers.
|
||||
if (! $this->migrator->repositoryExists()) {
|
||||
return $this->comment('Migration table not found.');
|
||||
}
|
||||
$this->migrator->setOutput($this->output)->reset(
|
||||
$this->getMigrationPaths(), $this->option('pretend')
|
||||
);
|
||||
});
|
||||
|
||||
$this->migrator->setOutput($this->output)->reset(
|
||||
$this->getMigrationPaths(), $this->option('pretend')
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -47,22 +47,24 @@ class RollbackCommand extends BaseCommand
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->migrator->setConnection($this->option('database'));
|
||||
$this->migrator->usingConnection($this->option('database'), function () {
|
||||
$this->migrator->setOutput($this->output)->rollback(
|
||||
$this->getMigrationPaths(), [
|
||||
'pretend' => $this->option('pretend'),
|
||||
'step' => (int) $this->option('step'),
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
$this->migrator->setOutput($this->output)->rollback(
|
||||
$this->getMigrationPaths(), [
|
||||
'pretend' => $this->option('pretend'),
|
||||
'step' => (int) $this->option('step'),
|
||||
]
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -45,27 +45,27 @@ class StatusCommand extends BaseCommand
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @return int|null
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->migrator->setConnection($this->option('database'));
|
||||
return $this->migrator->usingConnection($this->option('database'), function () {
|
||||
if (! $this->migrator->repositoryExists()) {
|
||||
$this->error('Migration table not found.');
|
||||
|
||||
if (! $this->migrator->repositoryExists()) {
|
||||
$this->error('Migration table not found.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
$ran = $this->migrator->getRepository()->getRan();
|
||||
|
||||
$ran = $this->migrator->getRepository()->getRan();
|
||||
$batches = $this->migrator->getRepository()->getMigrationBatches();
|
||||
|
||||
$batches = $this->migrator->getRepository()->getMigrationBatches();
|
||||
|
||||
if (count($migrations = $this->getStatusFor($ran, $batches)) > 0) {
|
||||
$this->table(['Ran?', 'Migration', 'Batch'], $migrations);
|
||||
} else {
|
||||
$this->error('No migrations found');
|
||||
}
|
||||
if (count($migrations = $this->getStatusFor($ran, $batches)) > 0) {
|
||||
$this->table(['Ran?', 'Migration', 'Batch'], $migrations);
|
||||
} else {
|
||||
$this->error('No migrations found');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -49,21 +49,29 @@ class SeedCommand extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
$previousConnection = $this->resolver->getDefaultConnection();
|
||||
|
||||
$this->resolver->setDefaultConnection($this->getDatabase());
|
||||
|
||||
Model::unguarded(function () {
|
||||
$this->getSeeder()->__invoke();
|
||||
});
|
||||
|
||||
if ($previousConnection) {
|
||||
$this->resolver->setDefaultConnection($previousConnection);
|
||||
}
|
||||
|
||||
$this->info('Database seeding completed successfully.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -69,7 +69,20 @@ class SeederMakeCommand extends GeneratorCommand
|
||||
*/
|
||||
protected function getStub()
|
||||
{
|
||||
return __DIR__.'/stubs/seeder.stub';
|
||||
return $this->resolveStubPath('/stubs/seeder.stub');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the fully-qualified path to the stub.
|
||||
*
|
||||
* @param string $stub
|
||||
* @return string
|
||||
*/
|
||||
protected function resolveStubPath($stub)
|
||||
{
|
||||
return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))
|
||||
? $customPath
|
||||
: __DIR__.$stub;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DummyClass extends Seeder
|
||||
class {{ class }} extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
|
@@ -27,12 +27,12 @@ class WipeCommand extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
$database = $this->input->getOption('database');
|
||||
@@ -52,6 +52,8 @@ class WipeCommand extends Command
|
||||
|
||||
$this->info('Dropped all types successfully.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -245,6 +245,24 @@ class DatabaseManager implements ConnectionResolverInterface
|
||||
return $this->refreshPdoConnections($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default database connection for the callback execution.
|
||||
*
|
||||
* @param string $name
|
||||
* @param callable $callback
|
||||
* @return mixed
|
||||
*/
|
||||
public function usingConnection($name, callable $callback)
|
||||
{
|
||||
$previousName = $this->getDefaultConnection();
|
||||
|
||||
$this->setDefaultConnection($name);
|
||||
|
||||
return tap($callback(), function () use ($previousName) {
|
||||
$this->setDefaultConnection($previousName);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the PDO connections on a given connection.
|
||||
*
|
||||
|
@@ -2,19 +2,19 @@
|
||||
|
||||
namespace Illuminate\Database;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Support\Str;
|
||||
use PDOException;
|
||||
use Throwable;
|
||||
|
||||
trait DetectsConcurrencyErrors
|
||||
{
|
||||
/**
|
||||
* Determine if the given exception was caused by a concurrency error such as a deadlock or serialization failure.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @return bool
|
||||
*/
|
||||
protected function causedByConcurrencyError(Exception $e)
|
||||
protected function causedByConcurrencyError(Throwable $e)
|
||||
{
|
||||
if ($e instanceof PDOException && $e->getCode() === '40001') {
|
||||
return true;
|
||||
|
@@ -50,13 +50,6 @@ trait DetectsLostConnections
|
||||
'SSL: Connection timed out',
|
||||
'SQLSTATE[HY000]: General error: 1105 The last transaction was aborted due to Seamless Scaling. Please retry.',
|
||||
'Temporary failure in name resolution',
|
||||
'SSL: Broken pipe',
|
||||
'SQLSTATE[08S01]: Communication link failure',
|
||||
'SQLSTATE[08006] [7] could not connect to server: Connection refused Is the server running on host',
|
||||
'SQLSTATE[HY000]: General error: 7 SSL SYSCALL error: No route to host',
|
||||
'The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior.',
|
||||
'SQLSTATE[08006] [7] could not translate host name',
|
||||
'TCP Provider: Error code 0x274C',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@@ -75,7 +75,7 @@ class Builder
|
||||
*/
|
||||
protected $passthru = [
|
||||
'insert', 'insertOrIgnore', 'insertGetId', 'insertUsing', 'getBindings', 'toSql', 'dump', 'dd',
|
||||
'exists', 'doesntExist', 'count', 'min', 'max', 'avg', 'average', 'sum', 'getConnection',
|
||||
'exists', 'doesntExist', 'count', 'min', 'max', 'avg', 'average', 'sum', 'getConnection', 'raw', 'getGrammar',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -233,7 +233,7 @@ class Builder
|
||||
*/
|
||||
public function where($column, $operator = null, $value = null, $boolean = 'and')
|
||||
{
|
||||
if ($column instanceof Closure) {
|
||||
if ($column instanceof Closure && is_null($operator)) {
|
||||
$column($query = $this->model->newQueryWithoutRelationships());
|
||||
|
||||
$this->query->addNestedWhereQuery($query->getQuery(), $boolean);
|
||||
@@ -264,7 +264,7 @@ class Builder
|
||||
* @param \Closure|array|string|\Illuminate\Database\Query\Expression $column
|
||||
* @param mixed $operator
|
||||
* @param mixed $value
|
||||
* @return \Illuminate\Database\Eloquent\Builder|static
|
||||
* @return $this
|
||||
*/
|
||||
public function orWhere($column, $operator = null, $value = null)
|
||||
{
|
||||
@@ -385,6 +385,8 @@ class Builder
|
||||
{
|
||||
$result = $this->find($id, $columns);
|
||||
|
||||
$id = $id instanceof Arrayable ? $id->toArray() : $id;
|
||||
|
||||
if (is_array($id)) {
|
||||
if (count($result) === count(array_unique($id))) {
|
||||
return $result;
|
||||
@@ -421,7 +423,7 @@ class Builder
|
||||
* @param array $values
|
||||
* @return \Illuminate\Database\Eloquent\Model|static
|
||||
*/
|
||||
public function firstOrNew(array $attributes, array $values = [])
|
||||
public function firstOrNew(array $attributes = [], array $values = [])
|
||||
{
|
||||
if (! is_null($instance = $this->where($attributes)->first())) {
|
||||
return $instance;
|
||||
@@ -897,6 +899,17 @@ class Builder
|
||||
$this->onDelete = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given model has a scope.
|
||||
*
|
||||
* @param string $scope
|
||||
* @return bool
|
||||
*/
|
||||
public function hasNamedScope($scope)
|
||||
{
|
||||
return $this->model && $this->model->hasNamedScope($scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the given local model scopes.
|
||||
*
|
||||
@@ -918,10 +931,7 @@ class Builder
|
||||
// Next we'll pass the scope callback to the callScope method which will take
|
||||
// care of grouping the "wheres" properly so the logical order doesn't get
|
||||
// messed up when adding scopes. Then we'll return back out the builder.
|
||||
$builder = $builder->callScope(
|
||||
[$this->model, 'scope'.ucfirst($scope)],
|
||||
Arr::wrap($parameters)
|
||||
);
|
||||
$builder = $builder->callNamedScope($scope, (array) $parameters);
|
||||
}
|
||||
|
||||
return $builder;
|
||||
@@ -972,7 +982,7 @@ class Builder
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
protected function callScope(callable $scope, $parameters = [])
|
||||
protected function callScope(callable $scope, array $parameters = [])
|
||||
{
|
||||
array_unshift($parameters, $this);
|
||||
|
||||
@@ -993,6 +1003,20 @@ class Builder
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the given named scope on the current builder instance.
|
||||
*
|
||||
* @param string $scope
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
protected function callNamedScope($scope, array $parameters = [])
|
||||
{
|
||||
return $this->callScope(function (...$parameters) use ($scope) {
|
||||
return $this->model->callNamedScope($scope, $parameters);
|
||||
}, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nest where conditions by slicing them at the given where count.
|
||||
*
|
||||
@@ -1111,9 +1135,9 @@ class Builder
|
||||
$results = [];
|
||||
|
||||
foreach ($relations as $name => $constraints) {
|
||||
// If the "name" value is a numeric key, we can assume that no
|
||||
// constraints have been specified. We'll just put an empty
|
||||
// Closure there, so that we can treat them all the same.
|
||||
// If the "name" value is a numeric key, we can assume that no constraints
|
||||
// have been specified. We will just put an empty Closure there so that
|
||||
// we can treat these all the same while we are looping through them.
|
||||
if (is_numeric($name)) {
|
||||
$name = $constraints;
|
||||
|
||||
@@ -1183,6 +1207,19 @@ class Builder
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply query-time casts to the model instance.
|
||||
*
|
||||
* @param array $casts
|
||||
* @return $this
|
||||
*/
|
||||
public function withCasts($casts)
|
||||
{
|
||||
$this->model->mergeCasts($casts);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying query builder instance.
|
||||
*
|
||||
@@ -1377,8 +1414,8 @@ class Builder
|
||||
return $callable(...$parameters);
|
||||
}
|
||||
|
||||
if ($this->model !== null && method_exists($this->model, $scope = 'scope'.ucfirst($method))) {
|
||||
return $this->callScope([$this->model, $scope], $parameters);
|
||||
if ($this->hasNamedScope($method)) {
|
||||
return $this->callNamedScope($method, $parameters);
|
||||
}
|
||||
|
||||
if (in_array($method, $this->passthru)) {
|
||||
|
@@ -79,17 +79,18 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
->whereKey($this->modelKeys())
|
||||
->select($this->first()->getKeyName())
|
||||
->withCount(...func_get_args())
|
||||
->get();
|
||||
->get()
|
||||
->keyBy($this->first()->getKeyName());
|
||||
|
||||
$attributes = Arr::except(
|
||||
array_keys($models->first()->getAttributes()),
|
||||
$models->first()->getKeyName()
|
||||
);
|
||||
|
||||
$models->each(function ($model) use ($attributes) {
|
||||
$this->find($model->getKey())->forceFill(
|
||||
Arr::only($model->getAttributes(), $attributes)
|
||||
)->syncOriginalAttributes($attributes);
|
||||
$this->each(function ($model) use ($models, $attributes) {
|
||||
$extraAttributes = Arr::only($models->get($model->getKey())->getAttributes(), $attributes);
|
||||
|
||||
$model->forceFill($extraAttributes)->syncOriginalAttributes($attributes);
|
||||
});
|
||||
|
||||
return $this;
|
||||
@@ -159,7 +160,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
return;
|
||||
}
|
||||
|
||||
$models = $models->pluck($name)->whereNotNull();
|
||||
$models = $models->pluck($name);
|
||||
|
||||
if ($models->first() instanceof BaseCollection) {
|
||||
$models = $models->collapse();
|
||||
@@ -189,6 +190,27 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a set of relationship counts onto the mixed relationship collection.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param array $relations
|
||||
* @return $this
|
||||
*/
|
||||
public function loadMorphCount($relation, $relations)
|
||||
{
|
||||
$this->pluck($relation)
|
||||
->filter()
|
||||
->groupBy(function ($model) {
|
||||
return get_class($model);
|
||||
})
|
||||
->each(function ($models, $className) use ($relations) {
|
||||
static::make($models)->loadCount($relations[$className] ?? []);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a key exists in the collection.
|
||||
*
|
||||
@@ -401,7 +423,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
*/
|
||||
public function makeHidden($attributes)
|
||||
{
|
||||
return $this->each->addHidden($attributes);
|
||||
return $this->each->makeHidden($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,6 +437,17 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
return $this->each->makeVisible($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append an attribute across the entire collection.
|
||||
*
|
||||
* @param array|string $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function append($attributes)
|
||||
{
|
||||
return $this->each->append($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a dictionary keyed by primary keys.
|
||||
*
|
||||
@@ -583,7 +616,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
if (count($relations) === 0 || $relations === [[]]) {
|
||||
return [];
|
||||
} elseif (count($relations) === 1) {
|
||||
return array_values($relations)[0];
|
||||
return reset($relations);
|
||||
} else {
|
||||
return array_intersect(...$relations);
|
||||
}
|
||||
@@ -612,4 +645,30 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Eloquent query builder from the collection.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function toQuery()
|
||||
{
|
||||
$model = $this->first();
|
||||
|
||||
if (! $model) {
|
||||
throw new LogicException('Unable to create query for empty collection.');
|
||||
}
|
||||
|
||||
$class = get_class($model);
|
||||
|
||||
if ($this->filter(function ($model) use ($class) {
|
||||
return ! $model instanceof $class;
|
||||
})->isNotEmpty()) {
|
||||
throw new LogicException('Unable to create query for collection with mixed types.');
|
||||
}
|
||||
|
||||
return $model->newModelQuery()->whereKey($this->modelKeys());
|
||||
}
|
||||
}
|
||||
|
@@ -57,6 +57,19 @@ trait GuardsAttributes
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge new fillable attributes with existing fillable attributes on the model.
|
||||
*
|
||||
* @param array $fillable
|
||||
* @return $this
|
||||
*/
|
||||
public function mergeFillable(array $fillable)
|
||||
{
|
||||
$this->fillable = array_merge($this->fillable, $fillable);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guarded attributes for the model.
|
||||
*
|
||||
@@ -80,6 +93,19 @@ trait GuardsAttributes
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge new guarded attributes with existing guarded attributes on the model.
|
||||
*
|
||||
* @param array $guarded
|
||||
* @return $this
|
||||
*/
|
||||
public function mergeGuarded(array $guarded)
|
||||
{
|
||||
$this->guarded = array_merge($this->guarded, $guarded);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable all mass assignable restrictions.
|
||||
*
|
||||
|
@@ -4,6 +4,8 @@ namespace Illuminate\Database\Eloquent\Concerns;
|
||||
|
||||
use Carbon\CarbonInterface;
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Database\Eloquent\JsonEncodingException;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
@@ -38,12 +40,44 @@ trait HasAttributes
|
||||
protected $changes = [];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [];
|
||||
|
||||
/**
|
||||
* The attributes that have been cast using custom classes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $classCastCache = [];
|
||||
|
||||
/**
|
||||
* The built-in, primitive cast types supported by Eloquent.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $primitiveCastTypes = [
|
||||
'array',
|
||||
'bool',
|
||||
'boolean',
|
||||
'collection',
|
||||
'custom_datetime',
|
||||
'date',
|
||||
'datetime',
|
||||
'decimal',
|
||||
'double',
|
||||
'float',
|
||||
'int',
|
||||
'integer',
|
||||
'json',
|
||||
'object',
|
||||
'real',
|
||||
'string',
|
||||
'timestamp',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be mutated to dates.
|
||||
*
|
||||
@@ -173,7 +207,8 @@ trait HasAttributes
|
||||
protected function addCastAttributesToArray(array $attributes, array $mutatedAttributes)
|
||||
{
|
||||
foreach ($this->getCasts() as $key => $value) {
|
||||
if (! array_key_exists($key, $attributes) || in_array($key, $mutatedAttributes)) {
|
||||
if (! array_key_exists($key, $attributes) ||
|
||||
in_array($key, $mutatedAttributes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -196,6 +231,11 @@ trait HasAttributes
|
||||
$attributes[$key] = $attributes[$key]->format(explode(':', $value, 2)[1]);
|
||||
}
|
||||
|
||||
if ($attributes[$key] && $attributes[$key] instanceof DateTimeInterface &&
|
||||
$this->isClassCastable($key)) {
|
||||
$attributes[$key] = $this->serializeDate($attributes[$key]);
|
||||
}
|
||||
|
||||
if ($attributes[$key] instanceof Arrayable) {
|
||||
$attributes[$key] = $attributes[$key]->toArray();
|
||||
}
|
||||
@@ -211,7 +251,7 @@ trait HasAttributes
|
||||
*/
|
||||
protected function getArrayableAttributes()
|
||||
{
|
||||
return $this->getArrayableItems($this->attributes);
|
||||
return $this->getArrayableItems($this->getAttributes());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,7 +359,9 @@ trait HasAttributes
|
||||
// get the attribute's value. Otherwise, we will proceed as if the developers
|
||||
// are asking for a relationship's value. This covers both types of values.
|
||||
if (array_key_exists($key, $this->attributes) ||
|
||||
$this->hasGetMutator($key)) {
|
||||
array_key_exists($key, $this->casts) ||
|
||||
$this->hasGetMutator($key) ||
|
||||
$this->isClassCastable($key)) {
|
||||
return $this->getAttributeValue($key);
|
||||
}
|
||||
|
||||
@@ -341,31 +383,7 @@ trait HasAttributes
|
||||
*/
|
||||
public function getAttributeValue($key)
|
||||
{
|
||||
$value = $this->getAttributeFromArray($key);
|
||||
|
||||
// If the attribute has a get mutator, we will call that then return what
|
||||
// it returns as the value, which is useful for transforming values on
|
||||
// retrieval from the model to a form that is more useful for usage.
|
||||
if ($this->hasGetMutator($key)) {
|
||||
return $this->mutateAttribute($key, $value);
|
||||
}
|
||||
|
||||
// If the attribute exists within the cast array, we will convert it to
|
||||
// an appropriate native PHP type dependent upon the associated value
|
||||
// given with the key in the pair. Dayle made this comment line up.
|
||||
if ($this->hasCast($key)) {
|
||||
return $this->castAttribute($key, $value);
|
||||
}
|
||||
|
||||
// If the attribute is listed as a date, we will convert it to a DateTime
|
||||
// instance on retrieval, which makes it quite convenient to work with
|
||||
// date fields without having to create a mutator for each property.
|
||||
if (in_array($key, $this->getDates()) &&
|
||||
! is_null($value)) {
|
||||
return $this->asDateTime($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
return $this->transformModelValue($key, $this->getAttributeFromArray($key));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,7 +394,7 @@ trait HasAttributes
|
||||
*/
|
||||
protected function getAttributeFromArray($key)
|
||||
{
|
||||
return $this->attributes[$key] ?? null;
|
||||
return $this->getAttributes()[$key] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,7 +415,8 @@ trait HasAttributes
|
||||
// If the "attribute" exists as a method on the model, we will just assume
|
||||
// it is a relationship and will load and return results from the query
|
||||
// and hydrate the relationship's value on the "relationships" array.
|
||||
if (method_exists($this, $key)) {
|
||||
if (method_exists($this, $key) ||
|
||||
(static::$relationResolvers[get_class($this)][$key] ?? null)) {
|
||||
return $this->getRelationshipFromMethod($key);
|
||||
}
|
||||
}
|
||||
@@ -463,11 +482,24 @@ trait HasAttributes
|
||||
*/
|
||||
protected function mutateAttributeForArray($key, $value)
|
||||
{
|
||||
$value = $this->mutateAttribute($key, $value);
|
||||
$value = $this->isClassCastable($key)
|
||||
? $this->getClassCastableAttributeValue($key, $value)
|
||||
: $this->mutateAttribute($key, $value);
|
||||
|
||||
return $value instanceof Arrayable ? $value->toArray() : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge new casts with existing casts on the model.
|
||||
*
|
||||
* @param array $casts
|
||||
* @return void
|
||||
*/
|
||||
public function mergeCasts($casts)
|
||||
{
|
||||
$this->casts = array_merge($this->casts, $casts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast an attribute to a native PHP type.
|
||||
*
|
||||
@@ -477,11 +509,13 @@ trait HasAttributes
|
||||
*/
|
||||
protected function castAttribute($key, $value)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
$castType = $this->getCastType($key);
|
||||
|
||||
if (is_null($value) && in_array($castType, static::$primitiveCastTypes)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
switch ($this->getCastType($key)) {
|
||||
switch ($castType) {
|
||||
case 'int':
|
||||
case 'integer':
|
||||
return (int) $value;
|
||||
@@ -510,8 +544,40 @@ trait HasAttributes
|
||||
return $this->asDateTime($value);
|
||||
case 'timestamp':
|
||||
return $this->asTimestamp($value);
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($this->isClassCastable($key)) {
|
||||
return $this->getClassCastableAttributeValue($key, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast the given attribute using a custom cast class.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getClassCastableAttributeValue($key, $value)
|
||||
{
|
||||
if (isset($this->classCastCache[$key])) {
|
||||
return $this->classCastCache[$key];
|
||||
} else {
|
||||
$caster = $this->resolveCasterClass($key);
|
||||
|
||||
$value = $caster instanceof CastsInboundAttributes
|
||||
? $value
|
||||
: $caster->get($this, $key, $value, $this->attributes);
|
||||
|
||||
if ($caster instanceof CastsInboundAttributes || ! is_object($value)) {
|
||||
unset($this->classCastCache[$key]);
|
||||
} else {
|
||||
$this->classCastCache[$key] = $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,6 +646,12 @@ trait HasAttributes
|
||||
$value = $this->fromDateTime($value);
|
||||
}
|
||||
|
||||
if ($this->isClassCastable($key)) {
|
||||
$this->setClassCastableAttribute($key, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->isJsonCastable($key) && ! is_null($value)) {
|
||||
$value = $this->castAttributeAsJson($key, $value);
|
||||
}
|
||||
@@ -649,6 +721,41 @@ trait HasAttributes
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a class castable attribute.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
protected function setClassCastableAttribute($key, $value)
|
||||
{
|
||||
$caster = $this->resolveCasterClass($key);
|
||||
|
||||
if (is_null($value)) {
|
||||
$this->attributes = array_merge($this->attributes, array_map(
|
||||
function () {
|
||||
},
|
||||
$this->normalizeCastClassResponse($key, $caster->set(
|
||||
$this, $key, $this->{$key}, $this->attributes
|
||||
))
|
||||
));
|
||||
} else {
|
||||
$this->attributes = array_merge(
|
||||
$this->attributes,
|
||||
$this->normalizeCastClassResponse($key, $caster->set(
|
||||
$this, $key, $value, $this->attributes
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
if ($caster instanceof CastsInboundAttributes || ! is_object($value)) {
|
||||
unset($this->classCastCache[$key]);
|
||||
} else {
|
||||
$this->classCastCache[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array attribute with the given key and value set.
|
||||
*
|
||||
@@ -802,15 +909,14 @@ trait HasAttributes
|
||||
|
||||
$format = $this->getDateFormat();
|
||||
|
||||
// https://bugs.php.net/bug.php?id=75577
|
||||
if (version_compare(PHP_VERSION, '7.3.0-dev', '<')) {
|
||||
$format = str_replace('.v', '.u', $format);
|
||||
}
|
||||
|
||||
// Finally, we will just assume this date is in the format used by default on
|
||||
// the database connection and use that format to create the Carbon object
|
||||
// that is returned back out to the developers after we convert it here.
|
||||
return Date::createFromFormat($format, $value);
|
||||
if (Date::hasFormat($value, $format)) {
|
||||
return Date::createFromFormat($format, $value);
|
||||
}
|
||||
|
||||
return Date::parse($value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -856,7 +962,7 @@ trait HasAttributes
|
||||
*/
|
||||
protected function serializeDate(DateTimeInterface $date)
|
||||
{
|
||||
return $date->format($this->getDateFormat());
|
||||
return Carbon::instance($date)->toJSON();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -866,14 +972,16 @@ trait HasAttributes
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
if (! $this->usesTimestamps()) {
|
||||
return $this->dates;
|
||||
}
|
||||
|
||||
$defaults = [
|
||||
$this->getCreatedAtColumn(),
|
||||
$this->getUpdatedAtColumn(),
|
||||
];
|
||||
|
||||
return $this->usesTimestamps()
|
||||
? array_unique(array_merge($this->dates, $defaults))
|
||||
: $this->dates;
|
||||
return array_unique(array_merge($this->dates, $defaults));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -951,6 +1059,93 @@ trait HasAttributes
|
||||
return $this->hasCast($key, ['array', 'json', 'object', 'collection']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given key is cast using a custom class.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
protected function isClassCastable($key)
|
||||
{
|
||||
return array_key_exists($key, $this->getCasts()) &&
|
||||
class_exists($class = $this->parseCasterClass($this->getCasts()[$key])) &&
|
||||
! in_array($class, static::$primitiveCastTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the custom caster class for a given key.
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
protected function resolveCasterClass($key)
|
||||
{
|
||||
$castType = $this->getCasts()[$key];
|
||||
|
||||
$arguments = [];
|
||||
|
||||
if (is_string($castType) && strpos($castType, ':') !== false) {
|
||||
$segments = explode(':', $castType, 2);
|
||||
|
||||
$castType = $segments[0];
|
||||
$arguments = explode(',', $segments[1]);
|
||||
}
|
||||
|
||||
if (is_subclass_of($castType, Castable::class)) {
|
||||
$castType = $castType::castUsing();
|
||||
}
|
||||
|
||||
if (is_object($castType)) {
|
||||
return $castType;
|
||||
}
|
||||
|
||||
return new $castType(...$arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given caster class, removing any arguments.
|
||||
*
|
||||
* @param string $class
|
||||
* @return string
|
||||
*/
|
||||
protected function parseCasterClass($class)
|
||||
{
|
||||
return strpos($class, ':') === false
|
||||
? $class
|
||||
: explode(':', $class, 2)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the cast class attributes back into the model.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function mergeAttributesFromClassCasts()
|
||||
{
|
||||
foreach ($this->classCastCache as $key => $value) {
|
||||
$caster = $this->resolveCasterClass($key);
|
||||
|
||||
$this->attributes = array_merge(
|
||||
$this->attributes,
|
||||
$caster instanceof CastsInboundAttributes
|
||||
? [$key => $value]
|
||||
: $this->normalizeCastClassResponse($key, $caster->set($this, $key, $value, $this->attributes))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the response from a custom class caster.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return array
|
||||
*/
|
||||
protected function normalizeCastClassResponse($key, $value)
|
||||
{
|
||||
return is_array($value) ? $value : [$key => $value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the current attributes on the model.
|
||||
*
|
||||
@@ -958,6 +1153,8 @@ trait HasAttributes
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
$this->mergeAttributesFromClassCasts();
|
||||
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
@@ -976,6 +1173,8 @@ trait HasAttributes
|
||||
$this->syncOriginal();
|
||||
}
|
||||
|
||||
$this->classCastCache = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -987,6 +1186,40 @@ trait HasAttributes
|
||||
* @return mixed|array
|
||||
*/
|
||||
public function getOriginal($key = null, $default = null)
|
||||
{
|
||||
return (new static)->setRawAttributes(
|
||||
$this->original, $sync = true
|
||||
)->getOriginalWithoutRewindingModel($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the model's original attribute values.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @param mixed $default
|
||||
* @return mixed|array
|
||||
*/
|
||||
protected function getOriginalWithoutRewindingModel($key = null, $default = null)
|
||||
{
|
||||
if ($key) {
|
||||
return $this->transformModelValue(
|
||||
$key, Arr::get($this->original, $key, $default)
|
||||
);
|
||||
}
|
||||
|
||||
return collect($this->original)->mapWithKeys(function ($value, $key) {
|
||||
return [$key => $this->transformModelValue($key, $value)];
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the model's raw original attribute values.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @param mixed $default
|
||||
* @return mixed|array
|
||||
*/
|
||||
public function getRawOriginal($key = null, $default = null)
|
||||
{
|
||||
return Arr::get($this->original, $key, $default);
|
||||
}
|
||||
@@ -1015,7 +1248,7 @@ trait HasAttributes
|
||||
*/
|
||||
public function syncOriginal()
|
||||
{
|
||||
$this->original = $this->attributes;
|
||||
$this->original = $this->getAttributes();
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -1041,8 +1274,10 @@ trait HasAttributes
|
||||
{
|
||||
$attributes = is_array($attributes) ? $attributes : func_get_args();
|
||||
|
||||
$modelAttributes = $this->getAttributes();
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
$this->original[$attribute] = $this->attributes[$attribute];
|
||||
$this->original[$attribute] = $modelAttributes[$attribute];
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -1135,7 +1370,7 @@ trait HasAttributes
|
||||
$dirty = [];
|
||||
|
||||
foreach ($this->getAttributes() as $key => $value) {
|
||||
if (! $this->originalIsEquivalent($key, $value)) {
|
||||
if (! $this->originalIsEquivalent($key)) {
|
||||
$dirty[$key] = $value;
|
||||
}
|
||||
}
|
||||
@@ -1157,40 +1392,74 @@ trait HasAttributes
|
||||
* Determine if the new and old values for a given key are equivalent.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $current
|
||||
* @return bool
|
||||
*/
|
||||
public function originalIsEquivalent($key, $current)
|
||||
public function originalIsEquivalent($key)
|
||||
{
|
||||
if (! array_key_exists($key, $this->original)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$original = $this->getOriginal($key);
|
||||
$attribute = Arr::get($this->attributes, $key);
|
||||
$original = Arr::get($this->original, $key);
|
||||
|
||||
if ($current === $original) {
|
||||
if ($attribute === $original) {
|
||||
return true;
|
||||
} elseif (is_null($current)) {
|
||||
} elseif (is_null($attribute)) {
|
||||
return false;
|
||||
} elseif ($this->isDateAttribute($key)) {
|
||||
return $this->fromDateTime($current) ===
|
||||
return $this->fromDateTime($attribute) ===
|
||||
$this->fromDateTime($original);
|
||||
} elseif ($this->hasCast($key, ['object', 'collection'])) {
|
||||
return $this->castAttribute($key, $current) ==
|
||||
return $this->castAttribute($key, $attribute) ==
|
||||
$this->castAttribute($key, $original);
|
||||
} elseif ($this->hasCast($key, ['real', 'float', 'double'])) {
|
||||
if (($current === null && $original !== null) || ($current !== null && $original === null)) {
|
||||
if (($attribute === null && $original !== null) || ($attribute !== null && $original === null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return abs($this->castAttribute($key, $current) - $this->castAttribute($key, $original)) < PHP_FLOAT_EPSILON * 4;
|
||||
} elseif ($this->hasCast($key)) {
|
||||
return $this->castAttribute($key, $current) ===
|
||||
return abs($this->castAttribute($key, $attribute) - $this->castAttribute($key, $original)) < PHP_FLOAT_EPSILON * 4;
|
||||
} elseif ($this->hasCast($key, static::$primitiveCastTypes)) {
|
||||
return $this->castAttribute($key, $attribute) ===
|
||||
$this->castAttribute($key, $original);
|
||||
}
|
||||
|
||||
return is_numeric($current) && is_numeric($original)
|
||||
&& strcmp((string) $current, (string) $original) === 0;
|
||||
return is_numeric($attribute) && is_numeric($original)
|
||||
&& strcmp((string) $attribute, (string) $original) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a raw model value using mutators, casts, etc.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function transformModelValue($key, $value)
|
||||
{
|
||||
// If the attribute has a get mutator, we will call that then return what
|
||||
// it returns as the value, which is useful for transforming values on
|
||||
// retrieval from the model to a form that is more useful for usage.
|
||||
if ($this->hasGetMutator($key)) {
|
||||
return $this->mutateAttribute($key, $value);
|
||||
}
|
||||
|
||||
// If the attribute exists within the cast array, we will convert it to
|
||||
// an appropriate native PHP type dependent upon the associated value
|
||||
// given with the key in the pair. Dayle made this comment line up.
|
||||
if ($this->hasCast($key)) {
|
||||
return $this->castAttribute($key, $value);
|
||||
}
|
||||
|
||||
// If the attribute is listed as a date, we will convert it to a DateTime
|
||||
// instance on retrieval, which makes it quite convenient to work with
|
||||
// date fields without having to create a mutator for each property.
|
||||
if ($value !== null
|
||||
&& \in_array($key, $this->getDates(), false)) {
|
||||
return $this->asDateTime($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1221,6 +1490,17 @@ trait HasAttributes
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the accessor attribute has been appended.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAppended($attribute)
|
||||
{
|
||||
return in_array($attribute, $this->appends);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mutated attributes for a given instance.
|
||||
*
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Illuminate\Database\Eloquent\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@@ -44,6 +45,28 @@ trait HasRelationships
|
||||
'belongsToMany', 'morphToMany', 'morphedByMany',
|
||||
];
|
||||
|
||||
/**
|
||||
* The relation resolver callbacks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $relationResolvers = [];
|
||||
|
||||
/**
|
||||
* Define a dynamic relation resolver.
|
||||
*
|
||||
* @param string $name
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
public static function resolveRelationUsing($name, Closure $callback)
|
||||
{
|
||||
static::$relationResolvers = array_replace_recursive(
|
||||
static::$relationResolvers,
|
||||
[static::class => [$name => $callback]]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a one-to-one relationship.
|
||||
*
|
||||
@@ -369,8 +392,12 @@ trait HasRelationships
|
||||
$secondKey = $secondKey ?: $through->getForeignKey();
|
||||
|
||||
return $this->newHasManyThrough(
|
||||
$this->newRelatedInstance($related)->newQuery(), $this, $through,
|
||||
$firstKey, $secondKey, $localKey ?: $this->getKeyName(),
|
||||
$this->newRelatedInstance($related)->newQuery(),
|
||||
$this,
|
||||
$through,
|
||||
$firstKey,
|
||||
$secondKey,
|
||||
$localKey ?: $this->getKeyName(),
|
||||
$secondLocalKey ?: $through->getKeyName()
|
||||
);
|
||||
}
|
||||
@@ -488,7 +515,7 @@ trait HasRelationships
|
||||
* @param string $relatedPivotKey
|
||||
* @param string $parentKey
|
||||
* @param string $relatedKey
|
||||
* @param string $relationName
|
||||
* @param string|null $relationName
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
protected function newBelongsToMany(Builder $query, Model $parent, $table, $foreignPivotKey, $relatedPivotKey,
|
||||
@@ -655,7 +682,7 @@ trait HasRelationships
|
||||
*/
|
||||
public function touches($relation)
|
||||
{
|
||||
return in_array($relation, $this->touches);
|
||||
return in_array($relation, $this->getTouchedRelations());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -665,7 +692,7 @@ trait HasRelationships
|
||||
*/
|
||||
public function touchOwners()
|
||||
{
|
||||
foreach ($this->touches as $relation) {
|
||||
foreach ($this->getTouchedRelations() as $relation) {
|
||||
$this->$relation()->touch();
|
||||
|
||||
if ($this->$relation instanceof self) {
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Illuminate\Database\Eloquent\Concerns;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait HidesAttributes
|
||||
{
|
||||
/**
|
||||
@@ -41,19 +43,6 @@ trait HidesAttributes
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add hidden attributes for the model.
|
||||
*
|
||||
* @param array|string|null $attributes
|
||||
* @return void
|
||||
*/
|
||||
public function addHidden($attributes = null)
|
||||
{
|
||||
$this->hidden = array_merge(
|
||||
$this->hidden, is_array($attributes) ? $attributes : func_get_args()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the visible attributes for the model.
|
||||
*
|
||||
@@ -77,50 +66,65 @@ trait HidesAttributes
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add visible attributes for the model.
|
||||
*
|
||||
* @param array|string|null $attributes
|
||||
* @return void
|
||||
*/
|
||||
public function addVisible($attributes = null)
|
||||
{
|
||||
$this->visible = array_merge(
|
||||
$this->visible, is_array($attributes) ? $attributes : func_get_args()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the given, typically hidden, attributes visible.
|
||||
*
|
||||
* @param array|string $attributes
|
||||
* @param array|string|null $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function makeVisible($attributes)
|
||||
{
|
||||
$this->hidden = array_diff($this->hidden, (array) $attributes);
|
||||
$attributes = is_array($attributes) ? $attributes : func_get_args();
|
||||
|
||||
$this->hidden = array_diff($this->hidden, $attributes);
|
||||
|
||||
if (! empty($this->visible)) {
|
||||
$this->addVisible($attributes);
|
||||
$this->visible = array_merge($this->visible, $attributes);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the given, typically hidden, attributes visible if the given truth test passes.
|
||||
*
|
||||
* @param bool|Closure $condition
|
||||
* @param array|string|null $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function makeVisibleIf($condition, $attributes)
|
||||
{
|
||||
$condition = $condition instanceof Closure ? $condition($this) : $condition;
|
||||
|
||||
return $condition ? $this->makeVisible($attributes) : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the given, typically visible, attributes hidden.
|
||||
*
|
||||
* @param array|string $attributes
|
||||
* @param array|string|null $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function makeHidden($attributes)
|
||||
{
|
||||
$attributes = (array) $attributes;
|
||||
|
||||
$this->visible = array_diff($this->visible, $attributes);
|
||||
|
||||
$this->hidden = array_unique(array_merge($this->hidden, $attributes));
|
||||
$this->hidden = array_merge(
|
||||
$this->hidden, is_array($attributes) ? $attributes : func_get_args()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the given, typically visible, attributes hidden if the given truth test passes.
|
||||
*
|
||||
* @param bool|Closure $condition
|
||||
* @param array|string|null $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function makeHiddenIf($condition, $attributes)
|
||||
{
|
||||
$condition = $condition instanceof Closure ? $condition($this) : $condition;
|
||||
|
||||
return value($condition) ? $this->makeHidden($attributes) : $this;
|
||||
}
|
||||
}
|
||||
|
@@ -152,7 +152,7 @@ trait QueriesRelationships
|
||||
* Add a relationship count / exists condition to the query with where clauses and an "or".
|
||||
*
|
||||
* @param string $relation
|
||||
* @param \Closure $callback
|
||||
* @param \Closure|null $callback
|
||||
* @param string $operator
|
||||
* @param int $count
|
||||
* @return \Illuminate\Database\Eloquent\Builder|static
|
||||
@@ -178,7 +178,7 @@ trait QueriesRelationships
|
||||
* Add a relationship count / exists condition to the query with where clauses and an "or".
|
||||
*
|
||||
* @param string $relation
|
||||
* @param \Closure $callback
|
||||
* @param \Closure|null $callback
|
||||
* @return \Illuminate\Database\Eloquent\Builder|static
|
||||
*/
|
||||
public function orWhereDoesntHave($relation, Closure $callback = null)
|
||||
@@ -205,10 +205,10 @@ trait QueriesRelationships
|
||||
|
||||
if ($types === ['*']) {
|
||||
$types = $this->model->newModelQuery()->distinct()->pluck($relation->getMorphType())->filter()->all();
|
||||
}
|
||||
|
||||
foreach ($types as &$type) {
|
||||
$type = Relation::getMorphedModel($type) ?? $type;
|
||||
}
|
||||
foreach ($types as &$type) {
|
||||
$type = Relation::getMorphedModel($type) ?? $type;
|
||||
}
|
||||
|
||||
return $this->where(function ($query) use ($relation, $callback, $operator, $count, $types) {
|
||||
@@ -311,7 +311,7 @@ trait QueriesRelationships
|
||||
*
|
||||
* @param string $relation
|
||||
* @param string|array $types
|
||||
* @param \Closure $callback
|
||||
* @param \Closure|null $callback
|
||||
* @param string $operator
|
||||
* @param int $count
|
||||
* @return \Illuminate\Database\Eloquent\Builder|static
|
||||
@@ -339,7 +339,7 @@ trait QueriesRelationships
|
||||
*
|
||||
* @param string $relation
|
||||
* @param string|array $types
|
||||
* @param \Closure $callback
|
||||
* @param \Closure|null $callback
|
||||
* @return \Illuminate\Database\Eloquent\Builder|static
|
||||
*/
|
||||
public function orWhereDoesntHaveMorph($relation, $types, Closure $callback = null)
|
||||
@@ -390,6 +390,10 @@ trait QueriesRelationships
|
||||
|
||||
$query = $query->mergeConstraintsFrom($relation->getQuery())->toBase();
|
||||
|
||||
$query->orders = null;
|
||||
|
||||
$query->setBindings([], 'order');
|
||||
|
||||
if (count($query->columns) > 1) {
|
||||
$query->columns = [$query->columns[0]];
|
||||
|
||||
|
@@ -68,30 +68,16 @@ class Factory implements ArrayAccess
|
||||
return (new static($faker))->load($pathToFactories);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a class with a given short-name.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $name
|
||||
* @param callable $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function defineAs($class, $name, callable $attributes)
|
||||
{
|
||||
return $this->define($class, $attributes, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a class with a given set of attributes.
|
||||
*
|
||||
* @param string $class
|
||||
* @param callable $attributes
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function define($class, callable $attributes, $name = 'default')
|
||||
public function define($class, callable $attributes)
|
||||
{
|
||||
$this->definitions[$class][$name] = $attributes;
|
||||
$this->definitions[$class] = $attributes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -179,19 +165,6 @@ class Factory implements ArrayAccess
|
||||
return $this->of($class)->create($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of the given model and type and persist it to the database.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $name
|
||||
* @param array $attributes
|
||||
* @return mixed
|
||||
*/
|
||||
public function createAs($class, $name, array $attributes = [])
|
||||
{
|
||||
return $this->of($class, $name)->create($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of the given model.
|
||||
*
|
||||
@@ -204,44 +177,17 @@ class Factory implements ArrayAccess
|
||||
return $this->of($class)->make($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of the given model and type.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $name
|
||||
* @param array $attributes
|
||||
* @return mixed
|
||||
*/
|
||||
public function makeAs($class, $name, array $attributes = [])
|
||||
{
|
||||
return $this->of($class, $name)->make($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw attribute array for a given named model.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $name
|
||||
* @param array $attributes
|
||||
* @return array
|
||||
*/
|
||||
public function rawOf($class, $name, array $attributes = [])
|
||||
{
|
||||
return $this->raw($class, $attributes, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw attribute array for a given model.
|
||||
*
|
||||
* @param string $class
|
||||
* @param array $attributes
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public function raw($class, array $attributes = [], $name = 'default')
|
||||
public function raw($class, array $attributes = [])
|
||||
{
|
||||
return array_merge(
|
||||
call_user_func($this->definitions[$class][$name], $this->faker), $attributes
|
||||
call_user_func($this->definitions[$class], $this->faker), $attributes
|
||||
);
|
||||
}
|
||||
|
||||
@@ -249,13 +195,12 @@ class Factory implements ArrayAccess
|
||||
* Create a builder for the given model.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $name
|
||||
* @return \Illuminate\Database\Eloquent\FactoryBuilder
|
||||
*/
|
||||
public function of($class, $name = 'default')
|
||||
public function of($class)
|
||||
{
|
||||
return new FactoryBuilder(
|
||||
$class, $name, $this->definitions, $this->states,
|
||||
$class, $this->definitions, $this->states,
|
||||
$this->afterMaking, $this->afterCreating, $this->faker
|
||||
);
|
||||
}
|
||||
|
@@ -24,13 +24,6 @@ class FactoryBuilder
|
||||
*/
|
||||
protected $class;
|
||||
|
||||
/**
|
||||
* The name of the model being built.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'default';
|
||||
|
||||
/**
|
||||
* The database connection on which the model instance should be persisted.
|
||||
*
|
||||
@@ -84,7 +77,6 @@ class FactoryBuilder
|
||||
* Create an new builder instance.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $name
|
||||
* @param array $definitions
|
||||
* @param array $states
|
||||
* @param array $afterMaking
|
||||
@@ -92,10 +84,9 @@ class FactoryBuilder
|
||||
* @param \Faker\Generator $faker
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($class, $name, array $definitions, array $states,
|
||||
public function __construct($class, array $definitions, array $states,
|
||||
array $afterMaking, array $afterCreating, Faker $faker)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->class = $class;
|
||||
$this->faker = $faker;
|
||||
$this->states = $states;
|
||||
@@ -278,12 +269,12 @@ class FactoryBuilder
|
||||
*/
|
||||
protected function getRawAttributes(array $attributes = [])
|
||||
{
|
||||
if (! isset($this->definitions[$this->class][$this->name])) {
|
||||
throw new InvalidArgumentException("Unable to locate factory with name [{$this->name}] [{$this->class}].");
|
||||
if (! isset($this->definitions[$this->class])) {
|
||||
throw new InvalidArgumentException("Unable to locate factory for [{$this->class}].");
|
||||
}
|
||||
|
||||
$definition = call_user_func(
|
||||
$this->definitions[$this->class][$this->name],
|
||||
$this->definitions[$this->class],
|
||||
$this->faker, $attributes
|
||||
);
|
||||
|
||||
@@ -416,7 +407,7 @@ class FactoryBuilder
|
||||
*/
|
||||
protected function callAfter(array $afterCallbacks, $models)
|
||||
{
|
||||
$states = array_merge([$this->name], $this->activeStates);
|
||||
$states = array_merge(['default'], $this->activeStates);
|
||||
|
||||
$models->each(function ($model) use ($states, $afterCallbacks) {
|
||||
foreach ($states as $state) {
|
||||
|
@@ -26,6 +26,7 @@ class HigherOrderBuilderProxy
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||
* @param string $method
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Builder $builder, $method)
|
||||
{
|
||||
|
@@ -18,6 +18,20 @@ class JsonEncodingException extends RuntimeException
|
||||
return new static('Error encoding model ['.get_class($model).'] with ID ['.$model->getKey().'] to JSON: '.$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new JSON encoding exception for the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Resources\Json\JsonResource $resource
|
||||
* @param string $message
|
||||
* @return static
|
||||
*/
|
||||
public static function forResource($resource, $message)
|
||||
{
|
||||
$model = $resource->resource;
|
||||
|
||||
return new static('Error encoding resource ['.get_class($resource).'] with model ['.get_class($model).'] with ID ['.$model->getKey().'] to JSON: '.$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new JSON encoding exception for an attribute.
|
||||
*
|
||||
|
@@ -10,7 +10,9 @@ use Illuminate\Contracts\Routing\UrlRoutable;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Support\Jsonable;
|
||||
use Illuminate\Database\ConnectionResolverInterface as Resolver;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\Concerns\AsPivot;
|
||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection as BaseCollection;
|
||||
@@ -184,14 +186,26 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
|
||||
$this->fireModelEvent('booting', false);
|
||||
|
||||
static::booting();
|
||||
static::boot();
|
||||
static::booted();
|
||||
|
||||
$this->fireModelEvent('booted', false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The "booting" method of the model.
|
||||
* Perform any actions required before the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booting()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap the model and its traits.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@@ -244,6 +258,16 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the list of booted models so they will be re-booted.
|
||||
*
|
||||
@@ -372,6 +396,8 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
*
|
||||
* @deprecated This method is deprecated and will be removed in a future Laravel version.
|
||||
*/
|
||||
protected function removeTableFromKey($key)
|
||||
{
|
||||
@@ -400,6 +426,8 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
|
||||
$model->setTable($this->getTable());
|
||||
|
||||
$model->mergeCasts($this->casts);
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
@@ -494,6 +522,22 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eager load relationships on the polymorphic relation of a model.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param array $relations
|
||||
* @return $this
|
||||
*/
|
||||
public function loadMorph($relation, $relations)
|
||||
{
|
||||
$className = get_class($this->{$relation});
|
||||
|
||||
$this->{$relation}->load($relations[$className] ?? []);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eager load relations on the model if they are not already eager loaded.
|
||||
*
|
||||
@@ -524,6 +568,22 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eager load relationship counts on the polymorphic relation of a model.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param array $relations
|
||||
* @return $this
|
||||
*/
|
||||
public function loadMorphCount($relation, $relations)
|
||||
{
|
||||
$className = get_class($this->{$relation});
|
||||
|
||||
$this->{$relation}->loadCount($relations[$className] ?? []);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment a column's value by a given amount.
|
||||
*
|
||||
@@ -644,6 +704,8 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
*/
|
||||
public function save(array $options = [])
|
||||
{
|
||||
$this->mergeAttributesFromClassCasts();
|
||||
|
||||
$query = $this->newModelQuery();
|
||||
|
||||
// If the "saving" event returns false we'll bail out of the save and return
|
||||
@@ -845,7 +907,7 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
/**
|
||||
* Destroy the models for the given IDs.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection|array|int $ids
|
||||
* @param \Illuminate\Support\Collection|array|int|string $ids
|
||||
* @return int
|
||||
*/
|
||||
public static function destroy($ids)
|
||||
@@ -884,6 +946,8 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->mergeAttributesFromClassCasts();
|
||||
|
||||
if (is_null($this->getKeyName())) {
|
||||
throw new Exception('No primary key defined on model.');
|
||||
}
|
||||
@@ -1079,6 +1143,29 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
: Pivot::fromAttributes($parent, $attributes, $table, $exists);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the model has a given scope.
|
||||
*
|
||||
* @param string $scope
|
||||
* @return bool
|
||||
*/
|
||||
public function hasNamedScope($scope)
|
||||
{
|
||||
return method_exists($this, 'scope'.ucfirst($scope));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the given named scope if possible.
|
||||
*
|
||||
* @param string $scope
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function callNamedScope($scope, array $parameters = [])
|
||||
{
|
||||
return $this->{'scope'.ucfirst($scope)}(...$parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the model instance to an array.
|
||||
*
|
||||
@@ -1176,7 +1263,7 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
];
|
||||
|
||||
$attributes = Arr::except(
|
||||
$this->attributes, $except ? array_unique(array_merge($except, $defaults)) : $defaults
|
||||
$this->getAttributes(), $except ? array_unique(array_merge($except, $defaults)) : $defaults
|
||||
);
|
||||
|
||||
return tap(new static, function ($instance) use ($attributes) {
|
||||
@@ -1476,11 +1563,34 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
* Retrieve the model for a bound value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string|null $field
|
||||
* @return \Illuminate\Database\Eloquent\Model|null
|
||||
*/
|
||||
public function resolveRouteBinding($value)
|
||||
public function resolveRouteBinding($value, $field = null)
|
||||
{
|
||||
return $this->where($this->getRouteKeyName(), $value)->first();
|
||||
return $this->where($field ?? $this->getRouteKeyName(), $value)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the child model for a bound value.
|
||||
*
|
||||
* @param string $childType
|
||||
* @param mixed $value
|
||||
* @param string|null $field
|
||||
* @return \Illuminate\Database\Eloquent\Model|null
|
||||
*/
|
||||
public function resolveChildRouteBinding($childType, $value, $field)
|
||||
{
|
||||
$relationship = $this->{Str::plural(Str::camel($childType))}();
|
||||
|
||||
$field = $field ?: $relationship->getRelated()->getRouteKeyName();
|
||||
|
||||
if ($relationship instanceof HasManyThrough ||
|
||||
$relationship instanceof BelongsToMany) {
|
||||
return $relationship->where($relationship->getRelated()->getTable().'.'.$field, $value)->first();
|
||||
} else {
|
||||
return $relationship->where($field, $value)->first();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1619,11 +1729,15 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
return $this->$method(...$parameters);
|
||||
}
|
||||
|
||||
if ($resolver = (static::$relationResolvers[get_class($this)][$method] ?? null)) {
|
||||
return $resolver($this);
|
||||
}
|
||||
|
||||
return $this->forwardCallTo($this->newQuery(), $method, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle dynamic static method calls into the method.
|
||||
* Handle dynamic static method calls into the model.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
@@ -1644,6 +1758,20 @@ abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializab
|
||||
return $this->toJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the object for serialization.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
$this->mergeAttributesFromClassCasts();
|
||||
|
||||
$this->classCastCache = [];
|
||||
|
||||
return array_keys(get_object_vars($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* When a model is being unserialized, check if it needs to be booted.
|
||||
*
|
||||
|
@@ -13,6 +13,8 @@ class BelongsTo extends Relation
|
||||
|
||||
/**
|
||||
* The child model instance of the relation.
|
||||
*
|
||||
* @var \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
protected $child;
|
||||
|
||||
@@ -206,7 +208,7 @@ class BelongsTo extends Relation
|
||||
|
||||
if ($model instanceof Model) {
|
||||
$this->child->setRelation($this->relationName, $model);
|
||||
} elseif ($this->child->isDirty($this->foreignKey)) {
|
||||
} else {
|
||||
$this->child->unsetRelation($this->relationName);
|
||||
}
|
||||
|
||||
@@ -283,7 +285,7 @@ class BelongsTo extends Relation
|
||||
protected function relationHasIncrementingId()
|
||||
{
|
||||
return $this->related->getIncrementing() &&
|
||||
$this->related->getKeyType() === 'int';
|
||||
in_array($this->related->getKeyType(), ['int', 'integer']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user