Laravel 5.6 updates
Travis config update Removed HHVM script as Laravel no longer support HHVM after releasing 5.3
This commit is contained in:
@@ -122,7 +122,7 @@ class Gate implements GateContract
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $class
|
||||
* @param array $abilities
|
||||
* @param array|null $abilities
|
||||
* @return $this
|
||||
*/
|
||||
public function resource($name, $class, array $abilities = null)
|
||||
|
@@ -35,7 +35,7 @@ class Response
|
||||
/**
|
||||
* Get the string representation of the message.
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
|
@@ -94,7 +94,7 @@ class AuthManager implements FactoryContract
|
||||
return $this->{$driverMethod}($name, $config);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Auth guard driver [{$name}] is not defined.");
|
||||
throw new InvalidArgumentException("Auth driver [{$config['driver']}] for guard [{$name}] is not defined.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -2,61 +2,63 @@
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Login</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Login') }}</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="POST" action="{{ route('login') }}">
|
||||
{{ csrf_field() }}
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('login') }}" aria-label="{{ __('Login') }}">
|
||||
@csrf
|
||||
|
||||
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
|
||||
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-sm-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>
|
||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autofocus>
|
||||
|
||||
@if ($errors->has('email'))
|
||||
<span class="help-block">
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('email') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
|
||||
<label for="password" class="col-md-4 control-label">Password</label>
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control" name="password" required>
|
||||
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
|
||||
|
||||
@if ($errors->has('password'))
|
||||
<span class="help-block">
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('password') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-6 col-md-offset-4">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> Remember Me
|
||||
<div class="form-group row">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
|
||||
|
||||
<label class="form-check-label" for="remember">
|
||||
{{ __('Remember Me') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-8 col-md-offset-4">
|
||||
<div class="form-group row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Login
|
||||
{{ __('Login') }}
|
||||
</button>
|
||||
|
||||
<a class="btn btn-link" href="{{ route('password.request') }}">
|
||||
Forgot Your Password?
|
||||
{{ __('Forgot Your Password?') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -2,39 +2,39 @@
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Reset Password</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Reset Password') }}</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success">
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form class="form-horizontal" method="POST" action="{{ route('password.email') }}">
|
||||
{{ csrf_field() }}
|
||||
<form method="POST" action="{{ route('password.email') }}" aria-label="{{ __('Reset Password') }}">
|
||||
@csrf
|
||||
|
||||
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
|
||||
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required>
|
||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required>
|
||||
|
||||
@if ($errors->has('email'))
|
||||
<span class="help-block">
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('email') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-6 col-md-offset-4">
|
||||
<div class="form-group row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Send Password Reset Link
|
||||
{{ __('Send Password Reset Link') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -2,62 +2,57 @@
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Reset Password</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Reset Password') }}</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="POST" action="{{ route('password.request') }}">
|
||||
{{ csrf_field() }}
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('password.request') }}" aria-label="{{ __('Reset Password') }}">
|
||||
@csrf
|
||||
|
||||
<input type="hidden" name="token" value="{{ $token }}">
|
||||
|
||||
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
|
||||
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control" name="email" value="{{ $email or old('email') }}" required autofocus>
|
||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ $email ?? old('email') }}" required autofocus>
|
||||
|
||||
@if ($errors->has('email'))
|
||||
<span class="help-block">
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('email') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
|
||||
<label for="password" class="col-md-4 control-label">Password</label>
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control" name="password" required>
|
||||
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
|
||||
|
||||
@if ($errors->has('password'))
|
||||
<span class="help-block">
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('password') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
|
||||
<label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>
|
||||
<div class="form-group row">
|
||||
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
|
||||
|
||||
@if ($errors->has('password_confirmation'))
|
||||
<span class="help-block">
|
||||
<strong>{{ $errors->first('password_confirmation') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-6 col-md-offset-4">
|
||||
<div class="form-group row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Reset Password
|
||||
{{ __('Reset Password') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -2,69 +2,69 @@
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Register</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Register') }}</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="POST" action="{{ route('register') }}">
|
||||
{{ csrf_field() }}
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('register') }}" aria-label="{{ __('Register') }}">
|
||||
@csrf
|
||||
|
||||
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
|
||||
<label for="name" class="col-md-4 control-label">Name</label>
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus>
|
||||
<input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name') }}" required autofocus>
|
||||
|
||||
@if ($errors->has('name'))
|
||||
<span class="help-block">
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('name') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
|
||||
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required>
|
||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required>
|
||||
|
||||
@if ($errors->has('email'))
|
||||
<span class="help-block">
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('email') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
|
||||
<label for="password" class="col-md-4 control-label">Password</label>
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control" name="password" required>
|
||||
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
|
||||
|
||||
@if ($errors->has('password'))
|
||||
<span class="help-block">
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $errors->first('password') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>
|
||||
<div class="form-group row">
|
||||
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-6 col-md-offset-4">
|
||||
<div class="form-group row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Register
|
||||
{{ __('Register') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -2,14 +2,14 @@
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Dashboard</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">Dashboard</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success">
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ app()->getLocale() }}">
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
@@ -10,60 +10,60 @@
|
||||
|
||||
<title>{{ config('app.name', 'Laravel') }}</title>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="{{ asset('js/app.js') }}" defer></script>
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="dns-prefetch" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- Styles -->
|
||||
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<nav class="navbar navbar-default navbar-static-top">
|
||||
<nav class="navbar navbar-expand-md navbar-light navbar-laravel">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="{{ url('/') }}">
|
||||
{{ config('app.name', 'Laravel') }}
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<!-- Collapsed Hamburger -->
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse" aria-expanded="false">
|
||||
<span class="sr-only">Toggle Navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
|
||||
<!-- Branding Image -->
|
||||
<a class="navbar-brand" href="{{ url('/') }}">
|
||||
{{ config('app.name', 'Laravel') }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="collapse navbar-collapse" id="app-navbar-collapse">
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<!-- Left Side Of Navbar -->
|
||||
<ul class="nav navbar-nav">
|
||||
|
||||
<ul class="navbar-nav mr-auto">
|
||||
|
||||
</ul>
|
||||
|
||||
<!-- Right Side Of Navbar -->
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<!-- Authentication Links -->
|
||||
@guest
|
||||
<li><a href="{{ route('login') }}">Login</a></li>
|
||||
<li><a href="{{ route('register') }}">Register</a></li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" v-pre>
|
||||
<li class="nav-item dropdown">
|
||||
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
|
||||
{{ Auth::user()->name }} <span class="caret"></span>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="{{ route('logout') }}"
|
||||
onclick="event.preventDefault();
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
|
||||
<a class="dropdown-item" href="{{ route('logout') }}"
|
||||
onclick="event.preventDefault();
|
||||
document.getElementById('logout-form').submit();">
|
||||
Logout
|
||||
</a>
|
||||
{{ __('Logout') }}
|
||||
</a>
|
||||
|
||||
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
|
||||
{{ csrf_field() }}
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
|
||||
@csrf
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
@endguest
|
||||
</ul>
|
||||
@@ -71,10 +71,9 @@
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@yield('content')
|
||||
<main class="py-4">
|
||||
@yield('content')
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="{{ asset('js/app.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -4,6 +4,7 @@ namespace Illuminate\Auth;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
|
||||
@@ -110,7 +111,13 @@ class DatabaseUserProvider implements UserProvider
|
||||
$query = $this->conn->table($this->table);
|
||||
|
||||
foreach ($credentials as $key => $value) {
|
||||
if (! Str::contains($key, 'password')) {
|
||||
if (Str::contains($key, 'password')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_array($value) || $value instanceof Arrayable) {
|
||||
$query->whereIn($key, $value);
|
||||
} else {
|
||||
$query->where($key, $value);
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ namespace Illuminate\Auth;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
|
||||
|
||||
@@ -113,7 +114,13 @@ class EloquentUserProvider implements UserProvider
|
||||
$query = $this->createModel()->newQuery();
|
||||
|
||||
foreach ($credentials as $key => $value) {
|
||||
if (! Str::contains($key, 'password')) {
|
||||
if (Str::contains($key, 'password')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_array($value) || $value instanceof Arrayable) {
|
||||
$query->whereIn($key, $value);
|
||||
} else {
|
||||
$query->where($key, $value);
|
||||
}
|
||||
}
|
||||
|
@@ -40,6 +40,16 @@ trait GuardHelpers
|
||||
throw new AuthenticationException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the guard has a user instance.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUser()
|
||||
{
|
||||
return ! is_null($this->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the current user is authenticated.
|
||||
*
|
||||
|
@@ -42,7 +42,7 @@ class Authorize
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string $ability
|
||||
* @param array|null $models
|
||||
* @param array|null ...$models
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Illuminate\Auth\AuthenticationException
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Illuminate\Auth\Notifications;
|
||||
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
|
||||
@@ -14,6 +15,13 @@ class ResetPassword extends Notification
|
||||
*/
|
||||
public $token;
|
||||
|
||||
/**
|
||||
* The callback that should be used to build the mail message.
|
||||
*
|
||||
* @var \Closure|null
|
||||
*/
|
||||
public static $toMailCallback;
|
||||
|
||||
/**
|
||||
* Create a notification instance.
|
||||
*
|
||||
@@ -44,9 +52,25 @@ class ResetPassword extends Notification
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
if (static::$toMailCallback) {
|
||||
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
|
||||
}
|
||||
|
||||
return (new MailMessage)
|
||||
->line('You are receiving this email because we received a password reset request for your account.')
|
||||
->action('Reset Password', url(config('app.url').route('password.reset', $this->token, false)))
|
||||
->line('If you did not request a password reset, no further action is required.');
|
||||
->subject(Lang::getFromJson('Reset Password Notification'))
|
||||
->line(Lang::getFromJson('You are receiving this email because we received a password reset request for your account.'))
|
||||
->action(Lang::getFromJson('Reset Password'), url(config('app.url').route('password.reset', $this->token, false)))
|
||||
->line(Lang::getFromJson('If you did not request a password reset, no further action is required.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback that should be used when building the notification mail message.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
public static function toMailUsing($callback)
|
||||
{
|
||||
static::$toMailCallback = $callback;
|
||||
}
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ class PasswordBrokerManager implements FactoryContract
|
||||
/**
|
||||
* Attempt to get the broker from the local cache.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $name
|
||||
* @return \Illuminate\Contracts\Auth\PasswordBroker
|
||||
*/
|
||||
public function broker($name = null)
|
||||
|
@@ -4,6 +4,7 @@ namespace Illuminate\Auth;
|
||||
|
||||
use RuntimeException;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Contracts\Session\Session;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
@@ -90,7 +91,7 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
* @param string $name
|
||||
* @param \Illuminate\Contracts\Auth\UserProvider $provider
|
||||
* @param \Illuminate\Contracts\Session\Session $session
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* @param \Symfony\Component\HttpFoundation\Request|null $request
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($name,
|
||||
@@ -533,6 +534,26 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
|
||||
$this->provider->updateRememberToken($user, $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate other sessions for the current user.
|
||||
*
|
||||
* The application must be using the AuthenticateSession middleware.
|
||||
*
|
||||
* @param string $password
|
||||
* @param string $attribute
|
||||
* @return null|bool
|
||||
*/
|
||||
public function logoutOtherDevices($password, $attribute = 'password')
|
||||
{
|
||||
if (! $this->user()) {
|
||||
return;
|
||||
}
|
||||
|
||||
return tap($this->user()->forceFill([
|
||||
$attribute => Hash::make($password),
|
||||
]))->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an authentication attempt event listener.
|
||||
*
|
||||
|
@@ -36,14 +36,16 @@ class TokenGuard implements Guard
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\UserProvider $provider
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $inputKey
|
||||
* @param string $storageKey
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(UserProvider $provider, Request $request)
|
||||
public function __construct(UserProvider $provider, Request $request, $inputKey = 'api_token', $storageKey = 'api_token')
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->provider = $provider;
|
||||
$this->inputKey = 'api_token';
|
||||
$this->storageKey = 'api_token';
|
||||
$this->inputKey = $inputKey;
|
||||
$this->storageKey = $storageKey;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -14,11 +14,11 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"illuminate/contracts": "5.5.*",
|
||||
"illuminate/http": "5.5.*",
|
||||
"illuminate/queue": "5.5.*",
|
||||
"illuminate/support": "5.5.*"
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.6.*",
|
||||
"illuminate/http": "5.6.*",
|
||||
"illuminate/queue": "5.6.*",
|
||||
"illuminate/support": "5.6.*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -27,13 +27,13 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.5-dev"
|
||||
"dev-master": "5.6-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/console": "Required to use the auth:clear-resets command (5.5.*).",
|
||||
"illuminate/queue": "Required to fire login / logout events (5.5.*).",
|
||||
"illuminate/session": "Required to use the session based guard (5.5.*)."
|
||||
"illuminate/console": "Required to use the auth:clear-resets command (5.6.*).",
|
||||
"illuminate/queue": "Required to fire login / logout events (5.6.*).",
|
||||
"illuminate/session": "Required to use the session based guard (5.6.*)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
|
@@ -65,7 +65,10 @@ class BroadcastManager implements FactoryContract
|
||||
$attributes = $attributes ?: ['middleware' => ['web']];
|
||||
|
||||
$this->app['router']->group($attributes, function ($router) {
|
||||
$router->post('/broadcasting/auth', '\\'.BroadcastController::class.'@authenticate');
|
||||
$router->match(
|
||||
['get', 'post'], '/broadcasting/auth',
|
||||
'\\'.BroadcastController::class.'@authenticate'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -140,7 +143,7 @@ class BroadcastManager implements FactoryContract
|
||||
/**
|
||||
* Get a driver instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function driver($name = null)
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Illuminate\Broadcasting\Broadcasters;
|
||||
|
||||
use Exception;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Container\Container;
|
||||
@@ -30,10 +32,10 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
* Register a channel authenticator.
|
||||
*
|
||||
* @param string $channel
|
||||
* @param callable $callback
|
||||
* @param callable|string $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function channel($channel, callable $callback)
|
||||
public function channel($channel, $callback)
|
||||
{
|
||||
$this->channels[$channel] = $callback;
|
||||
|
||||
@@ -57,7 +59,9 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
|
||||
$parameters = $this->extractAuthParameters($pattern, $channel, $callback);
|
||||
|
||||
if ($result = $callback($request->user(), ...$parameters)) {
|
||||
$handler = $this->normalizeChannelHandlerToCallable($callback);
|
||||
|
||||
if ($result = $handler($request->user(), ...$parameters)) {
|
||||
return $this->validAuthenticationResponse($request, $result);
|
||||
}
|
||||
}
|
||||
@@ -70,12 +74,12 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
*
|
||||
* @param string $pattern
|
||||
* @param string $channel
|
||||
* @param callable $callback
|
||||
* @param callable|string $callback
|
||||
* @return array
|
||||
*/
|
||||
protected function extractAuthParameters($pattern, $channel, $callback)
|
||||
{
|
||||
$callbackParameters = (new ReflectionFunction($callback))->getParameters();
|
||||
$callbackParameters = $this->extractParameters($callback);
|
||||
|
||||
return collect($this->extractChannelKeys($pattern, $channel))->reject(function ($value, $key) {
|
||||
return is_numeric($key);
|
||||
@@ -84,6 +88,42 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
})->values()->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the parameters out of what the user passed to handle the channel authentication.
|
||||
*
|
||||
* @param callable|string $callback
|
||||
* @return \ReflectionParameter[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function extractParameters($callback)
|
||||
{
|
||||
if (is_callable($callback)) {
|
||||
return (new ReflectionFunction($callback))->getParameters();
|
||||
} elseif (is_string($callback)) {
|
||||
return $this->extractParametersFromClass($callback);
|
||||
}
|
||||
|
||||
throw new Exception('Given channel handler is an unknown type.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the parameters out of a class channel's "join" method.
|
||||
*
|
||||
* @param string $callback
|
||||
* @return \ReflectionParameter[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function extractParametersFromClass($callback)
|
||||
{
|
||||
$reflection = new ReflectionClass($callback);
|
||||
|
||||
if (! $reflection->hasMethod('join')) {
|
||||
throw new Exception('Class based channel must define a "join" method.');
|
||||
}
|
||||
|
||||
return $reflection->getMethod('join')->getParameters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the channel keys from the incoming channel name.
|
||||
*
|
||||
@@ -201,4 +241,19 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
|
||||
return $this->bindingRegistrar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the given callback into a callable.
|
||||
*
|
||||
* @param mixed $callback
|
||||
* @return callable|\Closure
|
||||
*/
|
||||
protected function normalizeChannelHandlerToCallable($callback)
|
||||
{
|
||||
return is_callable($callback) ? $callback : function (...$args) use ($callback) {
|
||||
return Container::getInstance()
|
||||
->make($callback)
|
||||
->join(...$args);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -62,25 +62,34 @@ class PusherBroadcaster extends Broadcaster
|
||||
{
|
||||
if (Str::startsWith($request->channel_name, 'private')) {
|
||||
return $this->decodePusherResponse(
|
||||
$this->pusher->socket_auth($request->channel_name, $request->socket_id)
|
||||
$request, $this->pusher->socket_auth($request->channel_name, $request->socket_id)
|
||||
);
|
||||
}
|
||||
|
||||
return $this->decodePusherResponse(
|
||||
$request,
|
||||
$this->pusher->presence_auth(
|
||||
$request->channel_name, $request->socket_id, $request->user()->getAuthIdentifier(), $result)
|
||||
$request->channel_name, $request->socket_id,
|
||||
$request->user()->getAuthIdentifier(), $result
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the given Pusher response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param mixed $response
|
||||
* @return array
|
||||
*/
|
||||
protected function decodePusherResponse($response)
|
||||
protected function decodePusherResponse($request, $response)
|
||||
{
|
||||
return json_decode($response, true);
|
||||
if (! $request->input('callback', false)) {
|
||||
return json_decode($response, true);
|
||||
}
|
||||
|
||||
return response()->json(json_decode($response, true))
|
||||
->withCallback($request->callback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -27,7 +27,7 @@ class RedisBroadcaster extends Broadcaster
|
||||
* Create a new broadcaster instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Redis\Factory $redis
|
||||
* @param string $connection
|
||||
* @param string|null $connection
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Redis $redis, $connection = null)
|
||||
|
@@ -14,12 +14,12 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"php": "^7.1.3",
|
||||
"psr/log": "~1.0",
|
||||
"illuminate/bus": "5.5.*",
|
||||
"illuminate/contracts": "5.5.*",
|
||||
"illuminate/queue": "5.5.*",
|
||||
"illuminate/support": "5.5.*"
|
||||
"illuminate/bus": "5.6.*",
|
||||
"illuminate/contracts": "5.6.*",
|
||||
"illuminate/queue": "5.6.*",
|
||||
"illuminate/support": "5.6.*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -28,7 +28,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.5-dev"
|
||||
"dev-master": "5.6-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
|
@@ -14,10 +14,10 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"illuminate/contracts": "5.5.*",
|
||||
"illuminate/pipeline": "5.5.*",
|
||||
"illuminate/support": "5.5.*"
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.6.*",
|
||||
"illuminate/pipeline": "5.6.*",
|
||||
"illuminate/support": "5.6.*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -26,7 +26,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.5-dev"
|
||||
"dev-master": "5.6-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@@ -23,9 +23,7 @@ class ArrayStore extends TaggableStore implements Store
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if (array_key_exists($key, $this->storage)) {
|
||||
return $this->storage[$key];
|
||||
}
|
||||
return $this->storage[$key] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -61,7 +61,7 @@ class CacheManager implements FactoryContract
|
||||
/**
|
||||
* Get a cache driver instance.
|
||||
*
|
||||
* @param string $driver
|
||||
* @param string|null $driver
|
||||
* @return mixed
|
||||
*/
|
||||
public function driver($driver = null)
|
||||
|
@@ -72,7 +72,7 @@ class ClearCommand extends Command
|
||||
'cache:cleared', [$this->argument('store'), $this->tags()]
|
||||
);
|
||||
|
||||
$this->info('Cache cleared successfully.');
|
||||
$this->info('Application cache cleared!');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,11 @@ class ClearCommand extends Command
|
||||
*/
|
||||
public function flushFacades()
|
||||
{
|
||||
foreach ($this->files->files(storage_path('framework/cache')) as $file) {
|
||||
if (! $this->files->exists($storagePath = storage_path('framework/cache'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->files->files($storagePath) as $file) {
|
||||
if (preg_match('/facade-.*\.php$/', $file)) {
|
||||
$this->files->delete($file);
|
||||
}
|
||||
|
@@ -91,7 +91,7 @@ class FileStore implements Store
|
||||
$raw = $this->getPayload($key);
|
||||
|
||||
return tap(((int) $raw['data']) + $value, function ($newValue) use ($key, $raw) {
|
||||
$this->put($key, $newValue, $raw['time']);
|
||||
$this->put($key, $newValue, $raw['time'] ?? 0);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -47,7 +47,7 @@ class MemcachedConnector
|
||||
{
|
||||
$memcached = $this->createMemcachedInstance($connectionId);
|
||||
|
||||
if (count($credentials) == 2) {
|
||||
if (count($credentials) === 2) {
|
||||
$this->setCredentials($memcached, $credentials);
|
||||
}
|
||||
|
||||
|
@@ -32,10 +32,9 @@ class RateLimiter
|
||||
*
|
||||
* @param string $key
|
||||
* @param int $maxAttempts
|
||||
* @param float|int $decayMinutes
|
||||
* @return bool
|
||||
*/
|
||||
public function tooManyAttempts($key, $maxAttempts, $decayMinutes = 1)
|
||||
public function tooManyAttempts($key, $maxAttempts)
|
||||
{
|
||||
if ($this->attempts($key) >= $maxAttempts) {
|
||||
if ($this->cache->has($key.':timer')) {
|
||||
|
@@ -22,7 +22,7 @@ class RedisTaggedCache extends TaggedCache
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTime|float|int $minutes
|
||||
* @param \DateTime|float|int|null $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes = null)
|
||||
@@ -32,6 +32,34 @@ class RedisTaggedCache extends TaggedCache
|
||||
parent::put($key, $value, $minutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
{
|
||||
$this->pushStandardKeys($this->tags->getNamespace(), $key);
|
||||
|
||||
parent::increment($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
{
|
||||
$this->pushStandardKeys($this->tags->getNamespace(), $key);
|
||||
|
||||
parent::decrement($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
|
@@ -182,7 +182,7 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTimeInterface|\DateInterval|float|int $minutes
|
||||
* @param \DateTimeInterface|\DateInterval|float|int|null $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes = null)
|
||||
@@ -419,7 +419,7 @@ class Repository implements CacheContract, ArrayAccess
|
||||
throw new BadMethodCallException('This cache store does not support tagging.');
|
||||
}
|
||||
|
||||
$cache = $this->store->tags($names);
|
||||
$cache = $this->store->tags(is_array($names) ? $names : func_get_args());
|
||||
|
||||
if (! is_null($this->events)) {
|
||||
$cache->setEventDispatcher($this->events);
|
||||
|
@@ -42,7 +42,7 @@ class TaggedCache extends Repository
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
|
@@ -14,9 +14,9 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"illuminate/contracts": "5.5.*",
|
||||
"illuminate/support": "5.5.*"
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.6.*",
|
||||
"illuminate/support": "5.6.*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -25,13 +25,13 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.5-dev"
|
||||
"dev-master": "5.6-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/database": "Required to use the database cache driver (5.5.*).",
|
||||
"illuminate/filesystem": "Required to use the file cache driver (5.5.*).",
|
||||
"illuminate/redis": "Required to use the redis cache driver (5.5.*)."
|
||||
"illuminate/database": "Required to use the database cache driver (5.6.*).",
|
||||
"illuminate/filesystem": "Required to use the file cache driver (5.6.*).",
|
||||
"illuminate/redis": "Required to use the redis cache driver (5.6.*)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
|
@@ -14,9 +14,9 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"illuminate/contracts": "5.5.*",
|
||||
"illuminate/support": "5.5.*"
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.6.*",
|
||||
"illuminate/support": "5.6.*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.5-dev"
|
||||
"dev-master": "5.6-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@@ -16,6 +16,7 @@ use Symfony\Component\Console\Output\BufferedOutput;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Application as SymfonyApplication;
|
||||
use Symfony\Component\Console\Command\Command as SymfonyCommand;
|
||||
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||
use Illuminate\Contracts\Console\Application as ApplicationContract;
|
||||
|
||||
class Application extends SymfonyApplication implements ApplicationContract
|
||||
@@ -163,18 +164,28 @@ class Application extends SymfonyApplication implements ApplicationContract
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $parameters
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $outputBuffer
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface|null $outputBuffer
|
||||
* @return int
|
||||
*
|
||||
* @throws \Symfony\Component\Console\Exception\CommandNotFoundException
|
||||
*/
|
||||
public function call($command, array $parameters = [], $outputBuffer = null)
|
||||
{
|
||||
$parameters = collect($parameters)->prepend($command);
|
||||
if (is_subclass_of($command, SymfonyCommand::class)) {
|
||||
$command = $this->laravel->make($command)->getName();
|
||||
}
|
||||
|
||||
if (! $this->has($command)) {
|
||||
throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $command));
|
||||
}
|
||||
|
||||
array_unshift($parameters, $command);
|
||||
|
||||
$this->lastOutput = $outputBuffer ?: new BufferedOutput;
|
||||
|
||||
$this->setCatchExceptions(false);
|
||||
|
||||
$result = $this->run(new ArrayInput($parameters->toArray()), $this->lastOutput);
|
||||
$result = $this->run(new ArrayInput($parameters), $this->lastOutput);
|
||||
|
||||
$this->setCatchExceptions(true);
|
||||
|
||||
@@ -188,7 +199,9 @@ class Application extends SymfonyApplication implements ApplicationContract
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
return $this->lastOutput ? $this->lastOutput->fetch() : '';
|
||||
return $this->lastOutput && method_exists($this->lastOutput, 'fetch')
|
||||
? $this->lastOutput->fetch()
|
||||
: '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
@@ -245,7 +246,7 @@ class Command extends SymfonyCommand
|
||||
* Get the value of a command argument.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @return string|array
|
||||
* @return string|array|null
|
||||
*/
|
||||
public function argument($key = null)
|
||||
{
|
||||
@@ -280,8 +281,8 @@ class Command extends SymfonyCommand
|
||||
/**
|
||||
* Get the value of a command option.
|
||||
*
|
||||
* @param string $key
|
||||
* @return string|array
|
||||
* @param string|null $key
|
||||
* @return string|array|null
|
||||
*/
|
||||
public function option($key = null)
|
||||
{
|
||||
@@ -318,7 +319,7 @@ class Command extends SymfonyCommand
|
||||
* Prompt the user for input.
|
||||
*
|
||||
* @param string $question
|
||||
* @param string $default
|
||||
* @param string|null $default
|
||||
* @return string
|
||||
*/
|
||||
public function ask($question, $default = null)
|
||||
@@ -331,7 +332,7 @@ class Command extends SymfonyCommand
|
||||
*
|
||||
* @param string $question
|
||||
* @param array $choices
|
||||
* @param string $default
|
||||
* @param string|null $default
|
||||
* @return string
|
||||
*/
|
||||
public function anticipate($question, array $choices, $default = null)
|
||||
@@ -344,7 +345,7 @@ class Command extends SymfonyCommand
|
||||
*
|
||||
* @param string $question
|
||||
* @param array $choices
|
||||
* @param string $default
|
||||
* @param string|null $default
|
||||
* @return string
|
||||
*/
|
||||
public function askWithCompletion($question, array $choices, $default = null)
|
||||
@@ -377,9 +378,9 @@ class Command extends SymfonyCommand
|
||||
*
|
||||
* @param string $question
|
||||
* @param array $choices
|
||||
* @param string $default
|
||||
* @param mixed $attempts
|
||||
* @param bool $multiple
|
||||
* @param string|null $default
|
||||
* @param mixed|null $attempts
|
||||
* @param bool|null $multiple
|
||||
* @return string
|
||||
*/
|
||||
public function choice($question, array $choices, $default = null, $attempts = null, $multiple = null)
|
||||
@@ -506,9 +507,11 @@ class Command extends SymfonyCommand
|
||||
*/
|
||||
public function alert($string)
|
||||
{
|
||||
$this->comment(str_repeat('*', strlen($string) + 12));
|
||||
$length = Str::length(strip_tags($string)) + 12;
|
||||
|
||||
$this->comment(str_repeat('*', $length));
|
||||
$this->comment('* '.$string.' *');
|
||||
$this->comment(str_repeat('*', strlen($string) + 12));
|
||||
$this->comment(str_repeat('*', $length));
|
||||
|
||||
$this->output->newLine();
|
||||
}
|
||||
@@ -527,7 +530,7 @@ class Command extends SymfonyCommand
|
||||
/**
|
||||
* Get the verbosity level in terms of Symfony's OutputInterface level.
|
||||
*
|
||||
* @param string|int $level
|
||||
* @param string|int|null $level
|
||||
* @return int
|
||||
*/
|
||||
protected function parseVerbosity($level = null)
|
||||
|
@@ -56,7 +56,9 @@ abstract class GeneratorCommand extends Command
|
||||
// First 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') || ! $this->option('force')) && $this->alreadyExists($this->getNameInput())) {
|
||||
if ((! $this->hasOption('force') ||
|
||||
! $this->option('force')) &&
|
||||
$this->alreadyExists($this->getNameInput())) {
|
||||
$this->error($this->type.' already exists!');
|
||||
|
||||
return false;
|
||||
|
81
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheEventMutex.php
vendored
Normal file
81
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheEventMutex.php
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Contracts\Cache\Factory as Cache;
|
||||
|
||||
class CacheEventMutex implements EventMutex
|
||||
{
|
||||
/**
|
||||
* The cache repository implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Cache\Factory
|
||||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* The cache store that should be used.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $store;
|
||||
|
||||
/**
|
||||
* Create a new overlapping strategy.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Cache\Factory $cache
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to obtain an event mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return bool
|
||||
*/
|
||||
public function create(Event $event)
|
||||
{
|
||||
return $this->cache->store($this->store)->add(
|
||||
$event->mutexName(), true, $event->expiresAt
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an event mutex exists for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(Event $event)
|
||||
{
|
||||
return $this->cache->store($this->store)->has($event->mutexName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the event mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
||||
*/
|
||||
public function forget(Event $event)
|
||||
{
|
||||
$this->cache->store($this->store)->forget($event->mutexName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the cache store that should be used.
|
||||
*
|
||||
* @param string $store
|
||||
* @return $this
|
||||
*/
|
||||
public function useStore($store)
|
||||
{
|
||||
$this->store = $store;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||
|
||||
class CacheMutex implements Mutex
|
||||
{
|
||||
/**
|
||||
* The cache repository implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Cache\Repository
|
||||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* Create a new overlapping strategy.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Cache\Repository $cache
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to obtain a mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return bool
|
||||
*/
|
||||
public function create(Event $event)
|
||||
{
|
||||
return $this->cache->add(
|
||||
$event->mutexName(), true, $event->expiresAt
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a mutex exists for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(Event $event)
|
||||
{
|
||||
return $this->cache->has($event->mutexName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
||||
*/
|
||||
public function forget(Event $event)
|
||||
{
|
||||
$this->cache->forget($event->mutexName());
|
||||
}
|
||||
}
|
75
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheSchedulingMutex.php
vendored
Normal file
75
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheSchedulingMutex.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Contracts\Cache\Factory as Cache;
|
||||
|
||||
class CacheSchedulingMutex implements SchedulingMutex
|
||||
{
|
||||
/**
|
||||
* The cache factory implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Cache\Factory
|
||||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* The cache store that should be used.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $store;
|
||||
|
||||
/**
|
||||
* Create a new scheduling strategy.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Cache\Factory $cache
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to obtain a scheduling mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeInterface $time
|
||||
* @return bool
|
||||
*/
|
||||
public function create(Event $event, DateTimeInterface $time)
|
||||
{
|
||||
return $this->cache->store($this->store)->add(
|
||||
$event->mutexName().$time->format('Hi'), true, 60
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a scheduling mutex exists for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeInterface $time
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(Event $event, DateTimeInterface $time)
|
||||
{
|
||||
return $this->cache->store($this->store)->has(
|
||||
$event->mutexName().$time->format('Hi')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the cache store that should be used.
|
||||
*
|
||||
* @param string $store
|
||||
* @return $this
|
||||
*/
|
||||
public function useStore($store)
|
||||
{
|
||||
$this->store = $store;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -25,14 +25,14 @@ class CallbackEvent extends Event
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Mutex $mutex
|
||||
* @param \Illuminate\Console\Scheduling\EventMutex $mutex
|
||||
* @param string $callback
|
||||
* @param array $parameters
|
||||
* @return void
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(Mutex $mutex, $callback, array $parameters = [])
|
||||
public function __construct(EventMutex $mutex, $callback, array $parameters = [])
|
||||
{
|
||||
if (! is_string($callback) && ! is_callable($callback)) {
|
||||
throw new InvalidArgumentException(
|
||||
@@ -98,6 +98,8 @@ class CallbackEvent extends Event
|
||||
*
|
||||
* @param int $expiresAt
|
||||
* @return $this
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function withoutOverlapping($expiresAt = 1440)
|
||||
{
|
||||
@@ -116,6 +118,26 @@ class CallbackEvent extends Event
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow the event to only run on one server for each cron expression.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function onOneServer()
|
||||
{
|
||||
if (! isset($this->description)) {
|
||||
throw new LogicException(
|
||||
"A scheduled event name is required to only run on one server. Use the 'name' method before 'onOneServer'."
|
||||
);
|
||||
}
|
||||
|
||||
$this->onOneServer = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mutex name for the scheduled command.
|
||||
*
|
||||
|
@@ -4,6 +4,7 @@ namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Closure;
|
||||
use Cron\CronExpression;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Carbon;
|
||||
use GuzzleHttp\Client as HttpClient;
|
||||
use Illuminate\Contracts\Mail\Mailer;
|
||||
@@ -27,7 +28,7 @@ class Event
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $expression = '* * * * * *';
|
||||
public $expression = '* * * * *';
|
||||
|
||||
/**
|
||||
* The timezone the date should be evaluated on.
|
||||
@@ -64,6 +65,13 @@ class Event
|
||||
*/
|
||||
public $withoutOverlapping = false;
|
||||
|
||||
/**
|
||||
* Indicates if the command should only be allowed to run on one server for each cron expression.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $onOneServer = false;
|
||||
|
||||
/**
|
||||
* The amount of time the mutex should be valid.
|
||||
*
|
||||
@@ -128,20 +136,20 @@ class Event
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* The mutex implementation.
|
||||
* The event mutex implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Mutex
|
||||
* @var \Illuminate\Console\Scheduling\EventMutex
|
||||
*/
|
||||
public $mutex;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Mutex $mutex
|
||||
* @param \Illuminate\Console\Scheduling\EventMutex $mutex
|
||||
* @param string $command
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Mutex $mutex, $command)
|
||||
public function __construct(EventMutex $mutex, $command)
|
||||
{
|
||||
$this->mutex = $mutex;
|
||||
$this->command = $command;
|
||||
@@ -370,7 +378,7 @@ class Event
|
||||
{
|
||||
$this->ensureOutputIsBeingCapturedForEmail();
|
||||
|
||||
$addresses = is_array($addresses) ? $addresses : [$addresses];
|
||||
$addresses = Arr::wrap($addresses);
|
||||
|
||||
return $this->then(function (Mailer $mailer) use ($addresses, $onlyIfOutputExists) {
|
||||
$this->emailOutput($mailer, $addresses, $onlyIfOutputExists);
|
||||
@@ -450,6 +458,18 @@ class Event
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL before the job runs if the given condition is true.
|
||||
*
|
||||
* @param bool $value
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function pingBeforeIf($value, $url)
|
||||
{
|
||||
return $value ? $this->pingBefore($url) : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL after the job runs.
|
||||
*
|
||||
@@ -463,6 +483,18 @@ class Event
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL after the job runs if the given condition is true.
|
||||
*
|
||||
* @param bool $value
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function thenPingIf($value, $url)
|
||||
{
|
||||
return $value ? $this->thenPing($url) : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* State that the command should run in background.
|
||||
*
|
||||
@@ -532,6 +564,18 @@ class Event
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow the event to only run on one server for each cron expression.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function onOneServer()
|
||||
{
|
||||
$this->onOneServer = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to further filter the schedule.
|
||||
*
|
||||
@@ -663,12 +707,12 @@ class Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mutex implementation to be used.
|
||||
* Set the event mutex implementation to be used.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Mutex $mutex
|
||||
* @param \Illuminate\Console\Scheduling\EventMutex $mutex
|
||||
* @return $this
|
||||
*/
|
||||
public function preventOverlapsUsing(Mutex $mutex)
|
||||
public function preventOverlapsUsing(EventMutex $mutex)
|
||||
{
|
||||
$this->mutex = $mutex;
|
||||
|
||||
|
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
interface Mutex
|
||||
interface EventMutex
|
||||
{
|
||||
/**
|
||||
* Attempt to obtain a mutex for the given event.
|
||||
* Attempt to obtain an event mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return bool
|
||||
@@ -13,7 +13,7 @@ interface Mutex
|
||||
public function create(Event $event);
|
||||
|
||||
/**
|
||||
* Determine if a mutex exists for the given event.
|
||||
* Determine if an event mutex exists for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return bool
|
||||
@@ -21,7 +21,7 @@ interface Mutex
|
||||
public function exists(Event $event);
|
||||
|
||||
/**
|
||||
* Clear the mutex for the given event.
|
||||
* Clear the event mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Console\Application;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Support\ProcessUtils;
|
||||
@@ -17,11 +18,18 @@ class Schedule
|
||||
protected $events = [];
|
||||
|
||||
/**
|
||||
* The mutex implementation.
|
||||
* The event mutex implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Mutex
|
||||
* @var \Illuminate\Console\Scheduling\EventMutex
|
||||
*/
|
||||
protected $mutex;
|
||||
protected $eventMutex;
|
||||
|
||||
/**
|
||||
* The scheduling mutex implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\SchedulingMutex
|
||||
*/
|
||||
protected $schedulingMutex;
|
||||
|
||||
/**
|
||||
* Create a new schedule instance.
|
||||
@@ -32,9 +40,13 @@ class Schedule
|
||||
{
|
||||
$container = Container::getInstance();
|
||||
|
||||
$this->mutex = $container->bound(Mutex::class)
|
||||
? $container->make(Mutex::class)
|
||||
: $container->make(CacheMutex::class);
|
||||
$this->eventMutex = $container->bound(EventMutex::class)
|
||||
? $container->make(EventMutex::class)
|
||||
: $container->make(CacheEventMutex::class);
|
||||
|
||||
$this->schedulingMutex = $container->bound(SchedulingMutex::class)
|
||||
? $container->make(SchedulingMutex::class)
|
||||
: $container->make(CacheSchedulingMutex::class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,7 +59,7 @@ class Schedule
|
||||
public function call($callback, array $parameters = [])
|
||||
{
|
||||
$this->events[] = $event = new CallbackEvent(
|
||||
$this->mutex, $callback, $parameters
|
||||
$this->eventMutex, $callback, $parameters
|
||||
);
|
||||
|
||||
return $event;
|
||||
@@ -104,7 +116,7 @@ class Schedule
|
||||
$command .= ' '.$this->compileParameters($parameters);
|
||||
}
|
||||
|
||||
$this->events[] = $event = new Event($this->mutex, $command);
|
||||
$this->events[] = $event = new Event($this->eventMutex, $command);
|
||||
|
||||
return $event;
|
||||
}
|
||||
@@ -130,6 +142,18 @@ class Schedule
|
||||
})->implode(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the server is allowed to run this event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeInterface $time
|
||||
* @return bool
|
||||
*/
|
||||
public function serverShouldRun(Event $event, DateTimeInterface $time)
|
||||
{
|
||||
return $this->schedulingMutex->create($event, $time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the events on the schedule that are due.
|
||||
*
|
||||
@@ -150,4 +174,23 @@ class Schedule
|
||||
{
|
||||
return $this->events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the cache store that should be used to store mutexes.
|
||||
*
|
||||
* @param string $store
|
||||
* @return $this
|
||||
*/
|
||||
public function useCache($store)
|
||||
{
|
||||
if ($this->eventMutex instanceof CacheEventMutex) {
|
||||
$this->eventMutex->useStore($store);
|
||||
}
|
||||
|
||||
if ($this->schedulingMutex instanceof CacheSchedulingMutex) {
|
||||
$this->schedulingMutex->useStore($store);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class ScheduleRunCommand extends Command
|
||||
@@ -27,6 +28,20 @@ class ScheduleRunCommand extends Command
|
||||
*/
|
||||
protected $schedule;
|
||||
|
||||
/**
|
||||
* The 24 hour timestamp this scheduler command started running.
|
||||
*
|
||||
* @var \Illuminate\Support\Carbon;
|
||||
*/
|
||||
protected $startedAt;
|
||||
|
||||
/**
|
||||
* Check if any events ran.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $eventsRan = false;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
@@ -37,6 +52,8 @@ class ScheduleRunCommand extends Command
|
||||
{
|
||||
$this->schedule = $schedule;
|
||||
|
||||
$this->startedAt = Carbon::now();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
@@ -47,22 +64,52 @@ class ScheduleRunCommand extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$eventsRan = false;
|
||||
|
||||
foreach ($this->schedule->dueEvents($this->laravel) as $event) {
|
||||
if (! $event->filtersPass($this->laravel)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->line('<info>Running scheduled command:</info> '.$event->getSummaryForDisplay());
|
||||
if ($event->onOneServer) {
|
||||
$this->runSingleServerEvent($event);
|
||||
} else {
|
||||
$this->runEvent($event);
|
||||
}
|
||||
|
||||
$event->run($this->laravel);
|
||||
|
||||
$eventsRan = true;
|
||||
$this->eventsRan = true;
|
||||
}
|
||||
|
||||
if (! $eventsRan) {
|
||||
if (! $this->eventsRan) {
|
||||
$this->info('No scheduled commands are ready to run.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the given single server event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
||||
*/
|
||||
protected function runSingleServerEvent($event)
|
||||
{
|
||||
if ($this->schedule->serverShouldRun($event, $this->startedAt)) {
|
||||
$this->runEvent($event);
|
||||
} else {
|
||||
$this->line('<info>Skipping command (has already run on another server):</info> '.$event->getSummaryForDisplay());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
||||
*/
|
||||
protected function runEvent($event)
|
||||
{
|
||||
$this->line('<info>Running scheduled command:</info> '.$event->getSummaryForDisplay());
|
||||
|
||||
$event->run($this->laravel);
|
||||
|
||||
$this->eventsRan = true;
|
||||
}
|
||||
}
|
||||
|
26
vendor/laravel/framework/src/Illuminate/Console/Scheduling/SchedulingMutex.php
vendored
Normal file
26
vendor/laravel/framework/src/Illuminate/Console/Scheduling/SchedulingMutex.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use DateTimeInterface;
|
||||
|
||||
interface SchedulingMutex
|
||||
{
|
||||
/**
|
||||
* Attempt to obtain a scheduling mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeInterface $time
|
||||
* @return bool
|
||||
*/
|
||||
public function create(Event $event, DateTimeInterface $time);
|
||||
|
||||
/**
|
||||
* Determine if a scheduling mutex exists for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeInterface $time
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(Event $event, DateTimeInterface $time);
|
||||
}
|
@@ -14,10 +14,10 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"illuminate/contracts": "5.5.*",
|
||||
"illuminate/support": "5.5.*",
|
||||
"symfony/console": "~3.3"
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.6.*",
|
||||
"illuminate/support": "5.6.*",
|
||||
"symfony/console": "~4.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -26,13 +26,13 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.5-dev"
|
||||
"dev-master": "5.6-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"dragonmantank/cron-expression": "Required to use scheduling component (~2.0).",
|
||||
"guzzlehttp/guzzle": "Required to use the ping methods on schedules (~6.0).",
|
||||
"mtdowling/cron-expression": "Required to use scheduling component (~1.0).",
|
||||
"symfony/process": "Required to use scheduling component (~3.3)."
|
||||
"symfony/process": "Required to use scheduling component (~4.0)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
|
@@ -152,6 +152,10 @@ class BoundMethod
|
||||
$dependencies[] = $parameters[$parameter->name];
|
||||
|
||||
unset($parameters[$parameter->name]);
|
||||
} elseif ($parameter->getClass() && array_key_exists($parameter->getClass()->name, $parameters)) {
|
||||
$dependencies[] = $parameters[$parameter->getClass()->name];
|
||||
|
||||
unset($parameters[$parameter->getClass()->name]);
|
||||
} elseif ($parameter->getClass()) {
|
||||
$dependencies[] = $container->make($parameter->getClass()->name);
|
||||
} elseif ($parameter->isDefaultValueAvailable()) {
|
||||
|
@@ -271,13 +271,28 @@ class Container implements ArrayAccess, ContainerContract
|
||||
/**
|
||||
* Bind a callback to resolve with Container::call.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array|string $method
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
public function bindMethod($method, $callback)
|
||||
{
|
||||
$this->methodBindings[$method] = $callback;
|
||||
$this->methodBindings[$this->parseBindMethod($method)] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the method to be bound in class@method format.
|
||||
*
|
||||
* @param array|string $method
|
||||
* @return string
|
||||
*/
|
||||
protected function parseBindMethod($method)
|
||||
{
|
||||
if (is_array($method)) {
|
||||
return $method[0].'@'.$method[1];
|
||||
}
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1166,7 +1181,7 @@ class Container implements ArrayAccess, ContainerContract
|
||||
* Set the shared instance of the container.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container|null $container
|
||||
* @return static
|
||||
* @return \Illuminate\Contracts\Container\Container|static
|
||||
*/
|
||||
public static function setInstance(ContainerContract $container = null)
|
||||
{
|
||||
|
@@ -14,8 +14,8 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"illuminate/contracts": "5.5.*",
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.6.*",
|
||||
"psr/container": "~1.0"
|
||||
},
|
||||
"autoload": {
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.5-dev"
|
||||
"dev-master": "5.6-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@@ -7,7 +7,7 @@ interface Factory
|
||||
/**
|
||||
* Get a broadcaster implementation by name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $name
|
||||
* @return void
|
||||
*/
|
||||
public function connection($name = null);
|
||||
|
@@ -2,14 +2,12 @@
|
||||
|
||||
namespace Illuminate\Contracts\Broadcasting;
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
|
||||
interface ShouldBroadcast
|
||||
{
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return Channel|Channel[]
|
||||
* @return \Illuminate\Broadcasting\Channel|\Illuminate\Broadcasting\Channel[]
|
||||
*/
|
||||
public function broadcastOn();
|
||||
}
|
||||
|
@@ -21,6 +21,22 @@ interface Dispatcher
|
||||
*/
|
||||
public function dispatchNow($command, $handler = null);
|
||||
|
||||
/**
|
||||
* Determine if the given command has a handler.
|
||||
*
|
||||
* @param mixed $command
|
||||
* @return bool
|
||||
*/
|
||||
public function hasCommandHandler($command);
|
||||
|
||||
/**
|
||||
* Retrieve the handler for a command.
|
||||
*
|
||||
* @param mixed $command
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function getCommandHandler($command);
|
||||
|
||||
/**
|
||||
* Set the pipes commands should be piped through before dispatching.
|
||||
*
|
||||
@@ -28,4 +44,12 @@ interface Dispatcher
|
||||
* @return $this
|
||||
*/
|
||||
public function pipeThrough(array $pipes);
|
||||
|
||||
/**
|
||||
* Map a command to a handler.
|
||||
*
|
||||
* @param array $map
|
||||
* @return $this
|
||||
*/
|
||||
public function map(array $map);
|
||||
}
|
||||
|
@@ -5,13 +5,14 @@ namespace Illuminate\Contracts\Console;
|
||||
interface Application
|
||||
{
|
||||
/**
|
||||
* Call a console application command.
|
||||
* Run an Artisan console command by name.
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $parameters
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface|null $outputBuffer
|
||||
* @return int
|
||||
*/
|
||||
public function call($command, array $parameters = []);
|
||||
public function call($command, array $parameters = [], $outputBuffer = null);
|
||||
|
||||
/**
|
||||
* Get the output from the last command.
|
||||
|
@@ -8,7 +8,7 @@ interface Kernel
|
||||
* Handle an incoming console command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface|null $output
|
||||
* @return int
|
||||
*/
|
||||
public function handle($input, $output = null);
|
||||
@@ -18,9 +18,10 @@ interface Kernel
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $parameters
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface|null $outputBuffer
|
||||
* @return int
|
||||
*/
|
||||
public function call($command, array $parameters = []);
|
||||
public function call($command, array $parameters = [], $outputBuffer = null);
|
||||
|
||||
/**
|
||||
* Queue an Artisan console command by name.
|
||||
|
@@ -14,9 +14,11 @@ interface Factory
|
||||
* @param string $domain
|
||||
* @param bool $secure
|
||||
* @param bool $httpOnly
|
||||
* @param bool $raw
|
||||
* @param string|null $sameSite
|
||||
* @return \Symfony\Component\HttpFoundation\Cookie
|
||||
*/
|
||||
public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true);
|
||||
public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null);
|
||||
|
||||
/**
|
||||
* Create a cookie that lasts "forever" (five years).
|
||||
@@ -27,9 +29,11 @@ interface Factory
|
||||
* @param string $domain
|
||||
* @param bool $secure
|
||||
* @param bool $httpOnly
|
||||
* @param bool $raw
|
||||
* @param string|null $sameSite
|
||||
* @return \Symfony\Component\HttpFoundation\Cookie
|
||||
*/
|
||||
public function forever($name, $value, $path = null, $domain = null, $secure = false, $httpOnly = true);
|
||||
public function forever($name, $value, $path = null, $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null);
|
||||
|
||||
/**
|
||||
* Expire the given cookie.
|
||||
|
@@ -20,6 +20,13 @@ class ModelIdentifier
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* The relationships loaded on the model.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $relations;
|
||||
|
||||
/**
|
||||
* The connection name of the model.
|
||||
*
|
||||
@@ -32,13 +39,15 @@ class ModelIdentifier
|
||||
*
|
||||
* @param string $class
|
||||
* @param mixed $id
|
||||
* @param array $relations
|
||||
* @param mixed $connection
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($class, $id, $connection)
|
||||
public function __construct($class, $id, array $relations, $connection)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->class = $class;
|
||||
$this->relations = $relations;
|
||||
$this->connection = $connection;
|
||||
}
|
||||
}
|
||||
|
@@ -28,12 +28,19 @@ interface Application extends Container
|
||||
public function environment();
|
||||
|
||||
/**
|
||||
* Determine if we are running in the console.
|
||||
* Determine if the application is running in the console.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function runningInConsole();
|
||||
|
||||
/**
|
||||
* Determine if the application is running unit tests.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function runningUnitTests();
|
||||
|
||||
/**
|
||||
* Determine if the application is currently down for maintenance.
|
||||
*
|
||||
|
@@ -4,6 +4,14 @@ namespace Illuminate\Contracts\Hashing;
|
||||
|
||||
interface Hasher
|
||||
{
|
||||
/**
|
||||
* Get information about the given hashed value.
|
||||
*
|
||||
* @param string $hashedValue
|
||||
* @return array
|
||||
*/
|
||||
public function info($hashedValue);
|
||||
|
||||
/**
|
||||
* Hash the given value.
|
||||
*
|
||||
|
@@ -1,98 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Logging;
|
||||
|
||||
interface Log
|
||||
{
|
||||
/**
|
||||
* Log an alert message to the logs.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return void
|
||||
*/
|
||||
public function alert($message, array $context = []);
|
||||
|
||||
/**
|
||||
* Log a critical message to the logs.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return void
|
||||
*/
|
||||
public function critical($message, array $context = []);
|
||||
|
||||
/**
|
||||
* Log an error message to the logs.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return void
|
||||
*/
|
||||
public function error($message, array $context = []);
|
||||
|
||||
/**
|
||||
* Log a warning message to the logs.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return void
|
||||
*/
|
||||
public function warning($message, array $context = []);
|
||||
|
||||
/**
|
||||
* Log a notice to the logs.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return void
|
||||
*/
|
||||
public function notice($message, array $context = []);
|
||||
|
||||
/**
|
||||
* Log an informational message to the logs.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return void
|
||||
*/
|
||||
public function info($message, array $context = []);
|
||||
|
||||
/**
|
||||
* Log a debug message to the logs.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return void
|
||||
*/
|
||||
public function debug($message, array $context = []);
|
||||
|
||||
/**
|
||||
* Log a message to the logs.
|
||||
*
|
||||
* @param string $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return void
|
||||
*/
|
||||
public function log($level, $message, array $context = []);
|
||||
|
||||
/**
|
||||
* Register a file log handler.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $level
|
||||
* @return void
|
||||
*/
|
||||
public function useFiles($path, $level = 'debug');
|
||||
|
||||
/**
|
||||
* Register a daily file log handler.
|
||||
*
|
||||
* @param string $path
|
||||
* @param int $days
|
||||
* @param string $level
|
||||
* @return void
|
||||
*/
|
||||
public function useDailyFiles($path, $days = 0, $level = 'debug');
|
||||
}
|
@@ -7,7 +7,7 @@ interface MailQueue
|
||||
/**
|
||||
* Queue a new e-mail message for sending.
|
||||
*
|
||||
* @param string|array|MailableContract $view
|
||||
* @param string|array|\Illuminate\Contracts\Mail\Mailable $view
|
||||
* @param string $queue
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -17,7 +17,7 @@ interface MailQueue
|
||||
* Queue a new e-mail message for sending after (n) seconds.
|
||||
*
|
||||
* @param \DateTimeInterface|\DateInterval|int $delay
|
||||
* @param string|array|MailableContract $view
|
||||
* @param string|array|\Illuminate\Contracts\Mail\Mailable $view
|
||||
* @param string $queue
|
||||
* @return mixed
|
||||
*/
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Illuminate\Contracts\Mail;
|
||||
|
||||
use Illuminate\Contracts\Mail\Mailable as MailableContract;
|
||||
|
||||
interface Mailer
|
||||
{
|
||||
/**
|
||||
|
@@ -4,6 +4,20 @@ namespace Illuminate\Contracts\Queue;
|
||||
|
||||
interface Job
|
||||
{
|
||||
/**
|
||||
* Get the job identifier.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getJobId();
|
||||
|
||||
/**
|
||||
* Get the decoded body of the job.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function payload();
|
||||
|
||||
/**
|
||||
* Fire the job.
|
||||
*
|
||||
|
@@ -18,6 +18,13 @@ interface QueueableCollection
|
||||
*/
|
||||
public function getQueueableIds();
|
||||
|
||||
/**
|
||||
* Get the relationships of the entities being queued.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueueableRelations();
|
||||
|
||||
/**
|
||||
* Get the connection of the entities being queued.
|
||||
*
|
||||
|
@@ -11,6 +11,13 @@ interface QueueableEntity
|
||||
*/
|
||||
public function getQueueableId();
|
||||
|
||||
/**
|
||||
* Get the relationships for the entity.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueueableRelations();
|
||||
|
||||
/**
|
||||
* Get the connection of the entity.
|
||||
*
|
||||
|
35
vendor/laravel/framework/src/Illuminate/Contracts/Redis/Connection.php
vendored
Normal file
35
vendor/laravel/framework/src/Illuminate/Contracts/Redis/Connection.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Redis;
|
||||
|
||||
use Closure;
|
||||
|
||||
interface Connection
|
||||
{
|
||||
/**
|
||||
* Subscribe to a set of given channels for messages.
|
||||
*
|
||||
* @param array|string $channels
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
public function subscribe($channels, Closure $callback);
|
||||
|
||||
/**
|
||||
* Subscribe to a set of given channels with wildcards.
|
||||
*
|
||||
* @param array|string $channels
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
public function psubscribe($channels, Closure $callback);
|
||||
|
||||
/**
|
||||
* Run a command against the Redis database.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function command($method, array $parameters = []);
|
||||
}
|
@@ -58,11 +58,22 @@ interface ResponseFactory
|
||||
*/
|
||||
public function stream($callback, $status = 200, array $headers = []);
|
||||
|
||||
/**
|
||||
* Return a new streamed response as a file download from the application.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param string|null $name
|
||||
* @param array $headers
|
||||
* @param string|null $disposition
|
||||
* @return \Symfony\Component\HttpFoundation\StreamedResponse
|
||||
*/
|
||||
public function streamDownload($callback, $name = null, array $headers = [], $disposition = 'attachment');
|
||||
|
||||
/**
|
||||
* Create a new file download response.
|
||||
*
|
||||
* @param \SplFileInfo|string $file
|
||||
* @param string $name
|
||||
* @param string|null $name
|
||||
* @param array $headers
|
||||
* @param string|null $disposition
|
||||
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
|
@@ -9,5 +9,5 @@ interface ValidatesWhenResolved
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validate();
|
||||
public function validateResolved();
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"php": "^7.1.3",
|
||||
"psr/container": "~1.0",
|
||||
"psr/simple-cache": "~1.0"
|
||||
},
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.5-dev"
|
||||
"dev-master": "5.6-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@@ -54,13 +54,13 @@ class CookieJar implements JarContract
|
||||
* @param int $minutes
|
||||
* @param string $path
|
||||
* @param string $domain
|
||||
* @param bool $secure
|
||||
* @param bool|null $secure
|
||||
* @param bool $httpOnly
|
||||
* @param bool $raw
|
||||
* @param string|null $sameSite
|
||||
* @return \Symfony\Component\HttpFoundation\Cookie
|
||||
*/
|
||||
public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null)
|
||||
public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null)
|
||||
{
|
||||
list($path, $domain, $secure, $sameSite) = $this->getPathAndDomain($path, $domain, $secure, $sameSite);
|
||||
|
||||
@@ -76,13 +76,13 @@ class CookieJar implements JarContract
|
||||
* @param string $value
|
||||
* @param string $path
|
||||
* @param string $domain
|
||||
* @param bool $secure
|
||||
* @param bool|null $secure
|
||||
* @param bool $httpOnly
|
||||
* @param bool $raw
|
||||
* @param string|null $sameSite
|
||||
* @return \Symfony\Component\HttpFoundation\Cookie
|
||||
*/
|
||||
public function forever($name, $value, $path = null, $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null)
|
||||
public function forever($name, $value, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null)
|
||||
{
|
||||
return $this->make($name, $value, 2628000, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
|
||||
}
|
||||
@@ -154,15 +154,15 @@ class CookieJar implements JarContract
|
||||
/**
|
||||
* Get the path and domain, or the default values.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $domain
|
||||
* @param bool $secure
|
||||
* @param string $sameSite
|
||||
* @param string $path
|
||||
* @param string $domain
|
||||
* @param bool|null $secure
|
||||
* @param string $sameSite
|
||||
* @return array
|
||||
*/
|
||||
protected function getPathAndDomain($path, $domain, $secure = false, $sameSite = null)
|
||||
protected function getPathAndDomain($path, $domain, $secure = null, $sameSite = null)
|
||||
{
|
||||
return [$path ?: $this->path, $domain ?: $this->domain, $secure ?: $this->secure, $sameSite ?: $this->sameSite];
|
||||
return [$path ?: $this->path, $domain ?: $this->domain, is_bool($secure) ? $secure : $this->secure, $sameSite ?: $this->sameSite];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -39,12 +39,12 @@ class EncryptCookies
|
||||
/**
|
||||
* Disable encryption for the given cookie name(s).
|
||||
*
|
||||
* @param string|array $cookieName
|
||||
* @param string|array $name
|
||||
* @return void
|
||||
*/
|
||||
public function disableFor($cookieName)
|
||||
public function disableFor($name)
|
||||
{
|
||||
$this->except = array_merge($this->except, (array) $cookieName);
|
||||
$this->except = array_merge($this->except, (array) $name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ class EncryptCookies
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
@@ -67,13 +67,13 @@ class EncryptCookies
|
||||
*/
|
||||
protected function decrypt(Request $request)
|
||||
{
|
||||
foreach ($request->cookies as $key => $c) {
|
||||
foreach ($request->cookies as $key => $cookie) {
|
||||
if ($this->isDisabled($key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$request->cookies->set($key, $this->decryptCookie($c));
|
||||
$request->cookies->set($key, $this->decryptCookie($cookie));
|
||||
} catch (DecryptException $e) {
|
||||
$request->cookies->set($key, null);
|
||||
}
|
||||
@@ -138,16 +138,16 @@ class EncryptCookies
|
||||
/**
|
||||
* Duplicate a cookie with a new value.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Cookie $c
|
||||
* @param \Symfony\Component\HttpFoundation\Cookie $cookie
|
||||
* @param mixed $value
|
||||
* @return \Symfony\Component\HttpFoundation\Cookie
|
||||
*/
|
||||
protected function duplicate(Cookie $c, $value)
|
||||
protected function duplicate(Cookie $cookie, $value)
|
||||
{
|
||||
return new Cookie(
|
||||
$c->getName(), $value, $c->getExpiresTime(), $c->getPath(),
|
||||
$c->getDomain(), $c->isSecure(), $c->isHttpOnly(), $c->isRaw(),
|
||||
$c->getSameSite()
|
||||
$cookie->getName(), $value, $cookie->getExpiresTime(),
|
||||
$cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(),
|
||||
$cookie->isHttpOnly(), $cookie->isRaw(), $cookie->getSameSite()
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -14,11 +14,11 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"illuminate/contracts": "5.5.*",
|
||||
"illuminate/support": "5.5.*",
|
||||
"symfony/http-foundation": "~3.3",
|
||||
"symfony/http-kernel": "~3.3"
|
||||
"php": "^7.1.3",
|
||||
"illuminate/contracts": "5.6.*",
|
||||
"illuminate/support": "5.6.*",
|
||||
"symfony/http-foundation": "~4.0",
|
||||
"symfony/http-kernel": "~4.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -27,7 +27,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.5-dev"
|
||||
"dev-master": "5.6-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@@ -129,7 +129,7 @@ trait ManagesTransactions
|
||||
/**
|
||||
* Handle an exception from a transaction beginning.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
|
@@ -504,7 +504,7 @@ class Connection implements ConnectionInterface
|
||||
}
|
||||
|
||||
$this->recordsHaveBeenModified(
|
||||
$change = ($this->getPdo()->exec($query) === false ? false : true)
|
||||
$change = $this->getPdo()->exec($query) !== false
|
||||
);
|
||||
|
||||
return $change;
|
||||
@@ -552,7 +552,7 @@ class Connection implements ConnectionInterface
|
||||
|
||||
// Now we'll execute this callback and capture the result. Once it has been
|
||||
// executed we will restore the value of query logging and give back the
|
||||
// value of hte callback so the original callers can have the results.
|
||||
// value of the callback so the original callers can have the results.
|
||||
$result = $callback();
|
||||
|
||||
$this->loggingQueries = $loggingQueries;
|
||||
@@ -929,7 +929,7 @@ class Connection implements ConnectionInterface
|
||||
return $this->getPdo();
|
||||
}
|
||||
|
||||
if ($this->getConfig('sticky') && $this->recordsModified) {
|
||||
if ($this->recordsModified && $this->getConfig('sticky')) {
|
||||
return $this->getPdo();
|
||||
}
|
||||
|
||||
@@ -958,7 +958,7 @@ class Connection implements ConnectionInterface
|
||||
/**
|
||||
* Set the PDO connection used for reading.
|
||||
*
|
||||
* @param \PDO||\Closure|null $pdo
|
||||
* @param \PDO|\Closure|null $pdo
|
||||
* @return $this
|
||||
*/
|
||||
public function setReadPdo($pdo)
|
||||
@@ -1096,6 +1096,16 @@ class Connection implements ConnectionInterface
|
||||
$this->events = $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the event dispatcher for this connection.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unsetEventDispatcher()
|
||||
{
|
||||
$this->events = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the connection in a "dry run".
|
||||
*
|
||||
|
@@ -11,7 +11,6 @@ use Illuminate\Database\SQLiteConnection;
|
||||
use Illuminate\Database\PostgresConnection;
|
||||
use Illuminate\Database\SqlServerConnection;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\Debug\ExceptionHandler;
|
||||
|
||||
class ConnectionFactory
|
||||
{
|
||||
@@ -182,9 +181,7 @@ class ConnectionFactory
|
||||
try {
|
||||
return $this->createConnector($config)->connect($config);
|
||||
} catch (PDOException $e) {
|
||||
if (count($hosts) - 1 === $key && $this->container->bound(ExceptionHandler::class)) {
|
||||
$this->container->make(ExceptionHandler::class)->report($e);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,6 +280,6 @@ class ConnectionFactory
|
||||
return new SqlServerConnection($connection, $database, $prefix, $config);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Unsupported driver [$driver]");
|
||||
throw new InvalidArgumentException("Unsupported driver [{$driver}]");
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ namespace Illuminate\Database\Connectors;
|
||||
|
||||
use PDO;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
use Doctrine\DBAL\Driver\PDOConnection;
|
||||
use Illuminate\Database\DetectsLostConnections;
|
||||
|
||||
@@ -82,7 +83,7 @@ class Connector
|
||||
/**
|
||||
* Handle an exception that occurred during connect execution.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @param string $dsn
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
@@ -91,7 +92,7 @@ class Connector
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function tryAgainIfCausedByLostConnection(Exception $e, $dsn, $username, $password, $options)
|
||||
protected function tryAgainIfCausedByLostConnection(Throwable $e, $dsn, $username, $password, $options)
|
||||
{
|
||||
if ($this->causedByLostConnection($e)) {
|
||||
return $this->createPdoConnection($dsn, $username, $password, $options);
|
||||
|
@@ -172,7 +172,6 @@ class MySqlConnector extends Connector implements ConnectorInterface
|
||||
* Get the query to enable strict mode.
|
||||
*
|
||||
* @param \PDO $connection
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function strictMode(PDO $connection)
|
||||
|
@@ -31,7 +31,7 @@ class SQLiteConnector extends Connector implements ConnectorInterface
|
||||
// as the developer probably wants to know if the database exists and this
|
||||
// SQLite driver will not throw any exception if it does not by default.
|
||||
if ($path === false) {
|
||||
throw new InvalidArgumentException("Database (${config['database']}) does not exist.");
|
||||
throw new InvalidArgumentException("Database ({$config['database']}) does not exist.");
|
||||
}
|
||||
|
||||
return $this->createConnection("sqlite:{$path}", $config, $options);
|
||||
|
@@ -18,15 +18,27 @@ class BaseCommand extends Command
|
||||
// migrations may be run for any customized path from within the application.
|
||||
if ($this->input->hasOption('path') && $this->option('path')) {
|
||||
return collect($this->option('path'))->map(function ($path) {
|
||||
return $this->laravel->basePath().'/'.$path;
|
||||
return ! $this->usingRealPath()
|
||||
? $this->laravel->basePath().'/'.$path
|
||||
: $path;
|
||||
})->all();
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
[$this->getMigrationPath()], $this->migrator->paths()
|
||||
$this->migrator->paths(), [$this->getMigrationPath()]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given path(s) are pre-resolved "real" paths.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function usingRealPath()
|
||||
{
|
||||
return $this->input->hasOption('realpath') && $this->option('realpath');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to the migration directory.
|
||||
*
|
||||
|
@@ -35,15 +35,22 @@ class FreshCommand extends Command
|
||||
return;
|
||||
}
|
||||
|
||||
$this->dropAllTables(
|
||||
$database = $this->input->getOption('database')
|
||||
);
|
||||
$database = $this->input->getOption('database');
|
||||
|
||||
if ($this->option('drop-views')) {
|
||||
$this->dropAllViews($database);
|
||||
|
||||
$this->info('Dropped all views successfully.');
|
||||
}
|
||||
|
||||
$this->dropAllTables($database);
|
||||
|
||||
$this->info('Dropped all tables successfully.');
|
||||
|
||||
$this->call('migrate', [
|
||||
'--database' => $database,
|
||||
'--path' => $this->input->getOption('path'),
|
||||
'--realpath' => $this->input->getOption('realpath'),
|
||||
'--force' => true,
|
||||
]);
|
||||
|
||||
@@ -65,6 +72,19 @@ class FreshCommand extends Command
|
||||
->dropAllTables();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all of the database views.
|
||||
*
|
||||
* @param string $database
|
||||
* @return void
|
||||
*/
|
||||
protected function dropAllViews($database)
|
||||
{
|
||||
$this->laravel['db']->connection($database)
|
||||
->getSchemaBuilder()
|
||||
->dropAllViews();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the developer has requested database seeding.
|
||||
*
|
||||
@@ -100,9 +120,13 @@ class FreshCommand extends Command
|
||||
return [
|
||||
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
|
||||
|
||||
['drop-views', null, InputOption::VALUE_NONE, 'Drop all tables and views.'],
|
||||
|
||||
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
|
||||
|
||||
['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to be executed.'],
|
||||
['path', null, InputOption::VALUE_OPTIONAL, 'The path to the migrations files to be executed.'],
|
||||
|
||||
['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths.'],
|
||||
|
||||
['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'],
|
||||
|
||||
|
@@ -16,7 +16,8 @@ class MigrateCommand extends BaseCommand
|
||||
*/
|
||||
protected $signature = 'migrate {--database= : The database connection to use.}
|
||||
{--force : Force the operation to run when in production.}
|
||||
{--path= : The path of migrations files to be executed.}
|
||||
{--path= : The path to the migrations files to be executed.}
|
||||
{--realpath : Indicate any provided migration file paths are pre-resolved absolute paths.}
|
||||
{--pretend : Dump the SQL queries that would be run.}
|
||||
{--seed : Indicates if the seed task should be re-run.}
|
||||
{--step : Force the migrations to be run so they can be rolled back individually.}';
|
||||
|
@@ -16,7 +16,8 @@ class MigrateMakeCommand extends BaseCommand
|
||||
protected $signature = 'make:migration {name : The name of the migration.}
|
||||
{--create= : The table to be created.}
|
||||
{--table= : The table to migrate.}
|
||||
{--path= : The location where the migration file should be created.}';
|
||||
{--path= : The location where the migration file should be created.}
|
||||
{--realpath : Indicate any provided migration file paths are pre-resolved absolute paths.}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
@@ -83,11 +84,7 @@ class MigrateMakeCommand extends BaseCommand
|
||||
// "create" in the name. This will allow us to provide a convenient way
|
||||
// of creating migrations that create new tables for the application.
|
||||
if (! $table) {
|
||||
if (preg_match('/^create_(\w+)_table$/', $name, $matches)) {
|
||||
$table = $matches[1];
|
||||
|
||||
$create = true;
|
||||
}
|
||||
[$table, $create] = TableGuesser::guess($name);
|
||||
}
|
||||
|
||||
// Now we are ready to write the migration out to disk. Once we've written
|
||||
@@ -123,9 +120,21 @@ class MigrateMakeCommand extends BaseCommand
|
||||
protected function getMigrationPath()
|
||||
{
|
||||
if (! is_null($targetPath = $this->input->getOption('path'))) {
|
||||
return $this->laravel->basePath().'/'.$targetPath;
|
||||
return ! $this->usingRealPath()
|
||||
? $this->laravel->basePath().'/'.$targetPath
|
||||
: $targetPath;
|
||||
}
|
||||
|
||||
return parent::getMigrationPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given path(s) are pre-resolved "real" paths.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function usingRealPath()
|
||||
{
|
||||
return $this->input->hasOption('realpath') && $this->option('realpath');
|
||||
}
|
||||
}
|
||||
|
@@ -61,6 +61,7 @@ class RefreshCommand extends Command
|
||||
$this->call('migrate', [
|
||||
'--database' => $database,
|
||||
'--path' => $path,
|
||||
'--realpath' => $this->input->getOption('realpath'),
|
||||
'--force' => $force,
|
||||
]);
|
||||
|
||||
@@ -83,6 +84,7 @@ class RefreshCommand extends Command
|
||||
$this->call('migrate:rollback', [
|
||||
'--database' => $database,
|
||||
'--path' => $path,
|
||||
'--realpath' => $this->input->getOption('realpath'),
|
||||
'--step' => $step,
|
||||
'--force' => $force,
|
||||
]);
|
||||
@@ -101,6 +103,7 @@ class RefreshCommand extends Command
|
||||
$this->call('migrate:reset', [
|
||||
'--database' => $database,
|
||||
'--path' => $path,
|
||||
'--realpath' => $this->input->getOption('realpath'),
|
||||
'--force' => $force,
|
||||
]);
|
||||
}
|
||||
@@ -142,7 +145,9 @@ class RefreshCommand extends Command
|
||||
|
||||
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
|
||||
|
||||
['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to be executed.'],
|
||||
['path', null, InputOption::VALUE_OPTIONAL, 'The path to the migrations files to be executed.'],
|
||||
|
||||
['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths.'],
|
||||
|
||||
['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'],
|
||||
|
||||
|
@@ -88,7 +88,9 @@ class ResetCommand extends BaseCommand
|
||||
|
||||
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
|
||||
|
||||
['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) of migrations files to be executed.'],
|
||||
['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed.'],
|
||||
|
||||
['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths.'],
|
||||
|
||||
['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],
|
||||
];
|
||||
|
@@ -84,7 +84,9 @@ class RollbackCommand extends BaseCommand
|
||||
|
||||
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
|
||||
|
||||
['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to be executed.'],
|
||||
['path', null, InputOption::VALUE_OPTIONAL, 'The path to the migrations files to be executed.'],
|
||||
|
||||
['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths.'],
|
||||
|
||||
['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],
|
||||
|
||||
|
@@ -57,8 +57,10 @@ class StatusCommand extends BaseCommand
|
||||
|
||||
$ran = $this->migrator->getRepository()->getRan();
|
||||
|
||||
if (count($migrations = $this->getStatusFor($ran)) > 0) {
|
||||
$this->table(['Ran?', 'Migration'], $migrations);
|
||||
$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');
|
||||
}
|
||||
@@ -68,16 +70,17 @@ class StatusCommand extends BaseCommand
|
||||
* Get the status for the given ran migrations.
|
||||
*
|
||||
* @param array $ran
|
||||
* @param array $batches
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
protected function getStatusFor(array $ran)
|
||||
protected function getStatusFor(array $ran, array $batches)
|
||||
{
|
||||
return Collection::make($this->getAllMigrationFiles())
|
||||
->map(function ($migration) use ($ran) {
|
||||
->map(function ($migration) use ($ran, $batches) {
|
||||
$migrationName = $this->migrator->getMigrationName($migration);
|
||||
|
||||
return in_array($migrationName, $ran)
|
||||
? ['<info>Y</info>', $migrationName]
|
||||
? ['<info>Y</info>', $migrationName, $batches[$migrationName]]
|
||||
: ['<fg=red>N</fg=red>', $migrationName];
|
||||
});
|
||||
}
|
||||
@@ -102,7 +105,9 @@ class StatusCommand extends BaseCommand
|
||||
return [
|
||||
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
|
||||
|
||||
['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to use.'],
|
||||
['path', null, InputOption::VALUE_OPTIONAL, 'The path to the migrations files to use.'],
|
||||
|
||||
['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths.'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
23
vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/TableGuesser.php
vendored
Normal file
23
vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/TableGuesser.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Console\Migrations;
|
||||
|
||||
class TableGuesser
|
||||
{
|
||||
/**
|
||||
* Attempt to guess the table name and "creation" status of the given migration.
|
||||
*
|
||||
* @param string $migration
|
||||
* @return array
|
||||
*/
|
||||
public static function guess($migration)
|
||||
{
|
||||
if (preg_match('/^create_(\w+)_table$/', $migration, $matches)) {
|
||||
return [$matches[1], $create = true];
|
||||
}
|
||||
|
||||
if (preg_match('/_(to|from|in)_(\w+)_table$/', $migration, $matches)) {
|
||||
return [$matches[2], $create = false];
|
||||
}
|
||||
}
|
||||
}
|
@@ -137,7 +137,7 @@ class DatabaseManager implements ConnectionResolverInterface
|
||||
$connections = $this->app['config']['database.connections'];
|
||||
|
||||
if (is_null($config = Arr::get($connections, $name))) {
|
||||
throw new InvalidArgumentException("Database [$name] not configured.");
|
||||
throw new InvalidArgumentException("Database [{$name}] not configured.");
|
||||
}
|
||||
|
||||
return $config;
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Illuminate\Database;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait DetectsLostConnections
|
||||
@@ -10,10 +10,10 @@ trait DetectsLostConnections
|
||||
/**
|
||||
* Determine if the given exception was caused by a lost connection.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @return bool
|
||||
*/
|
||||
protected function causedByLostConnection(Exception $e)
|
||||
protected function causedByLostConnection(Throwable $e)
|
||||
{
|
||||
$message = $e->getMessage();
|
||||
|
||||
|
@@ -68,7 +68,7 @@ class Builder
|
||||
*/
|
||||
protected $passthru = [
|
||||
'insert', 'insertGetId', 'getBindings', 'toSql',
|
||||
'exists', 'doesntExist', 'count', 'min', 'max', 'avg', 'sum', 'getConnection',
|
||||
'exists', 'doesntExist', 'count', 'min', 'max', 'avg', 'average', 'sum', 'getConnection',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -211,8 +211,8 @@ class Builder
|
||||
* Add a basic where clause to the query.
|
||||
*
|
||||
* @param string|array|\Closure $column
|
||||
* @param string $operator
|
||||
* @param mixed $value
|
||||
* @param mixed $operator
|
||||
* @param mixed $value
|
||||
* @param string $boolean
|
||||
* @return $this
|
||||
*/
|
||||
@@ -233,14 +233,14 @@ class Builder
|
||||
* Add an "or where" clause to the query.
|
||||
*
|
||||
* @param \Closure|array|string $column
|
||||
* @param string $operator
|
||||
* @param mixed $operator
|
||||
* @param mixed $value
|
||||
* @return \Illuminate\Database\Eloquent\Builder|static
|
||||
*/
|
||||
public function orWhere($column, $operator = null, $value = null)
|
||||
{
|
||||
list($value, $operator) = $this->query->prepareValueAndOperator(
|
||||
$value, $operator, func_num_args() == 2
|
||||
$value, $operator, func_num_args() === 2
|
||||
);
|
||||
|
||||
return $this->where($column, $operator, $value, 'or');
|
||||
@@ -321,7 +321,7 @@ class Builder
|
||||
$result = $this->find($id, $columns);
|
||||
|
||||
if (is_array($id)) {
|
||||
if (count($result) == count(array_unique($id))) {
|
||||
if (count($result) === count(array_unique($id))) {
|
||||
return $result;
|
||||
}
|
||||
} elseif (! is_null($result)) {
|
||||
@@ -622,7 +622,7 @@ class Builder
|
||||
|
||||
$alias = is_null($alias) ? $column : $alias;
|
||||
|
||||
$lastId = 0;
|
||||
$lastId = null;
|
||||
|
||||
do {
|
||||
$clone = clone $this;
|
||||
@@ -784,7 +784,7 @@ class Builder
|
||||
* Increment a column's value by a given amount.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $amount
|
||||
* @param float|int $amount
|
||||
* @param array $extra
|
||||
* @return int
|
||||
*/
|
||||
@@ -799,7 +799,7 @@ class Builder
|
||||
* Decrement a column's value by a given amount.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $amount
|
||||
* @param float|int $amount
|
||||
* @param array $extra
|
||||
* @return int
|
||||
*/
|
||||
@@ -1306,7 +1306,9 @@ class Builder
|
||||
}
|
||||
|
||||
if (! isset(static::$macros[$method])) {
|
||||
throw new BadMethodCallException("Method {$method} does not exist.");
|
||||
throw new BadMethodCallException(sprintf(
|
||||
'Method %s::%s does not exist.', static::class, $method
|
||||
));
|
||||
}
|
||||
|
||||
if (static::$macros[$method] instanceof Closure) {
|
||||
|
@@ -4,7 +4,9 @@ namespace Illuminate\Database\Eloquent;
|
||||
|
||||
use LogicException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
use Illuminate\Contracts\Queue\QueueableCollection;
|
||||
use Illuminate\Support\Collection as BaseCollection;
|
||||
|
||||
@@ -43,7 +45,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
/**
|
||||
* Load a set of relationships onto the collection.
|
||||
*
|
||||
* @param mixed $relations
|
||||
* @param array|string $relations
|
||||
* @return $this
|
||||
*/
|
||||
public function load($relations)
|
||||
@@ -61,6 +63,100 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a set of relationships onto the collection if they are not already eager loaded.
|
||||
*
|
||||
* @param array|string $relations
|
||||
* @return $this
|
||||
*/
|
||||
public function loadMissing($relations)
|
||||
{
|
||||
if (is_string($relations)) {
|
||||
$relations = func_get_args();
|
||||
}
|
||||
|
||||
foreach ($relations as $key => $value) {
|
||||
if (is_numeric($key)) {
|
||||
$key = $value;
|
||||
}
|
||||
|
||||
$segments = explode('.', explode(':', $key)[0]);
|
||||
|
||||
if (Str::contains($key, ':')) {
|
||||
$segments[count($segments) - 1] .= ':'.explode(':', $key)[1];
|
||||
}
|
||||
|
||||
$path = array_combine($segments, $segments);
|
||||
|
||||
if (is_callable($value)) {
|
||||
$path[end($segments)] = $value;
|
||||
}
|
||||
|
||||
$this->loadMissingRelation($this, $path);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a relationship path if it is not already eager loaded.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Collection $models
|
||||
* @param array $path
|
||||
* @return void
|
||||
*/
|
||||
protected function loadMissingRelation(Collection $models, array $path)
|
||||
{
|
||||
$relation = array_splice($path, 0, 1);
|
||||
|
||||
$name = explode(':', key($relation))[0];
|
||||
|
||||
if (is_string(reset($relation))) {
|
||||
$relation = reset($relation);
|
||||
}
|
||||
|
||||
$models->filter(function ($model) use ($name) {
|
||||
return ! is_null($model) && ! $model->relationLoaded($name);
|
||||
})->load($relation);
|
||||
|
||||
if (empty($path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$models = $models->pluck($name);
|
||||
|
||||
if ($models->first() instanceof BaseCollection) {
|
||||
$models = $models->collapse();
|
||||
}
|
||||
|
||||
$this->loadMissingRelation(new static($models), $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a set of relationships onto the mixed relationship collection.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param array $relations
|
||||
* @return $this
|
||||
*/
|
||||
public function loadMorph($relation, $relations)
|
||||
{
|
||||
$this->pluck($relation)
|
||||
->filter()
|
||||
->groupBy(function ($model) {
|
||||
return get_class($model);
|
||||
})
|
||||
->filter(function ($models, $className) use ($relations) {
|
||||
return Arr::has($relations, $className);
|
||||
})
|
||||
->each(function ($models, $className) use ($relations) {
|
||||
$className::with($relations[$className])
|
||||
->eagerLoadRelations($models->all());
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item to the collection.
|
||||
*
|
||||
@@ -412,7 +508,23 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
*/
|
||||
public function getQueueableIds()
|
||||
{
|
||||
return $this->modelKeys();
|
||||
if ($this->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->first() instanceof Pivot
|
||||
? $this->map->getQueueableId()->all()
|
||||
: $this->modelKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relationships of the entities being queued.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueueableRelations()
|
||||
{
|
||||
return $this->isNotEmpty() ? $this->first()->getQueueableRelations() : [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -189,6 +189,10 @@ trait HasAttributes
|
||||
($value === 'date' || $value === 'datetime')) {
|
||||
$attributes[$key] = $this->serializeDate($attributes[$key]);
|
||||
}
|
||||
|
||||
if ($attributes[$key] && $this->isCustomDateTimeCast($value)) {
|
||||
$attributes[$key] = $attributes[$key]->format(explode(':', $value, 2)[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
@@ -407,7 +411,9 @@ trait HasAttributes
|
||||
$relation = $this->$method();
|
||||
|
||||
if (! $relation instanceof Relation) {
|
||||
throw new LogicException(get_class($this).'::'.$method.' must return a relationship instance.');
|
||||
throw new LogicException(sprintf(
|
||||
'%s::%s must return a relationship instance.', static::class, $method
|
||||
));
|
||||
}
|
||||
|
||||
return tap($relation->getResults(), function ($results) use ($method) {
|
||||
@@ -488,6 +494,7 @@ trait HasAttributes
|
||||
case 'date':
|
||||
return $this->asDate($value);
|
||||
case 'datetime':
|
||||
case 'custom_datetime':
|
||||
return $this->asDateTime($value);
|
||||
case 'timestamp':
|
||||
return $this->asTimestamp($value);
|
||||
@@ -504,15 +511,31 @@ trait HasAttributes
|
||||
*/
|
||||
protected function getCastType($key)
|
||||
{
|
||||
if ($this->isCustomDateTimeCast($this->getCasts()[$key])) {
|
||||
return 'custom_datetime';
|
||||
}
|
||||
|
||||
return trim(strtolower($this->getCasts()[$key]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the cast type is a custom date time cast.
|
||||
*
|
||||
* @param string $cast
|
||||
* @return bool
|
||||
*/
|
||||
protected function isCustomDateTimeCast($cast)
|
||||
{
|
||||
return strncmp($cast, 'date:', 5) === 0 ||
|
||||
strncmp($cast, 'datetime:', 9) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a given attribute on the model.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
* @return mixed
|
||||
*/
|
||||
public function setAttribute($key, $value)
|
||||
{
|
||||
@@ -520,9 +543,7 @@ trait HasAttributes
|
||||
// which simply lets the developers tweak the attribute as it is set on
|
||||
// the model, such as "json_encoding" an listing of data for storage.
|
||||
if ($this->hasSetMutator($key)) {
|
||||
$method = 'set'.Str::studly($key).'Attribute';
|
||||
|
||||
return $this->{$method}($value);
|
||||
return $this->setMutatedAttributeValue($key, $value);
|
||||
}
|
||||
|
||||
// If an attribute is listed as a "date", we'll convert it from a DateTime
|
||||
@@ -559,6 +580,18 @@ trait HasAttributes
|
||||
return method_exists($this, 'set'.Str::studly($key).'Attribute');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of an attribute using its mutator.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function setMutatedAttributeValue($key, $value)
|
||||
{
|
||||
return $this->{'set'.Str::studly($key).'Attribute'}($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given attribute is a date or date castable.
|
||||
*
|
||||
@@ -781,7 +814,7 @@ trait HasAttributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDateFormat()
|
||||
public function getDateFormat()
|
||||
{
|
||||
return $this->dateFormat ?: $this->getConnection()->getQueryGrammar()->getDateFormat();
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Illuminate\Database\Eloquent\Concerns;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
trait HasEvents
|
||||
@@ -25,21 +26,34 @@ trait HasEvents
|
||||
protected $observables = [];
|
||||
|
||||
/**
|
||||
* Register an observer with the Model.
|
||||
* Register observers with the model.
|
||||
*
|
||||
* @param object|string $class
|
||||
* @param object|array|string $classes
|
||||
* @return void
|
||||
*/
|
||||
public static function observe($class)
|
||||
public static function observe($classes)
|
||||
{
|
||||
$instance = new static;
|
||||
|
||||
foreach (Arr::wrap($classes) as $class) {
|
||||
$instance->registerObserver($class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a single observer with the model.
|
||||
*
|
||||
* @param object|string $class
|
||||
* @return void
|
||||
*/
|
||||
protected function registerObserver($class)
|
||||
{
|
||||
$className = is_string($class) ? $class : get_class($class);
|
||||
|
||||
// When registering a model observer, we will spin through the possible events
|
||||
// and determine if this observer has that method. If it does, we will hook
|
||||
// it into the model's event system, making it convenient to watch these.
|
||||
foreach ($instance->getObservableEvents() as $event) {
|
||||
foreach ($this->getObservableEvents() as $event) {
|
||||
if (method_exists($class, $event)) {
|
||||
static::registerModelEvent($event, $className.'@'.$event);
|
||||
}
|
||||
@@ -55,9 +69,9 @@ trait HasEvents
|
||||
{
|
||||
return array_merge(
|
||||
[
|
||||
'retrieved', 'creating', 'created', 'updating',
|
||||
'updated', 'deleting', 'deleted', 'saving',
|
||||
'saved', 'restoring', 'restored',
|
||||
'retrieved', 'creating', 'created', 'updating', 'updated',
|
||||
'saving', 'saved', 'restoring', 'restored',
|
||||
'deleting', 'deleted', 'forceDeleted',
|
||||
],
|
||||
$this->observables
|
||||
);
|
||||
|
@@ -173,9 +173,10 @@ trait HasRelationships
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param string $id
|
||||
* @param string $ownerKey
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function morphTo($name = null, $type = null, $id = null)
|
||||
public function morphTo($name = null, $type = null, $id = null, $ownerKey = null)
|
||||
{
|
||||
// If no name is provided, we will use the backtrace to get the function name
|
||||
// since that is most likely the name of the polymorphic interface. We can
|
||||
@@ -190,8 +191,8 @@ trait HasRelationships
|
||||
// the relationship. In this case we'll just pass in a dummy query where we
|
||||
// need to remove any eager loads that may already be defined on a model.
|
||||
return empty($class = $this->{$type})
|
||||
? $this->morphEagerTo($name, $type, $id)
|
||||
: $this->morphInstanceTo($class, $name, $type, $id);
|
||||
? $this->morphEagerTo($name, $type, $id, $ownerKey)
|
||||
: $this->morphInstanceTo($class, $name, $type, $id, $ownerKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,12 +201,13 @@ trait HasRelationships
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param string $id
|
||||
* @param string $ownerKey
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
protected function morphEagerTo($name, $type, $id)
|
||||
protected function morphEagerTo($name, $type, $id, $ownerKey)
|
||||
{
|
||||
return $this->newMorphTo(
|
||||
$this->newQuery()->setEagerLoads([]), $this, $id, null, $type, $name
|
||||
$this->newQuery()->setEagerLoads([]), $this, $id, $ownerKey, $type, $name
|
||||
);
|
||||
}
|
||||
|
||||
@@ -216,16 +218,17 @@ trait HasRelationships
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param string $id
|
||||
* @param string $ownerKey
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
protected function morphInstanceTo($target, $name, $type, $id)
|
||||
protected function morphInstanceTo($target, $name, $type, $id, $ownerKey)
|
||||
{
|
||||
$instance = $this->newRelatedInstance(
|
||||
static::getActualClassNameForMorph($target)
|
||||
);
|
||||
|
||||
return $this->newMorphTo(
|
||||
$instance->newQuery(), $this, $id, $instance->getKeyName(), $type, $name
|
||||
$instance->newQuery(), $this, $id, $ownerKey ?? $instance->getKeyName(), $type, $name
|
||||
);
|
||||
}
|
||||
|
||||
@@ -492,7 +495,7 @@ trait HasRelationships
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new HasManyThrough relationship.
|
||||
* Instantiate a new MorphToMany relationship.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Model $parent
|
||||
@@ -690,7 +693,7 @@ trait HasRelationships
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the specific relationship in the model.
|
||||
* Set the given relationship on the model.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param mixed $value
|
||||
@@ -703,6 +706,19 @@ trait HasRelationships
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset a loaded relationship.
|
||||
*
|
||||
* @param string $relation
|
||||
* @return $this
|
||||
*/
|
||||
public function unsetRelation($relation)
|
||||
{
|
||||
unset($this->relations[$relation]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entire relations array on the model.
|
||||
*
|
||||
|
@@ -42,7 +42,8 @@ trait HasTimestamps
|
||||
$this->setUpdatedAt($time);
|
||||
}
|
||||
|
||||
if (! $this->exists && ! $this->isDirty(static::CREATED_AT)) {
|
||||
if (! $this->exists && ! is_null(static::CREATED_AT) &&
|
||||
! $this->isDirty(static::CREATED_AT)) {
|
||||
$this->setCreatedAt($time);
|
||||
}
|
||||
}
|
||||
|
@@ -210,14 +210,18 @@ trait QueriesRelationships
|
||||
|
||||
$query->callScope($constraints);
|
||||
|
||||
$query->mergeConstraintsFrom($relation->getQuery());
|
||||
$query = $query->mergeConstraintsFrom($relation->getQuery())->toBase();
|
||||
|
||||
if (count($query->columns) > 1) {
|
||||
$query->columns = [$query->columns[0]];
|
||||
}
|
||||
|
||||
// Finally we will add the proper result column alias to the query and run the subselect
|
||||
// statement against the query builder. Then we will return the builder instance back
|
||||
// to the developer for further constraint chaining that needs to take place on it.
|
||||
$column = $alias ?? Str::snake($name.'_count');
|
||||
|
||||
$this->selectSub($query->toBase(), $column);
|
||||
$this->selectSub($query, $column);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@@ -22,6 +22,20 @@ class Factory implements ArrayAccess
|
||||
*/
|
||||
protected $states = [];
|
||||
|
||||
/**
|
||||
* The registered after making callbacks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $afterMaking = [];
|
||||
|
||||
/**
|
||||
* The registered after creating callbacks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $afterCreating = [];
|
||||
|
||||
/**
|
||||
* The Faker instance for the builder.
|
||||
*
|
||||
@@ -97,6 +111,62 @@ class Factory implements ArrayAccess
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a callback to run after making a model.
|
||||
*
|
||||
* @param string $class
|
||||
* @param callable $callback
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function afterMaking($class, callable $callback, $name = 'default')
|
||||
{
|
||||
$this->afterMaking[$class][$name][] = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a callback to run after making a model with given state.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $state
|
||||
* @param callable $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function afterMakingState($class, $state, callable $callback)
|
||||
{
|
||||
return $this->afterMaking($class, $callback, $state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a callback to run after creating a model.
|
||||
*
|
||||
* @param string $class
|
||||
* @param callable $callback
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function afterCreating($class, callable $callback, $name = 'default')
|
||||
{
|
||||
$this->afterCreating[$class][$name][] = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a callback to run after creating a model with given state.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $state
|
||||
* @param callable $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function afterCreatingState($class, $state, callable $callback)
|
||||
{
|
||||
return $this->afterCreating($class, $callback, $state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of the given model and persist it to the database.
|
||||
*
|
||||
@@ -184,7 +254,10 @@ class Factory implements ArrayAccess
|
||||
*/
|
||||
public function of($class, $name = 'default')
|
||||
{
|
||||
return new FactoryBuilder($class, $name, $this->definitions, $this->states, $this->faker);
|
||||
return new FactoryBuilder(
|
||||
$class, $name, $this->definitions, $this->states,
|
||||
$this->afterMaking, $this->afterCreating, $this->faker
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -45,6 +45,20 @@ class FactoryBuilder
|
||||
*/
|
||||
protected $states;
|
||||
|
||||
/**
|
||||
* The model after making callbacks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $afterMaking = [];
|
||||
|
||||
/**
|
||||
* The model after creating callbacks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $afterCreating = [];
|
||||
|
||||
/**
|
||||
* The states to apply.
|
||||
*
|
||||
@@ -73,16 +87,21 @@ class FactoryBuilder
|
||||
* @param string $name
|
||||
* @param array $definitions
|
||||
* @param array $states
|
||||
* @param array $afterMaking
|
||||
* @param array $afterCreating
|
||||
* @param \Faker\Generator $faker
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($class, $name, array $definitions, array $states, Faker $faker)
|
||||
public function __construct($class, $name, array $definitions, array $states,
|
||||
array $afterMaking, array $afterCreating, Faker $faker)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->class = $class;
|
||||
$this->faker = $faker;
|
||||
$this->states = $states;
|
||||
$this->definitions = $definitions;
|
||||
$this->afterMaking = $afterMaking;
|
||||
$this->afterCreating = $afterCreating;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,6 +117,17 @@ class FactoryBuilder
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state to be applied to the model.
|
||||
*
|
||||
* @param string $state
|
||||
* @return $this
|
||||
*/
|
||||
public function state($state)
|
||||
{
|
||||
return $this->states([$state]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the states to be applied to the model.
|
||||
*
|
||||
@@ -149,8 +179,12 @@ class FactoryBuilder
|
||||
|
||||
if ($results instanceof Model) {
|
||||
$this->store(collect([$results]));
|
||||
|
||||
$this->callAfterCreating(collect([$results]));
|
||||
} else {
|
||||
$this->store($results);
|
||||
|
||||
$this->callAfterCreating($results);
|
||||
}
|
||||
|
||||
return $results;
|
||||
@@ -182,16 +216,22 @@ class FactoryBuilder
|
||||
public function make(array $attributes = [])
|
||||
{
|
||||
if ($this->amount === null) {
|
||||
return $this->makeInstance($attributes);
|
||||
return tap($this->makeInstance($attributes), function ($instance) {
|
||||
$this->callAfterMaking(collect([$instance]));
|
||||
});
|
||||
}
|
||||
|
||||
if ($this->amount < 1) {
|
||||
return (new $this->class)->newCollection();
|
||||
}
|
||||
|
||||
return (new $this->class)->newCollection(array_map(function () use ($attributes) {
|
||||
$instances = (new $this->class)->newCollection(array_map(function () use ($attributes) {
|
||||
return $this->makeInstance($attributes);
|
||||
}, range(1, $this->amount)));
|
||||
|
||||
$this->callAfterMaking($instances);
|
||||
|
||||
return $instances;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,9 +260,15 @@ class FactoryBuilder
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
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}].");
|
||||
}
|
||||
|
||||
$definition = call_user_func(
|
||||
$this->definitions[$this->class][$this->name],
|
||||
$this->faker, $attributes
|
||||
@@ -238,16 +284,10 @@ class FactoryBuilder
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function makeInstance(array $attributes = [])
|
||||
{
|
||||
return Model::unguarded(function () use ($attributes) {
|
||||
if (! isset($this->definitions[$this->class][$this->name])) {
|
||||
throw new InvalidArgumentException("Unable to locate factory with name [{$this->name}] [{$this->class}].");
|
||||
}
|
||||
|
||||
$instance = new $this->class(
|
||||
$this->getRawAttributes($attributes)
|
||||
);
|
||||
@@ -271,6 +311,10 @@ class FactoryBuilder
|
||||
{
|
||||
foreach ($this->activeStates as $state) {
|
||||
if (! isset($this->states[$this->class][$state])) {
|
||||
if ($this->stateHasAfterCallback($state)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Unable to locate [{$state}] state for [{$this->class}].");
|
||||
}
|
||||
|
||||
@@ -313,7 +357,7 @@ class FactoryBuilder
|
||||
protected function expandAttributes(array $attributes)
|
||||
{
|
||||
foreach ($attributes as &$attribute) {
|
||||
if (is_callable($attribute) && ! is_string($attribute)) {
|
||||
if (is_callable($attribute) && ! is_string($attribute) && ! is_array($attribute)) {
|
||||
$attribute = $attribute($attributes);
|
||||
}
|
||||
|
||||
@@ -328,4 +372,75 @@ class FactoryBuilder
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run after making callbacks on a collection of models.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $models
|
||||
* @return void
|
||||
*/
|
||||
public function callAfterMaking($models)
|
||||
{
|
||||
$this->callAfter($this->afterMaking, $models);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run after creating callbacks on a collection of models.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $models
|
||||
* @return void
|
||||
*/
|
||||
public function callAfterCreating($models)
|
||||
{
|
||||
$this->callAfter($this->afterCreating, $models);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call after callbacks for each model and state.
|
||||
*
|
||||
* @param array $afterCallbacks
|
||||
* @param \Illuminate\Support\Collection $models
|
||||
* @return void
|
||||
*/
|
||||
protected function callAfter(array $afterCallbacks, $models)
|
||||
{
|
||||
$states = array_merge([$this->name], $this->activeStates);
|
||||
|
||||
$models->each(function ($model) use ($states, $afterCallbacks) {
|
||||
foreach ($states as $state) {
|
||||
$this->callAfterCallbacks($afterCallbacks, $model, $state);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Call after callbacks for each model and state.
|
||||
*
|
||||
* @param array $afterCallbacks
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $state
|
||||
* @return void
|
||||
*/
|
||||
protected function callAfterCallbacks(array $afterCallbacks, $model, $state)
|
||||
{
|
||||
if (! isset($afterCallbacks[$this->class][$state])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($afterCallbacks[$this->class][$state] as $callback) {
|
||||
$callback($model, $this->faker);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given state has an "after" callback.
|
||||
*
|
||||
* @param string $state
|
||||
* @return bool
|
||||
*/
|
||||
protected function stateHasAfterCallback($state)
|
||||
{
|
||||
return isset($this->afterMaking[$this->class][$state]) ||
|
||||
isset($this->afterCreating[$this->class][$state]);
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Routing\UrlRoutable;
|
||||
use Illuminate\Contracts\Queue\QueueableEntity;
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
use Illuminate\Contracts\Queue\QueueableCollection;
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
use Illuminate\Database\ConnectionResolverInterface as Resolver;
|
||||
|
||||
@@ -123,6 +124,13 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
*/
|
||||
protected static $globalScopes = [];
|
||||
|
||||
/**
|
||||
* The list of models classes that should not be affected with touch.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $ignoreOnTouch = [];
|
||||
|
||||
/**
|
||||
* The name of the "created at" column.
|
||||
*
|
||||
@@ -189,9 +197,15 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
{
|
||||
$class = static::class;
|
||||
|
||||
$booted = [];
|
||||
|
||||
foreach (class_uses_recursive($class) as $trait) {
|
||||
if (method_exists($class, $method = 'boot'.class_basename($trait))) {
|
||||
$method = 'boot'.class_basename($trait);
|
||||
|
||||
if (method_exists($class, $method) && ! in_array($method, $booted)) {
|
||||
forward_static_call([$class, $method]);
|
||||
|
||||
$booted[] = $method;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,6 +222,54 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
static::$globalScopes = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables relationship model touching for the current class during given callback scope.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return void
|
||||
*/
|
||||
public static function withoutTouching(callable $callback)
|
||||
{
|
||||
static::withoutTouchingOn([static::class], $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables relationship model touching for the given model classes during given callback scope.
|
||||
*
|
||||
* @param array $models
|
||||
* @param callable $callback
|
||||
* @return void
|
||||
*/
|
||||
public static function withoutTouchingOn(array $models, callable $callback)
|
||||
{
|
||||
static::$ignoreOnTouch = array_values(array_merge(static::$ignoreOnTouch, $models));
|
||||
|
||||
try {
|
||||
call_user_func($callback);
|
||||
} finally {
|
||||
static::$ignoreOnTouch = array_values(array_diff(static::$ignoreOnTouch, $models));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given model is ignoring touches.
|
||||
*
|
||||
* @param string|null $class
|
||||
* @return bool
|
||||
*/
|
||||
public static function isIgnoringTouch($class = null)
|
||||
{
|
||||
$class = $class ?: static::class;
|
||||
|
||||
foreach (static::$ignoreOnTouch as $ignoredClass) {
|
||||
if ($class === $ignoredClass || is_subclass_of($class, $ignoredClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the model with an array of attributes.
|
||||
*
|
||||
@@ -229,7 +291,10 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
if ($this->isFillable($key)) {
|
||||
$this->setAttribute($key, $value);
|
||||
} elseif ($totallyGuarded) {
|
||||
throw new MassAssignmentException($key);
|
||||
throw new MassAssignmentException(sprintf(
|
||||
'Add [%s] to fillable property to allow mass assignment on [%s].',
|
||||
$key, get_class($this)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,16 +466,16 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
{
|
||||
$relations = is_string($relations) ? func_get_args() : $relations;
|
||||
|
||||
return $this->load(array_filter($relations, function ($relation) {
|
||||
return ! $this->relationLoaded($relation);
|
||||
}));
|
||||
$this->newCollection([$this])->loadMissing($relations);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment a column's value by a given amount.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $amount
|
||||
* @param float|int $amount
|
||||
* @param array $extra
|
||||
* @return int
|
||||
*/
|
||||
@@ -423,7 +488,7 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
* Decrement a column's value by a given amount.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $amount
|
||||
* @param float|int $amount
|
||||
* @param array $extra
|
||||
* @return int
|
||||
*/
|
||||
@@ -436,7 +501,7 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
* Run the increment or decrement method on the model.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $amount
|
||||
* @param float|int $amount
|
||||
* @param array $extra
|
||||
* @param string $method
|
||||
* @return int
|
||||
@@ -460,7 +525,7 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
* Increment the underlying attribute value and sync with original.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $amount
|
||||
* @param float|int $amount
|
||||
* @param array $extra
|
||||
* @param string $method
|
||||
* @return void
|
||||
@@ -895,9 +960,7 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
*/
|
||||
public function newQueryWithoutScope($scope)
|
||||
{
|
||||
$builder = $this->newQuery();
|
||||
|
||||
return $builder->withoutGlobalScope($scope);
|
||||
return $this->newQuery()->withoutGlobalScope($scope);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -908,11 +971,9 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
*/
|
||||
public function newQueryForRestoration($ids)
|
||||
{
|
||||
if (is_array($ids)) {
|
||||
return $this->newQueryWithoutScopes()->whereIn($this->getQualifiedKeyName(), $ids);
|
||||
}
|
||||
|
||||
return $this->newQueryWithoutScopes()->whereKey($ids);
|
||||
return is_array($ids)
|
||||
? $this->newQueryWithoutScopes()->whereIn($this->getQualifiedKeyName(), $ids)
|
||||
: $this->newQueryWithoutScopes()->whereKey($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1041,6 +1102,8 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
|
||||
$this->load(collect($this->relations)->except('pivot')->keys()->toArray());
|
||||
|
||||
$this->syncOriginal();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -1297,6 +1360,36 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
return $this->getKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the queueable relationships for the entity.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueueableRelations()
|
||||
{
|
||||
$relations = [];
|
||||
|
||||
foreach ($this->getRelations() as $key => $relation) {
|
||||
if (method_exists($this, $key)) {
|
||||
$relations[] = $key;
|
||||
}
|
||||
|
||||
if ($relation instanceof QueueableCollection) {
|
||||
foreach ($relation->getQueueableRelations() as $collectionValue) {
|
||||
$relations[] = $key.'.'.$collectionValue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($relation instanceof QueueableEntity) {
|
||||
foreach ($relation->getQueueableRelations() as $entityKey => $entityValue) {
|
||||
$relations[] = $key.'.'.$entityValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($relations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the queueable connection for the entity.
|
||||
*
|
||||
@@ -1345,7 +1438,7 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
|
||||
*/
|
||||
public function getForeignKey()
|
||||
{
|
||||
return Str::snake(class_basename($this)).'_'.$this->primaryKey;
|
||||
return Str::snake(class_basename($this)).'_'.$this->getKeyName();
|
||||
}
|
||||
|
||||
/**
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user