Commit 33636614 by abalsh

Newsletter Pt.2

parent aac610e2
Showing with 772 additions and 572 deletions
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/beyondcode/laravel-dump-server" /> <excludeFolder url="file://$MODULE_DIR$/vendor/beyondcode/laravel-dump-server" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" /> <excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/dnoegel/php-xdg-base-dir" /> <excludeFolder url="file://$MODULE_DIR$/vendor/dnoegel/php-xdg-base-dir" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/event-manager" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" /> <excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" /> <excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/lexer" /> <excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
......
...@@ -81,6 +81,9 @@ ...@@ -81,6 +81,9 @@
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" /> <path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/spatie/laravel-newsletter" /> <path value="$PROJECT_DIR$/vendor/spatie/laravel-newsletter" />
<path value="$PROJECT_DIR$/vendor/drewm/mailchimp-api" /> <path value="$PROJECT_DIR$/vendor/drewm/mailchimp-api" />
<path value="$PROJECT_DIR$/vendor/doctrine/cache" />
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
</include_path> </include_path>
</component> </component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.1" /> <component name="PhpProjectSharedConfiguration" php_language_level="7.1" />
......
...@@ -3,28 +3,23 @@ ...@@ -3,28 +3,23 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Newsletter;
class NewsletterController extends Controller
use Spatie\Newsletter\Newsletter;
class NewsLetterController extends Controller
{ {
// public function create()
function index()
{ {
return view('subscribe'); return view('subscribe');
} }
public function store(request $request){ public function store(Request $request)
if(! Newsletter::isSubscribed($request->email)){ {
if ( ! Newsletter::isSubscribed($request->email) )
{
Newsletter::subscribePending($request->email); Newsletter::subscribePending($request->email);
return redirect('subscribe')->with('success', 'Thanks For Subscribing! Check your Inbox!');
return redirect('subscribe')->with('Success', 'Please check Email');
} }
return redirect('subscribe')->with('failure', 'Sorry! You have already subscribed ');
return redirect('subscribe')->with('Fail','Sorry,Already Subscribed!');
} }
} }
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": "^7.1.3", "php": "^7.1.3",
"doctrine/dbal": "^2.9",
"fideloper/proxy": "^4.0", "fideloper/proxy": "^4.0",
"laravel/framework": "5.8.*", "laravel/framework": "5.8.*",
"laravel/tinker": "^1.0", "laravel/tinker": "^1.0",
......
<?php
return [
/*
* The API key of a MailChimp account. You can find yours at
* https://us10.admin.mailchimp.com/account/api-key-popup/.
*/
'apiKey' => env('MAILCHIMP_APIKEY'),
/*
* The listName to use when no listName has been specified in a method.
*/
'defaultListName' => 'subscribers',
/*
* Here you can define properties of the lists.
*/
'lists' => [
/*
* This key is used to identify this list. It can be used
* as the listName parameter provided in the various methods.
*
* You can set it to any string you want and you can add
* as many lists as you want.
*/
'subscribers' => [
/*
* A MailChimp list id. Check the MailChimp docs if you don't know
* how to get this value:
* http://kb.mailchimp.com/lists/managing-subscribers/find-your-list-id.
*/
'id' => env('MAILCHIMP_LIST_ID'),
],
],
/*
* If you're having trouble with https connections, set this to false.
*/
'ssl' => true,
];
<!Doctype html> <!Doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="Currency Exchange Website"> <meta name="description" content="Currency Exchange Website">
...@@ -14,47 +15,44 @@ ...@@ -14,47 +15,44 @@
<!-- Main Custom styles for the website --> <!-- Main Custom styles for the website -->
<link href="css\main.css" rel="stylesheet"> <link href="css\main.css" rel="stylesheet">
<link href="css\subscribe.css" rel="stylesheet"> <link href="css\subscribe.css" rel="stylesheet">
</head> </head>
<body class="text-center" background="img\background.jpg"> <body class="text-center" background="img\background.jpg">
<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column"> <div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
<header class="masthead mb-auto"> <header class="masthead mb-auto">
<div class="inner"> <div class="inner">
<i class="material-icons masthead-brand img-fluid">autorenew</i> <i class="material-icons masthead-brand img-fluid">autorenew</i>
<h3 class="masthead-brand">XCHANGE</h3> <h3 class="masthead-brand">XCHANGE</h3>
<nav class="nav nav-masthead justify-content-center"> <nav class="nav nav-masthead justify-content-center">
<a class="nav-link" href='/'>Home</a> <a class="nav-link" href='/'>Home</a>
<a class="nav-link" href='/currency'>Currnecy</a> <a class="nav-link" href='/currency'>Currnecy</a>
<a class="nav-link" href='/crypto'>Crypto</a> <a class="nav-link" href='/crypto'>Crypto</a>
<a class="nav-link" href='/contact'>Contact</a> <a class="nav-link" href='/contact'>Contact</a>
<a class="nav-link active" href='/subscribe'>Subscribe</a> <a class="nav-link active" href='/subscribe'>Subscribe</a>
</nav> </nav>
</div> </div>
</header> </header>
<br> <br> <br> <br>
<div class="page-wrapper bg-gra-01 p-t-180 p-b-100 font-poppins"> <div class="page-wrapper bg-gra-01 p-t-180 p-b-100 font-poppins">
<div class="wrapper wrapper--w780"> <div class="wrapper wrapper--w780">
<div class="card card-3"> <div class="card card-3">
<div class="card-heading"></div> <div class="card-heading"></div>
<div class="card-body"> <div class="card-body">
@if (Session::has('success')) @if (\Session::has('success'))
<div class="alert alert-success" role="alert"> <div class="alert alert-success">
{{ session('success') }} <p>{{ \Session::get('success') }}</p>
</div> </div><br />
@endif
@if (Session::has('failure'))
<div class="alert alert-danger" role="alert">
{{ session('failure') }}
</div>
@endif @endif
<h2 class="title">Subscribe to our newsletter!</h2> @if (\Session::has('failure'))
<br> <div class="alert alert-danger">
<p class="paragraph">Subscribe to our Newsletter to get more information about fiat and crypto currencies. By subscribing to us, you will be receiving everyday five main news article stories to get updated on what is going on in the currency world.</p> <p>{{ \Session::get('failure') }}</p>
<br> </div><br />
<form action={{url('/subscribe/newsletter')}} method="POST"> @endif
{{csrf_field()}} <h2 class="title">Subscribe to our newsletter!</h2>
<div class="input-group"> <br>
<input class="input--style-3" type="text" placeholder="Name" name="name"> <p class="paragraph">Subscribe to our Newsletter to get more information about fiat and crypto currencies. By subscribing to us, you will be receiving everyday five main news article stories to get updated on what is going on in the currency world.</p>
</div> <br>
<form action={{url('/subscribe')}} method="post">
@csrf
<div class="input-group"> <div class="input-group">
<input class="input--style-3" type="email" placeholder="Email" name="email"> <input class="input--style-3" type="email" placeholder="Email" name="email">
</div> </div>
...@@ -69,9 +67,9 @@ ...@@ -69,9 +67,9 @@
</div> </div>
<footer class="mastfoot mt-auto"> <footer class="mastfoot mt-auto">
<div class="inner"> <div class="inner">
<p>Develeoped and Designed by <a href="#">&#169;Garlix</a>.</p> <p>Develeoped and Designed by <a href="#">&#169;Garlix</a>.</p>
</div> </div>
</footer> </footer>
</div> </div>
</body> </body>
</html> </html>
...@@ -40,6 +40,6 @@ Auth::routes(); ...@@ -40,6 +40,6 @@ Auth::routes();
Route::get('/home', 'HomeController@index')->name('home'); Route::get('/home', 'HomeController@index')->name('home');
Route::get('/subscribe', 'NewsLetterController@index'); Route::get('/subscribe', 'NewsLetterController@create');
Route::post('/subscribe/newsletter', 'NewsLetterController@store'); Route::post('/subscribe', 'NewsLetterController@store');
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Composer
Upstream-Contact: Jordi Boggiano <j.boggiano@seld.be>
Source: https://github.com/composer/composer
Copyright (c) Nils Adermann, Jordi Boggiano Files: *
Copyright: 2016, Nils Adermann <naderman@naderman.de>
2016, Jordi Boggiano <j.boggiano@seld.be>
License: Expat
Permission is hereby granted, free of charge, to any person obtaining a copy Files: src/Composer/Util/TlsHelper.php
of this software and associated documentation files (the "Software"), to deal Copyright: 2016, Nils Adermann <naderman@naderman.de>
in the Software without restriction, including without limitation the rights 2016, Jordi Boggiano <j.boggiano@seld.be>
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 2013, Evan Coury <me@evancoury.com>
copies of the Software, and to permit persons to whom the Software is furnished License: Expat and BSD-2-Clause
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all License: BSD-2-Clause
copies or substantial portions of the Software. Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR .
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * Redistributions of source code must retain the above copyright notice,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE this list of conditions and the following disclaimer.
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER .
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * Redistributions in binary form must reproduce the above copyright notice,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN this list of conditions and the following disclaimer in the documentation
THE SOFTWARE. and/or other materials provided with the distribution.
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: Expat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
...@@ -50,7 +50,10 @@ return array( ...@@ -50,7 +50,10 @@ return array(
'DrewM\\MailChimp\\' => array($vendorDir . '/drewm/mailchimp-api/src'), 'DrewM\\MailChimp\\' => array($vendorDir . '/drewm/mailchimp-api/src'),
'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'), 'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'),
'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
'Doctrine\\DBAL\\' => array($vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL'),
'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Common/Inflector'), 'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Common/Inflector'),
'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'),
'Doctrine\\Common\\' => array($vendorDir . '/doctrine/event-manager/lib/Doctrine/Common'),
'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'), 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
'Cron\\' => array($vendorDir . '/dragonmantank/cron-expression/src/Cron'), 'Cron\\' => array($vendorDir . '/dragonmantank/cron-expression/src/Cron'),
'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'), 'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'),
......
...@@ -20,7 +20,7 @@ Laravel is a web application framework with expressive, elegant syntax. We belie ...@@ -20,7 +20,7 @@ Laravel is a web application framework with expressive, elegant syntax. We belie
- [Robust background job processing](https://laravel.com/docs/queues). - [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting). - [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, yet powerful, providing tools needed for large, robust applications. A superb combination of simplicity, elegance, and innovation gives you a complete toolset required to build any application with which you are tasked Laravel is accessible, yet powerful, providing tools needed for large, robust applications. A superb combination of simplicity, elegance, and innovation gives you a complete toolset required to build any application with which you are tasked.
## Learning Laravel ## Learning Laravel
......
...@@ -527,7 +527,6 @@ class Gate implements GateContract ...@@ -527,7 +527,6 @@ class Gate implements GateContract
} }
return function () { return function () {
return null;
}; };
} }
...@@ -653,7 +652,7 @@ class Gate implements GateContract ...@@ -653,7 +652,7 @@ class Gate implements GateContract
protected function callPolicyBefore($policy, $user, $ability, $arguments) protected function callPolicyBefore($policy, $user, $ability, $arguments)
{ {
if (! method_exists($policy, 'before')) { if (! method_exists($policy, 'before')) {
return null; return;
} }
if ($this->canBeCalledWithUser($user, $policy, 'before')) { if ($this->canBeCalledWithUser($user, $policy, 'before')) {
...@@ -680,7 +679,7 @@ class Gate implements GateContract ...@@ -680,7 +679,7 @@ class Gate implements GateContract
} }
if (! is_callable([$policy, $method])) { if (! is_callable([$policy, $method])) {
return null; return;
} }
if ($this->canBeCalledWithUser($user, $policy, $method)) { if ($this->canBeCalledWithUser($user, $policy, $method)) {
......
...@@ -74,11 +74,11 @@ class AuthMakeCommand extends Command ...@@ -74,11 +74,11 @@ class AuthMakeCommand extends Command
*/ */
protected function createDirectories() protected function createDirectories()
{ {
if (! is_dir($directory = resource_path('views/layouts'))) { if (! is_dir($directory = $this->getViewPath('layouts'))) {
mkdir($directory, 0755, true); mkdir($directory, 0755, true);
} }
if (! is_dir($directory = resource_path('views/auth/passwords'))) { if (! is_dir($directory = $this->getViewPath('auth/passwords'))) {
mkdir($directory, 0755, true); mkdir($directory, 0755, true);
} }
} }
...@@ -91,7 +91,7 @@ class AuthMakeCommand extends Command ...@@ -91,7 +91,7 @@ class AuthMakeCommand extends Command
protected function exportViews() protected function exportViews()
{ {
foreach ($this->views as $key => $value) { foreach ($this->views as $key => $value) {
if (file_exists($view = resource_path('views/'.$value)) && ! $this->option('force')) { if (file_exists($view = $this->getViewPath($value)) && ! $this->option('force')) {
if (! $this->confirm("The [{$value}] view already exists. Do you want to replace it?")) { if (! $this->confirm("The [{$value}] view already exists. Do you want to replace it?")) {
continue; continue;
} }
...@@ -117,4 +117,16 @@ class AuthMakeCommand extends Command ...@@ -117,4 +117,16 @@ class AuthMakeCommand extends Command
file_get_contents(__DIR__.'/stubs/make/controllers/HomeController.stub') file_get_contents(__DIR__.'/stubs/make/controllers/HomeController.stub')
); );
} }
/**
* Get full view path relative to the app's configured view path.
*
* @return string
*/
protected function getViewPath($path)
{
return implode(DIRECTORY_SEPARATOR, [
config('view.paths')[0] ?? resource_path('views'), $path,
]);
}
} }
...@@ -15,13 +15,13 @@ ...@@ -15,13 +15,13 @@
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6"> <div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus> <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@if ($errors->has('email')) @error('email')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong> <strong>{{ $message }}</strong>
</span> </span>
@endif @enderror
</div> </div>
</div> </div>
...@@ -29,13 +29,13 @@ ...@@ -29,13 +29,13 @@
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label> <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6"> <div class="col-md-6">
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required autocomplete="current-password"> <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@if ($errors->has('password')) @error('password')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('password') }}</strong> <strong>{{ $message }}</strong>
</span> </span>
@endif @enderror
</div> </div>
</div> </div>
......
...@@ -21,13 +21,13 @@ ...@@ -21,13 +21,13 @@
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6"> <div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus> <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@if ($errors->has('email')) @error('email')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong> <strong>{{ $message }}</strong>
</span> </span>
@endif @enderror
</div> </div>
</div> </div>
......
...@@ -17,13 +17,13 @@ ...@@ -17,13 +17,13 @@
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6"> <div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus> <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus>
@if ($errors->has('email')) @error('email')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong> <strong>{{ $message }}</strong>
</span> </span>
@endif @enderror
</div> </div>
</div> </div>
...@@ -31,13 +31,13 @@ ...@@ -31,13 +31,13 @@
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label> <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6"> <div class="col-md-6">
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required autocomplete="new-password"> <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
@if ($errors->has('password')) @error('password')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('password') }}</strong> <strong>{{ $message }}</strong>
</span> </span>
@endif @enderror
</div> </div>
</div> </div>
......
...@@ -15,13 +15,13 @@ ...@@ -15,13 +15,13 @@
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label> <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
<div class="col-md-6"> <div class="col-md-6">
<input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus> <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@if ($errors->has('name')) @error('name')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('name') }}</strong> <strong>{{ $message }}</strong>
</span> </span>
@endif @enderror
</div> </div>
</div> </div>
...@@ -29,13 +29,13 @@ ...@@ -29,13 +29,13 @@
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6"> <div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autocomplete="email"> <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">
@if ($errors->has('email')) @error('email')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong> <strong>{{ $message }}</strong>
</span> </span>
@endif @enderror
</div> </div>
</div> </div>
...@@ -43,13 +43,13 @@ ...@@ -43,13 +43,13 @@
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label> <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6"> <div class="col-md-6">
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required autocomplete="new-password"> <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
@if ($errors->has('password')) @error('password')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('password') }}</strong> <strong>{{ $message }}</strong>
</span> </span>
@endif @enderror
</div> </div>
</div> </div>
......
...@@ -68,7 +68,7 @@ class EloquentUserProvider implements UserProvider ...@@ -68,7 +68,7 @@ class EloquentUserProvider implements UserProvider
)->first(); )->first();
if (! $retrievedModel) { if (! $retrievedModel) {
return null; return;
} }
$rememberToken = $retrievedModel->getRememberToken(); $rememberToken = $retrievedModel->getRememberToken();
......
...@@ -46,9 +46,7 @@ class PasswordBrokerManager implements FactoryContract ...@@ -46,9 +46,7 @@ class PasswordBrokerManager implements FactoryContract
{ {
$name = $name ?: $this->getDefaultDriver(); $name = $name ?: $this->getDefaultDriver();
return isset($this->brokers[$name]) return $this->brokers[$name] ?? ($this->brokers[$name] = $this->resolve($name));
? $this->brokers[$name]
: $this->brokers[$name] = $this->resolve($name);
} }
/** /**
......
...@@ -550,7 +550,10 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth ...@@ -550,7 +550,10 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
$attribute => Hash::make($password), $attribute => Hash::make($password),
]))->save(); ]))->save();
$this->queueRecallerCookie($this->user()); if ($this->recaller() ||
$this->getCookieJar()->hasQueued($this->getRecallerName())) {
$this->queueRecallerCookie($this->user());
}
$this->fireOtherDeviceLogoutEvent($this->user()); $this->fireOtherDeviceLogoutEvent($this->user());
......
...@@ -294,8 +294,6 @@ abstract class Broadcaster implements BroadcasterContract ...@@ -294,8 +294,6 @@ abstract class Broadcaster implements BroadcasterContract
return $user; return $user;
} }
} }
return null;
} }
/** /**
......
...@@ -24,7 +24,7 @@ class ArrayStore extends TaggableStore ...@@ -24,7 +24,7 @@ class ArrayStore extends TaggableStore
public function get($key) public function get($key)
{ {
if (! isset($this->storage[$key])) { if (! isset($this->storage[$key])) {
return null; return;
} }
$item = $this->storage[$key]; $item = $this->storage[$key];
...@@ -34,7 +34,7 @@ class ArrayStore extends TaggableStore ...@@ -34,7 +34,7 @@ class ArrayStore extends TaggableStore
if ($expiresAt !== 0 && $this->currentTime() > $expiresAt) { if ($expiresAt !== 0 && $this->currentTime() > $expiresAt) {
$this->forget($key); $this->forget($key);
return null; return;
} }
return $item['value']; return $item['value'];
......
...@@ -151,7 +151,6 @@ class DynamoDbStore implements Store, LockProvider ...@@ -151,7 +151,6 @@ class DynamoDbStore implements Store, LockProvider
$now = Carbon::now(); $now = Carbon::now();
return array_merge(collect(array_flip($keys))->map(function () { return array_merge(collect(array_flip($keys))->map(function () {
return null;
})->all(), collect($response['Responses'][$this->table])->mapWithKeys(function ($response) use ($now) { })->all(), collect($response['Responses'][$this->table])->mapWithKeys(function ($response) use ($now) {
if ($this->isExpired($response, $now)) { if ($this->isExpired($response, $now)) {
$value = null; $value = null;
......
...@@ -21,7 +21,6 @@ class NullStore extends TaggableStore ...@@ -21,7 +21,6 @@ class NullStore extends TaggableStore
*/ */
public function get($key) public function get($key)
{ {
return null;
} }
/** /**
......
...@@ -546,11 +546,7 @@ class Container implements ArrayAccess, ContainerContract ...@@ -546,11 +546,7 @@ class Container implements ArrayAccess, ContainerContract
*/ */
protected function getReboundCallbacks($abstract) protected function getReboundCallbacks($abstract)
{ {
if (isset($this->reboundCallbacks[$abstract])) { return $this->reboundCallbacks[$abstract] ?? [];
return $this->reboundCallbacks[$abstract];
}
return [];
} }
/** /**
...@@ -1122,11 +1118,7 @@ class Container implements ArrayAccess, ContainerContract ...@@ -1122,11 +1118,7 @@ class Container implements ArrayAccess, ContainerContract
{ {
$abstract = $this->getAlias($abstract); $abstract = $this->getAlias($abstract);
if (isset($this->extenders[$abstract])) { return $this->extenders[$abstract] ?? [];
return $this->extenders[$abstract];
}
return [];
} }
/** /**
......
...@@ -15,7 +15,7 @@ interface UserProvider ...@@ -15,7 +15,7 @@ interface UserProvider
/** /**
* Retrieve a user by their unique identifier and "remember me" token. * Retrieve a user by their unique identifier and "remember me" token.
* *
* @param mixed $identifier * @param mixed $identifier
* @param string $token * @param string $token
* @return \Illuminate\Contracts\Auth\Authenticatable|null * @return \Illuminate\Contracts\Auth\Authenticatable|null
*/ */
......
...@@ -1118,7 +1118,7 @@ class Connection implements ConnectionInterface ...@@ -1118,7 +1118,7 @@ class Connection implements ConnectionInterface
} }
/** /**
* Determine if the connection in a "dry run". * Determine if the connection is in a "dry run".
* *
* @return bool * @return bool
*/ */
......
...@@ -151,7 +151,8 @@ class DatabaseManager implements ConnectionResolverInterface ...@@ -151,7 +151,8 @@ class DatabaseManager implements ConnectionResolverInterface
throw new InvalidArgumentException("Database [{$name}] not configured."); throw new InvalidArgumentException("Database [{$name}] not configured.");
} }
return $config; return (new ConfigurationUrlParser)
->parseConfiguration($config);
} }
/** /**
......
...@@ -141,7 +141,7 @@ class Collection extends BaseCollection implements QueueableCollection ...@@ -141,7 +141,7 @@ class Collection extends BaseCollection implements QueueableCollection
* @param array $path * @param array $path
* @return void * @return void
*/ */
protected function loadMissingRelation(Collection $models, array $path) protected function loadMissingRelation(self $models, array $path)
{ {
$relation = array_shift($path); $relation = array_shift($path);
......
...@@ -50,7 +50,7 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab ...@@ -50,7 +50,7 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
protected $primaryKey = 'id'; protected $primaryKey = 'id';
/** /**
* The "type" of the auto-incrementing ID. * The "type" of the primary key ID.
* *
* @var string * @var string
*/ */
...@@ -1287,9 +1287,7 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab ...@@ -1287,9 +1287,7 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
*/ */
public function getTable() public function getTable()
{ {
return isset($this->table) return $this->table ?? Str::snake(Str::pluralStudly(class_basename($this)));
? $this->table
: Str::snake(Str::pluralStudly(class_basename($this)));
} }
/** /**
......
...@@ -214,7 +214,7 @@ trait InteractsWithPivotTable ...@@ -214,7 +214,7 @@ trait InteractsWithPivotTable
protected function updateExistingPivotUsingCustomClass($id, array $attributes, $touch) protected function updateExistingPivotUsingCustomClass($id, array $attributes, $touch)
{ {
$updated = $this->newPivot([ $updated = $this->newPivot([
$this->foreignPivotKey => $this->parent->getKey(), $this->foreignPivotKey => $this->parent->{$this->parentKey},
$this->relatedPivotKey => $this->parseId($id), $this->relatedPivotKey => $this->parseId($id),
], true)->fill($attributes)->save(); ], true)->fill($attributes)->save();
...@@ -446,7 +446,7 @@ trait InteractsWithPivotTable ...@@ -446,7 +446,7 @@ trait InteractsWithPivotTable
foreach ($this->parseIds($ids) as $id) { foreach ($this->parseIds($ids) as $id) {
$results += $this->newPivot([ $results += $this->newPivot([
$this->foreignPivotKey => $this->parent->getKey(), $this->foreignPivotKey => $this->parent->{$this->parentKey},
$this->relatedPivotKey => $id, $this->relatedPivotKey => $id,
], true)->delete(); ], true)->delete();
} }
......
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
namespace Illuminate\Database\Eloquent; namespace Illuminate\Database\Eloquent;
/**
* @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withTrashed()
* @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder onlyTrashed()
* @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withoutTrashed()
* @method bool restore()
*/
trait SoftDeletes trait SoftDeletes
{ {
/** /**
......
...@@ -580,7 +580,7 @@ class Migrator ...@@ -580,7 +580,7 @@ class Migrator
} }
/** /**
* Write a note to the conosle's output. * Write a note to the console's output.
* *
* @param string $message * @param string $message
* @return void * @return void
......
...@@ -2979,6 +2979,26 @@ class Builder ...@@ -2979,6 +2979,26 @@ class Builder
} }
/** /**
* Dump the current SQL and bindings.
*
* @return void
*/
public function dump()
{
dump($this->toSql(), $this->getBindings());
}
/**
* Die and dump the current SQL and bindings.
*
* @return void
*/
public function dd()
{
dd($this->toSql(), $this->getBindings());
}
/**
* Handle dynamic method calls into the method. * Handle dynamic method calls into the method.
* *
* @param string $method * @param string $method
......
...@@ -733,9 +733,7 @@ class Grammar extends BaseGrammar ...@@ -733,9 +733,7 @@ class Grammar extends BaseGrammar
protected function compileOrdersToArray(Builder $query, $orders) protected function compileOrdersToArray(Builder $query, $orders)
{ {
return array_map(function ($order) { return array_map(function ($order) {
return ! isset($order['sql']) return $order['sql'] ?? $this->wrap($order['column']).' '.$order['direction'];
? $this->wrap($order['column']).' '.$order['direction']
: $order['sql'];
}, $orders); }, $orders);
} }
......
...@@ -2,27 +2,11 @@ ...@@ -2,27 +2,11 @@
namespace Illuminate\Database\Schema; namespace Illuminate\Database\Schema;
use Illuminate\Database\Connection;
use Illuminate\Database\Schema\Types\TinyInteger; use Illuminate\Database\Schema\Types\TinyInteger;
class MySqlBuilder extends Builder class MySqlBuilder extends Builder
{ {
/** /**
* Create a new builder instance.
*
* @param \Illuminate\Database\Connection $connection
* @return void
*
* @throws \Doctrine\DBAL\DBALException
*/
public function __construct(Connection $connection)
{
parent::__construct($connection);
$this->registerCustomDoctrineTypes();
}
/**
* Determine if the given table exists. * Determine if the given table exists.
* *
* @param string $table * @param string $table
......
...@@ -29,7 +29,7 @@ class Application extends Container implements ApplicationContract, HttpKernelIn ...@@ -29,7 +29,7 @@ class Application extends Container implements ApplicationContract, HttpKernelIn
* *
* @var string * @var string
*/ */
const VERSION = '5.8.13'; const VERSION = '5.8.15';
/** /**
* The base path for the Laravel installation. * The base path for the Laravel installation.
......
...@@ -31,7 +31,7 @@ trait SendsPasswordResetEmails ...@@ -31,7 +31,7 @@ trait SendsPasswordResetEmails
// to send the link, we will examine the response then see the message we // to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response. // need to show to the user. Finally, we'll send out a proper response.
$response = $this->broker()->sendResetLink( $response = $this->broker()->sendResetLink(
$request->only('email') $this->credentials($request)
); );
return $response == Password::RESET_LINK_SENT return $response == Password::RESET_LINK_SENT
...@@ -51,6 +51,17 @@ trait SendsPasswordResetEmails ...@@ -51,6 +51,17 @@ trait SendsPasswordResetEmails
} }
/** /**
* Get the needed authentication credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
return $request->only('email');
}
/**
* Get the response for a successful password reset link. * Get the response for a successful password reset link.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
......
// Body // Body
$body-bg: #f8fafc; $body-bg: #f8fafc;
// Typography // Typography
$font-family-sans-serif: "Nunito", sans-serif; $font-family-sans-serif: 'Nunito', sans-serif;
$font-size-base: 0.9rem; $font-size-base: 0.9rem;
$line-height-base: 1.6; $line-height-base: 1.6;
...@@ -11,7 +10,7 @@ $line-height-base: 1.6; ...@@ -11,7 +10,7 @@ $line-height-base: 1.6;
$blue: #3490dc; $blue: #3490dc;
$indigo: #6574cd; $indigo: #6574cd;
$purple: #9561e2; $purple: #9561e2;
$pink: #f66D9b; $pink: #f66d9b;
$red: #e3342f; $red: #e3342f;
$orange: #f6993f; $orange: #f6993f;
$yellow: #ffed4a; $yellow: #ffed4a;
......
// Fonts // Fonts
@import url('https://fonts.googleapis.com/css?family=Nunito'); @import url('https://fonts.googleapis.com/css?family=Nunito');
...@@ -9,6 +8,6 @@ ...@@ -9,6 +8,6 @@
@import '~bootstrap/scss/bootstrap'; @import '~bootstrap/scss/bootstrap';
.navbar-laravel { .navbar-laravel {
background-color: #fff; background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
} }
/** /**
* First, we will load all of this project's Javascript utilities and other * First, we will load all of this project's Javascript utilities and other
* dependencies. Then, we will be ready to develop a robust and powerful * dependencies. Then, we will be ready to develop a robust and powerful
......
...@@ -10,9 +10,7 @@ export default class Example extends Component { ...@@ -10,9 +10,7 @@ export default class Example extends Component {
<div className="card"> <div className="card">
<div className="card-header">Example Component</div> <div className="card-header">Example Component</div>
<div className="card-body"> <div className="card-body">I'm an example component!</div>
I'm an example component!
</div>
</div> </div>
</div> </div>
</div> </div>
......
/** /**
* First we will load all of this project's JavaScript dependencies which * First we will load all of this project's JavaScript dependencies which
* includes React and other helpers. It's a great starting point while * includes React and other helpers. It's a great starting point while
......
/** /**
* First we will load all of this project's JavaScript dependencies which * First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when * includes Vue and other libraries. It is a great starting point when
...@@ -29,5 +28,5 @@ Vue.component('example-component', require('./components/ExampleComponent.vue'). ...@@ -29,5 +28,5 @@ Vue.component('example-component', require('./components/ExampleComponent.vue').
*/ */
const app = new Vue({ const app = new Vue({
el: '#app' el: '#app',
}); });
...@@ -79,7 +79,7 @@ class VerifyCsrfToken ...@@ -79,7 +79,7 @@ class VerifyCsrfToken
}); });
} }
throw new TokenMismatchException; throw new TokenMismatchException('CSRF token mismatch.');
} }
/** /**
......
...@@ -915,7 +915,7 @@ class TestResponse ...@@ -915,7 +915,7 @@ class TestResponse
$keys = (array) $keys; $keys = (array) $keys;
if (empty($keys)) { if (empty($keys)) {
return $this->assertSessionMissing('errors'); return $this->assertSessionHasNoErrors();
} }
if (is_null($this->session()->get('errors'))) { if (is_null($this->session()->get('errors'))) {
......
...@@ -167,7 +167,7 @@ trait ConditionallyLoadsAttributes ...@@ -167,7 +167,7 @@ trait ConditionallyLoadsAttributes
} }
if ($this->resource->{$relationship} === null) { if ($this->resource->{$relationship} === null) {
return null; return;
} }
return value($value); return value($value);
......
<table class="action" align="center" width="100%" cellpadding="0" cellspacing="0"> <table class="action" align="center" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td align="center"> <td align="center">
<table width="100%" border="0" cellpadding="0" cellspacing="0"> <table width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td align="center"> <td align="center">
<table border="0" cellpadding="0" cellspacing="0"> <table border="0" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td> <td>
<a href="{{ $url }}" class="button button-{{ $color ?? 'primary' }}" target="_blank">{{ $slot }}</a> <a href="{{ $url }}" class="button button-{{ $color ?? 'primary' }}" target="_blank">{{ $slot }}</a>
......
<tr> <tr>
<td> <td>
<table class="footer" align="center" width="570" cellpadding="0" cellspacing="0"> <table class="footer" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td class="content-cell" align="center"> <td class="content-cell" align="center">
{{ Illuminate\Mail\Markdown::parse($slot) }} {{ Illuminate\Mail\Markdown::parse($slot) }}
......
...@@ -23,16 +23,16 @@ ...@@ -23,16 +23,16 @@
} }
</style> </style>
<table class="wrapper" width="100%" cellpadding="0" cellspacing="0"> <table class="wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td align="center"> <td align="center">
<table class="content" width="100%" cellpadding="0" cellspacing="0"> <table class="content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
{{ $header ?? '' }} {{ $header ?? '' }}
<!-- Email Body --> <!-- Email Body -->
<tr> <tr>
<td class="body" width="100%" cellpadding="0" cellspacing="0"> <td class="body" width="100%" cellpadding="0" cellspacing="0">
<table class="inner-body" align="center" width="570" cellpadding="0" cellspacing="0"> <table class="inner-body" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
<!-- Body content --> <!-- Body content -->
<tr> <tr>
<td class="content-cell"> <td class="content-cell">
......
<table class="panel" width="100%" cellpadding="0" cellspacing="0"> <table class="panel" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td class="panel-content"> <td class="panel-content">
<table width="100%" cellpadding="0" cellspacing="0"> <table width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td class="panel-item"> <td class="panel-item">
{{ Illuminate\Mail\Markdown::parse($slot) }} {{ Illuminate\Mail\Markdown::parse($slot) }}
......
<table class="promotion" align="center" width="100%" cellpadding="0" cellspacing="0"> <table class="promotion" align="center" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td align="center"> <td align="center">
{{ Illuminate\Mail\Markdown::parse($slot) }} {{ Illuminate\Mail\Markdown::parse($slot) }}
......
<table width="100%" border="0" cellpadding="0" cellspacing="0"> <table width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td align="center"> <td align="center">
<table border="0" cellpadding="0" cellspacing="0"> <table border="0" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td> <td>
<a href="{{ $url }}" class="button button-green" target="_blank">{{ $slot }}</a> <a href="{{ $url }}" class="button button-green" target="_blank">{{ $slot }}</a>
......
<table class="subcopy" width="100%" cellpadding="0" cellspacing="0"> <table class="subcopy" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr> <tr>
<td> <td>
{{ Illuminate\Mail\Markdown::parse($slot) }} {{ Illuminate\Mail\Markdown::parse($slot) }}
......
/* Base */ /* Base */
body, body *:not(html):not(style):not(br):not(tr):not(code) { body,
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; body *:not(html):not(style):not(br):not(tr):not(code) {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
box-sizing: border-box; box-sizing: border-box;
} }
body { body {
background-color: #F8FAFC; background-color: #f8fafc;
color: #74787E; color: #74787e;
height: 100%; height: 100%;
hyphens: auto; hyphens: auto;
line-height: 1.4; line-height: 1.4;
...@@ -30,7 +32,7 @@ blockquote { ...@@ -30,7 +32,7 @@ blockquote {
} }
a { a {
color: #3869D4; color: #3869d4;
} }
a img { a img {
...@@ -40,7 +42,7 @@ a img { ...@@ -40,7 +42,7 @@ a img {
/* Typography */ /* Typography */
h1 { h1 {
color: #3D4852; color: #3d4852;
font-size: 19px; font-size: 19px;
font-weight: bold; font-weight: bold;
margin-top: 0; margin-top: 0;
...@@ -48,7 +50,7 @@ h1 { ...@@ -48,7 +50,7 @@ h1 {
} }
h2 { h2 {
color: #3D4852; color: #3d4852;
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
margin-top: 0; margin-top: 0;
...@@ -56,7 +58,7 @@ h2 { ...@@ -56,7 +58,7 @@ h2 {
} }
h3 { h3 {
color: #3D4852; color: #3d4852;
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: bold;
margin-top: 0; margin-top: 0;
...@@ -64,7 +66,7 @@ h3 { ...@@ -64,7 +66,7 @@ h3 {
} }
p { p {
color: #3D4852; color: #3d4852;
font-size: 16px; font-size: 16px;
line-height: 1.5em; line-height: 1.5em;
margin-top: 0; margin-top: 0;
...@@ -82,7 +84,7 @@ img { ...@@ -82,7 +84,7 @@ img {
/* Layout */ /* Layout */
.wrapper { .wrapper {
background-color: #F8FAFC; background-color: #f8fafc;
margin: 0; margin: 0;
padding: 0; padding: 0;
width: 100%; width: 100%;
...@@ -118,9 +120,9 @@ img { ...@@ -118,9 +120,9 @@ img {
/* Body */ /* Body */
.body { .body {
background-color: #FFFFFF; background-color: #ffffff;
border-bottom: 1px solid #EDEFF2; border-bottom: 1px solid #edeff2;
border-top: 1px solid #EDEFF2; border-top: 1px solid #edeff2;
margin: 0; margin: 0;
padding: 0; padding: 0;
width: 100%; width: 100%;
...@@ -130,7 +132,7 @@ img { ...@@ -130,7 +132,7 @@ img {
} }
.inner-body { .inner-body {
background-color: #FFFFFF; background-color: #ffffff;
margin: 0 auto; margin: 0 auto;
padding: 0; padding: 0;
width: 570px; width: 570px;
...@@ -142,7 +144,7 @@ img { ...@@ -142,7 +144,7 @@ img {
/* Subcopy */ /* Subcopy */
.subcopy { .subcopy {
border-top: 1px solid #EDEFF2; border-top: 1px solid #edeff2;
margin-top: 25px; margin-top: 25px;
padding-top: 25px; padding-top: 25px;
} }
...@@ -164,7 +166,7 @@ img { ...@@ -164,7 +166,7 @@ img {
} }
.footer p { .footer p {
color: #AEAEAE; color: #aeaeae;
font-size: 12px; font-size: 12px;
text-align: center; text-align: center;
} }
...@@ -180,13 +182,13 @@ img { ...@@ -180,13 +182,13 @@ img {
} }
.table th { .table th {
border-bottom: 1px solid #EDEFF2; border-bottom: 1px solid #edeff2;
padding-bottom: 8px; padding-bottom: 8px;
margin: 0; margin: 0;
} }
.table td { .table td {
color: #74787E; color: #74787e;
font-size: 15px; font-size: 15px;
line-height: 18px; line-height: 18px;
padding: 10px 0; padding: 10px 0;
...@@ -212,7 +214,7 @@ img { ...@@ -212,7 +214,7 @@ img {
.button { .button {
border-radius: 3px; border-radius: 3px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16); box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
color: #FFF; color: #fff;
display: inline-block; display: inline-block;
text-decoration: none; text-decoration: none;
-webkit-text-size-adjust: none; -webkit-text-size-adjust: none;
...@@ -220,29 +222,29 @@ img { ...@@ -220,29 +222,29 @@ img {
.button-blue, .button-blue,
.button-primary { .button-primary {
background-color: #3490DC; background-color: #3490dc;
border-top: 10px solid #3490DC; border-top: 10px solid #3490dc;
border-right: 18px solid #3490DC; border-right: 18px solid #3490dc;
border-bottom: 10px solid #3490DC; border-bottom: 10px solid #3490dc;
border-left: 18px solid #3490DC; border-left: 18px solid #3490dc;
} }
.button-green, .button-green,
.button-success { .button-success {
background-color: #38C172; background-color: #38c172;
border-top: 10px solid #38C172; border-top: 10px solid #38c172;
border-right: 18px solid #38C172; border-right: 18px solid #38c172;
border-bottom: 10px solid #38C172; border-bottom: 10px solid #38c172;
border-left: 18px solid #38C172; border-left: 18px solid #38c172;
} }
.button-red, .button-red,
.button-error { .button-error {
background-color: #E3342F; background-color: #e3342f;
border-top: 10px solid #E3342F; border-top: 10px solid #e3342f;
border-right: 18px solid #E3342F; border-right: 18px solid #e3342f;
border-bottom: 10px solid #E3342F; border-bottom: 10px solid #e3342f;
border-left: 18px solid #E3342F; border-left: 18px solid #e3342f;
} }
/* Panels */ /* Panels */
...@@ -252,7 +254,7 @@ img { ...@@ -252,7 +254,7 @@ img {
} }
.panel-content { .panel-content {
background-color: #F1F5F8; background-color: #f1f5f8;
padding: 16px; padding: 16px;
} }
...@@ -268,8 +270,8 @@ img { ...@@ -268,8 +270,8 @@ img {
/* Promotions */ /* Promotions */
.promotion { .promotion {
background-color: #FFFFFF; background-color: #ffffff;
border: 2px dashed #9BA2AB; border: 2px dashed #9ba2ab;
margin: 0; margin: 0;
margin-bottom: 25px; margin-bottom: 25px;
margin-top: 25px; margin-top: 25px;
......
...@@ -98,11 +98,7 @@ class ListFailedCommand extends Command ...@@ -98,11 +98,7 @@ class ListFailedCommand extends Command
{ {
preg_match('/"([^"]+)"/', $payload['data']['command'], $matches); preg_match('/"([^"]+)"/', $payload['data']['command'], $matches);
if (isset($matches[1])) { return $matches[1] ?? $payload['job'] ?? null;
return $matches[1];
}
return $payload['job'] ?? null;
} }
/** /**
......
...@@ -199,8 +199,6 @@ class DatabaseQueue extends Queue implements QueueContract ...@@ -199,8 +199,6 @@ class DatabaseQueue extends Queue implements QueueContract
if ($job = $this->getNextAvailableJob($queue)) { if ($job = $this->getNextAvailableJob($queue)) {
return $this->marshalJob($queue, $job); return $this->marshalJob($queue, $job);
} }
return null;
}); });
} }
......
...@@ -234,6 +234,16 @@ abstract class Job ...@@ -234,6 +234,16 @@ abstract class Job
} }
/** /**
* Get the number of seconds to delay a failed job before retrying it.
*
* @return int|null
*/
public function delaySeconds()
{
return $this->payload()['delay'] ?? null;
}
/**
* Get the number of seconds the job can run. * Get the number of seconds the job can run.
* *
* @return int|null * @return int|null
......
...@@ -124,6 +124,7 @@ abstract class Queue ...@@ -124,6 +124,7 @@ abstract class Queue
'displayName' => $this->getDisplayName($job), 'displayName' => $this->getDisplayName($job),
'job' => 'Illuminate\Queue\CallQueuedHandler@call', 'job' => 'Illuminate\Queue\CallQueuedHandler@call',
'maxTries' => $job->tries ?? null, 'maxTries' => $job->tries ?? null,
'delay' => $this->getJobRetryDelay($job),
'timeout' => $job->timeout ?? null, 'timeout' => $job->timeout ?? null,
'timeoutAt' => $this->getJobExpiration($job), 'timeoutAt' => $this->getJobExpiration($job),
'data' => [ 'data' => [
...@@ -153,6 +154,24 @@ abstract class Queue ...@@ -153,6 +154,24 @@ abstract class Queue
} }
/** /**
* Get the retry delay for an object-based queue handler.
*
* @param mixed $job
* @return mixed
*/
public function getJobRetryDelay($job)
{
if (! method_exists($job, 'retryAfter') && ! isset($job->retryAfter)) {
return;
}
$delay = $job->retryAfter ?? $job->retryAfter();
return $delay instanceof DateTimeInterface
? $this->secondsUntil($delay) : $delay;
}
/**
* Get the expiration timestamp for an object-based queue handler. * Get the expiration timestamp for an object-based queue handler.
* *
* @param mixed $job * @param mixed $job
...@@ -184,6 +203,7 @@ abstract class Queue ...@@ -184,6 +203,7 @@ abstract class Queue
'displayName' => is_string($job) ? explode('@', $job)[0] : null, 'displayName' => is_string($job) ? explode('@', $job)[0] : null,
'job' => $job, 'job' => $job,
'maxTries' => null, 'maxTries' => null,
'delay' => null,
'timeout' => null, 'timeout' => null,
'data' => $data, 'data' => $data,
]); ]);
......
...@@ -367,7 +367,11 @@ class Worker ...@@ -367,7 +367,11 @@ class Worker
// so it is not lost entirely. This'll let the job be retried at a later time by // so it is not lost entirely. This'll let the job be retried at a later time by
// another listener (or this same one). We will re-throw this exception after. // another listener (or this same one). We will re-throw this exception after.
if (! $job->isDeleted() && ! $job->isReleased() && ! $job->hasFailed()) { if (! $job->isDeleted() && ! $job->isReleased() && ! $job->hasFailed()) {
$job->release($options->delay); $job->release(
method_exists($job, 'delaySeconds') && ! is_null($job->delaySeconds())
? $job->delaySeconds()
: $options->delay
);
} }
} }
......
...@@ -327,11 +327,15 @@ class Str ...@@ -327,11 +327,15 @@ class Str
*/ */
public static function replaceArray($search, array $replace, $subject) public static function replaceArray($search, array $replace, $subject)
{ {
foreach ($replace as $value) { $segments = explode($search, $subject);
$subject = static::replaceFirst($search, $value, $subject);
$result = array_shift($segments);
foreach ($segments as $segment) {
$result .= (array_shift($replace) ?? $search).$segment;
} }
return $subject; return $result;
} }
/** /**
......
...@@ -173,11 +173,7 @@ class NotificationFake implements NotificationFactory, NotificationDispatcher ...@@ -173,11 +173,7 @@ class NotificationFake implements NotificationFactory, NotificationDispatcher
*/ */
protected function notificationsFor($notifiable, $notification) protected function notificationsFor($notifiable, $notification)
{ {
if (isset($this->notifications[get_class($notifiable)][$notifiable->getKey()][$notification])) { return $this->notifications[get_class($notifiable)][$notifiable->getKey()][$notification] ?? [];
return $this->notifications[get_class($notifiable)][$notifiable->getKey()][$notification];
}
return [];
} }
/** /**
......
...@@ -25,11 +25,7 @@ class ArrayLoader implements Loader ...@@ -25,11 +25,7 @@ class ArrayLoader implements Loader
{ {
$namespace = $namespace ?: '*'; $namespace = $namespace ?: '*';
if (isset($this->messages[$namespace][$locale][$group])) { return $this->messages[$namespace][$locale][$group] ?? [];
return $this->messages[$namespace][$locale][$group];
}
return [];
} }
/** /**
......
...@@ -131,11 +131,7 @@ class Translator extends NamespacedItemResolver implements TranslatorContract ...@@ -131,11 +131,7 @@ class Translator extends NamespacedItemResolver implements TranslatorContract
// If the line doesn't exist, we will return back the key which was requested as // If the line doesn't exist, we will return back the key which was requested as
// that will be quick to spot in the UI if language keys are wrong or missing // that will be quick to spot in the UI if language keys are wrong or missing
// from the application's language files. Otherwise we can return the line. // from the application's language files. Otherwise we can return the line.
if (isset($line)) { return $line ?? $key;
return $line;
}
return $key;
} }
/** /**
......
<!--
🛑 DON'T REMOVE ME.
This issue template apply to all
- bug reports,
- feature proposals,
- and documentation requests
Having all those informations will allow us to know exactly
what you expect and answer you faster and precisely (answer
that matches your Carbon version, PHP version and usage).
Note: Comments between <!- - and - -> won't appear in the final
issue (See [Preview] tab).
-->
Hello, Hello,
I encountered an issue with the following code: I encountered an issue with the following code:
```php ```php
echo Carbon::parse('2018-06-01')->subDay()->month; echo Carbon::parse('2018-06-01')->subDay()->month;
``` ```
Carbon version: **PUT HERE YOUR COMPOSER CARBON VERSION** Carbon version: **PUT HERE YOUR COMPOSER CARBON VERSION**
PHP version: **PUT HERE YOUR PHP VERSION** PHP version: **PUT HERE YOUR PHP VERSION**
<!-- <!--
Run the command `composer show nesbot/carbon` Run the command `composer show nesbot/carbon`
to get "versions" to get "versions"
Use `echo phpversion();` Use `echo phpversion();`
to get PHP version. to get PHP version.
Some issues can depends on your context, settings, Some issues can depends on your context, settings,
macros, timezone, language. So to be sure the code macros, timezone, language. So to be sure the code
you give is enough to reproduce your bug, try it you give is enough to reproduce your bug, try it
first in: first in:
https://try-carbon.herokuapp.com/?theme=xcode&export&embed https://try-carbon.herokuapp.com/?theme=xcode&export&embed
You can use the [Options] button to change the version You can use the [Options] button to change the version
then when you get the bug with this editor, you can use then when you get the bug with this editor, you can use
the [Export] button, copy the link of the opened tab, the [Export] button, copy the link of the opened tab,
then paste it in the issue. Then we can immediatly get then paste it in the issue. Then we can immediatly get
your issue. your issue.
--> -->
I expected to get: I expected to get:
``` ```
6 6
``` ```
<!-- <!--
Always give your expectations. Each use has their owns. Always give your expectations. Each use has their owns.
You may want daylight saving time to be taken into account, You may want daylight saving time to be taken into account,
someone else want it to be ignored. You may want timezone someone else want it to be ignored. You may want timezone
to be used in comparisons, someone else may not, etc. to be used in comparisons, someone else may not, etc.
--> -->
But I actually get: But I actually get:
``` ```
5 5
``` ```
<!-- <!--
If you did not succeed to get the same result in If you did not succeed to get the same result in
https://try-carbon.herokuapp.com/ then precise the https://try-carbon.herokuapp.com/ then precise the
result you get. result you get.
--> -->
Thanks! Thanks!
\ No newline at end of file
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* - JD Isaacks * - JD Isaacks
* - Jens Herlevsen * - Jens Herlevsen
* - Ulrik McArdle (mcardle) * - Ulrik McArdle (mcardle)
* - Frederik Sauer (FrittenKeeZ)
*/ */
return [ return [
'year' => ':count år|:count år', 'year' => ':count år|:count år',
...@@ -24,13 +25,13 @@ return [ ...@@ -24,13 +25,13 @@ return [
'y' => ':count år|:count år', 'y' => ':count år|:count år',
'month' => ':count måned|:count måneder', 'month' => ':count måned|:count måneder',
'a_month' => 'en måned|:count måneder', 'a_month' => 'en måned|:count måneder',
'm' => ':count mån.', 'm' => ':count mdr.',
'week' => ':count uge|:count uger', 'week' => ':count uge|:count uger',
'a_week' => 'en uge|:count uger', 'a_week' => 'en uge|:count uger',
'w' => ':count u.', 'w' => ':count u.',
'day' => ':count dag|:count dage', 'day' => ':count dag|:count dage',
'a_day' => ':count dag|:count dage', 'a_day' => ':count dag|:count dage',
'd' => 'en d.', 'd' => ':count d.',
'hour' => ':count time|:count timer', 'hour' => ':count time|:count timer',
'a_hour' => 'en time|:count timer', 'a_hour' => 'en time|:count timer',
'h' => ':count t.', 'h' => ':count t.',
......
...@@ -57,7 +57,7 @@ class Generic extends BaseTag implements Factory\StaticMethod ...@@ -57,7 +57,7 @@ class Generic extends BaseTag implements Factory\StaticMethod
Assert::stringNotEmpty($name); Assert::stringNotEmpty($name);
Assert::notNull($descriptionFactory); Assert::notNull($descriptionFactory);
$description = $descriptionFactory && $body ? $descriptionFactory->create($body, $context) : null; $description = $descriptionFactory && $body !== "" ? $descriptionFactory->create($body, $context) : null;
return new static($name, $description); return new static($name, $description);
} }
......
...@@ -4,7 +4,7 @@ php: ...@@ -4,7 +4,7 @@ php:
- 7.1 - 7.1
- 7.2 - 7.2
- 7.3 - 7.3
- master - 7.4snapshot
sudo: false sudo: false
......
...@@ -2,6 +2,16 @@ ...@@ -2,6 +2,16 @@
All notable changes in `sebastianbergmann/environment` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. All notable changes in `sebastianbergmann/environment` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [4.2.1] - 2019-04-25
* Fixed an issue in `Runtime::getCurrentSettings()`
## [4.2.0] - 2019-04-25
### Added
* Implemented [#36](https://github.com/sebastianbergmann/environment/pull/36): `Runtime::getCurrentSettings()`
## [4.1.0] - 2019-02-01 ## [4.1.0] - 2019-02-01
### Added ### Added
...@@ -75,6 +85,8 @@ All notable changes in `sebastianbergmann/environment` are documented in this fi ...@@ -75,6 +85,8 @@ All notable changes in `sebastianbergmann/environment` are documented in this fi
* This component is no longer supported on PHP 5.6 * This component is no longer supported on PHP 5.6
[4.2.1]: https://github.com/sebastianbergmann/phpunit/compare/4.2.0...4.2.1
[4.2.0]: https://github.com/sebastianbergmann/phpunit/compare/4.1.0...4.2.0
[4.1.0]: https://github.com/sebastianbergmann/phpunit/compare/4.0.2...4.1.0 [4.1.0]: https://github.com/sebastianbergmann/phpunit/compare/4.0.2...4.1.0
[4.0.2]: https://github.com/sebastianbergmann/phpunit/compare/4.0.1...4.0.2 [4.0.2]: https://github.com/sebastianbergmann/phpunit/compare/4.0.1...4.0.2
[4.0.1]: https://github.com/sebastianbergmann/phpunit/compare/66691f8e2dc4641909166b275a9a4f45c0e89092...4.0.1 [4.0.1]: https://github.com/sebastianbergmann/phpunit/compare/66691f8e2dc4641909166b275a9a4f45c0e89092...4.0.1
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "4.1-dev" "dev-master": "4.2-dev"
} }
} }
} }
...@@ -218,4 +218,50 @@ final class Runtime ...@@ -218,4 +218,50 @@ final class Runtime
{ {
return $this->isPHP() && \extension_loaded('pcov') && \ini_get('pcov.enabled'); return $this->isPHP() && \extension_loaded('pcov') && \ini_get('pcov.enabled');
} }
/**
* Parses the loaded php.ini file (if any) as well as all
* additional php.ini files from the additional ini dir for
* a list of all configuration settings loaded from files
* at startup. Then checks for each php.ini setting passed
* via the `$values` parameter whether this setting has
* been changed at runtime. Returns an array of strings
* where each string has the format `key=value` denoting
* the name of a changed php.ini setting with its new value.
*
* @return string[]
*/
public function getCurrentSettings(array $values): array
{
$diff = [];
$files = [];
if ($file = \php_ini_loaded_file()) {
$files[] = $file;
}
if ($scanned = \php_ini_scanned_files()) {
$files = \array_merge(
$files,
\array_map(
'trim',
\explode(",\n", $scanned)
)
);
}
foreach ($files as $ini) {
$config = \parse_ini_file($ini, true);
foreach ($values as $value) {
$set = \ini_get($value);
if (isset($config[$value]) && $set != $config[$value]) {
$diff[] = \sprintf('%s=%s', $value, $set);
}
}
}
return $diff;
}
} }
Changelog Changelog
========= =========
6.2.1 (2019-04-21)
------------------
* reverted "deprecated Swift_CharacterStream_ArrayCharacterStream and Swift_CharacterStream_NgCharacterStream in favor of Swift_CharacterStream_CharacterStream"
6.2.0 (2019-03-10) 6.2.0 (2019-03-10)
------------------ ------------------
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
*/ */
abstract class Swift abstract class Swift
{ {
const VERSION = '6.2.0'; const VERSION = '6.2.1';
public static $initialized = false; public static $initialized = false;
public static $inits = []; public static $inits = [];
......
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
@trigger_error(sprintf('The "%s" class is deprecated since Swiftmailer 6.2; use "%s" instead.', Swift_CharacterStream_ArrayCharacterStream::class, Swift_CharacterStream_CharacterStream::class), E_USER_DEPRECATED);
/** /**
* A CharacterStream implementation which stores characters in an internal array. * A CharacterStream implementation which stores characters in an internal array.
* *
......
<?php
/*
* This file is part of SwiftMailer.
* (c) 2004-2009 Chris Corbyn
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* A CharacterStream implementation which stores characters in an internal array.
*
* @author Xavier De Cock <xdecock@gmail.com>
*/
class Swift_CharacterStream_CharacterStream implements Swift_CharacterStream
{
/**
* The char reader (lazy-loaded) for the current charset.
*
* @var Swift_CharacterReader
*/
private $charReader;
/**
* A factory for creating CharacterReader instances.
*
* @var Swift_CharacterReaderFactory
*/
private $charReaderFactory;
/**
* The character set this stream is using.
*
* @var string
*/
private $charset;
/**
* The data's stored as-is.
*
* @var string
*/
private $datas = '';
/**
* Number of bytes in the stream.
*
* @var int
*/
private $datasSize = 0;
/**
* Map.
*
* @var mixed
*/
private $map;
/**
* Map Type.
*
* @var int
*/
private $mapType = 0;
/**
* Number of characters in the stream.
*
* @var int
*/
private $charCount = 0;
/**
* Position in the stream.
*
* @var int
*/
private $currentPos = 0;
/**
* Constructor.
*
* @param string $charset
*/
public function __construct(Swift_CharacterReaderFactory $factory, $charset)
{
$this->setCharacterReaderFactory($factory);
$this->setCharacterSet($charset);
}
/* -- Changing parameters of the stream -- */
/**
* Set the character set used in this CharacterStream.
*
* @param string $charset
*/
public function setCharacterSet($charset)
{
$this->charset = $charset;
$this->charReader = null;
$this->mapType = 0;
}
/**
* Set the CharacterReaderFactory for multi charset support.
*/
public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory)
{
$this->charReaderFactory = $factory;
}
public function flushContents()
{
$this->datas = null;
$this->map = null;
$this->charCount = 0;
$this->currentPos = 0;
$this->datasSize = 0;
}
public function importByteStream(Swift_OutputByteStream $os)
{
$this->flushContents();
$blocks = 512;
$os->setReadPointer(0);
while (false !== ($read = $os->read($blocks))) {
$this->write($read);
}
}
public function importString($string)
{
$this->flushContents();
$this->write($string);
}
public function read($length)
{
if ($this->currentPos >= $this->charCount) {
return false;
}
$ret = false;
$length = ($this->currentPos + $length > $this->charCount) ? $this->charCount - $this->currentPos : $length;
switch ($this->mapType) {
case Swift_CharacterReader::MAP_TYPE_FIXED_LEN:
$len = $length * $this->map;
$ret = substr($this->datas,
$this->currentPos * $this->map,
$len);
$this->currentPos += $length;
break;
case Swift_CharacterReader::MAP_TYPE_INVALID:
$ret = '';
for (; $this->currentPos < $length; ++$this->currentPos) {
if (isset($this->map[$this->currentPos])) {
$ret .= '?';
} else {
$ret .= $this->datas[$this->currentPos];
}
}
break;
case Swift_CharacterReader::MAP_TYPE_POSITIONS:
$end = $this->currentPos + $length;
$end = $end > $this->charCount ? $this->charCount : $end;
$ret = '';
$start = 0;
if ($this->currentPos > 0) {
$start = $this->map['p'][$this->currentPos - 1];
}
$to = $start;
for (; $this->currentPos < $end; ++$this->currentPos) {
if (isset($this->map['i'][$this->currentPos])) {
$ret .= substr($this->datas, $start, $to - $start).'?';
$start = $this->map['p'][$this->currentPos];
} else {
$to = $this->map['p'][$this->currentPos];
}
}
$ret .= substr($this->datas, $start, $to - $start);
break;
}
return $ret;
}
public function readBytes($length)
{
$read = $this->read($length);
if (false !== $read) {
$ret = array_map('ord', str_split($read, 1));
return $ret;
}
return false;
}
public function setPointer($charOffset)
{
if ($this->charCount < $charOffset) {
$charOffset = $this->charCount;
}
$this->currentPos = $charOffset;
}
public function write($chars)
{
if (!isset($this->charReader)) {
$this->charReader = $this->charReaderFactory->getReaderFor(
$this->charset);
$this->map = [];
$this->mapType = $this->charReader->getMapType();
}
$ignored = '';
$this->datas .= $chars;
$this->charCount += $this->charReader->getCharPositions(substr($this->datas, $this->datasSize), $this->datasSize, $this->map, $ignored);
if (false !== $ignored) {
$this->datasSize = strlen($this->datas) - strlen($ignored);
} else {
$this->datasSize = strlen($this->datas);
}
}
}
...@@ -8,13 +8,255 @@ ...@@ -8,13 +8,255 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
@trigger_error(sprintf('The "%s" class is deprecated since Swiftmailer 6.2; use "%s" instead.', Swift_CharacterStream_NgCharacterStream::class, Swift_CharacterStream_CharacterStream::class), E_USER_DEPRECATED);
/** /**
* A CharacterStream implementation which stores characters in an internal array. * A CharacterStream implementation which stores characters in an internal array.
* *
* @author Xavier De Cock <xdecock@gmail.com> * @author Xavier De Cock <xdecock@gmail.com>
*/ */
class Swift_CharacterStream_NgCharacterStream extends Swift_CharacterStream_CharacterStream class Swift_CharacterStream_NgCharacterStream implements Swift_CharacterStream
{ {
/**
* The char reader (lazy-loaded) for the current charset.
*
* @var Swift_CharacterReader
*/
private $charReader;
/**
* A factory for creating CharacterReader instances.
*
* @var Swift_CharacterReaderFactory
*/
private $charReaderFactory;
/**
* The character set this stream is using.
*
* @var string
*/
private $charset;
/**
* The data's stored as-is.
*
* @var string
*/
private $datas = '';
/**
* Number of bytes in the stream.
*
* @var int
*/
private $datasSize = 0;
/**
* Map.
*
* @var mixed
*/
private $map;
/**
* Map Type.
*
* @var int
*/
private $mapType = 0;
/**
* Number of characters in the stream.
*
* @var int
*/
private $charCount = 0;
/**
* Position in the stream.
*
* @var int
*/
private $currentPos = 0;
/**
* Constructor.
*
* @param string $charset
*/
public function __construct(Swift_CharacterReaderFactory $factory, $charset)
{
$this->setCharacterReaderFactory($factory);
$this->setCharacterSet($charset);
}
/* -- Changing parameters of the stream -- */
/**
* Set the character set used in this CharacterStream.
*
* @param string $charset
*/
public function setCharacterSet($charset)
{
$this->charset = $charset;
$this->charReader = null;
$this->mapType = 0;
}
/**
* Set the CharacterReaderFactory for multi charset support.
*/
public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory)
{
$this->charReaderFactory = $factory;
}
/**
* @see Swift_CharacterStream::flushContents()
*/
public function flushContents()
{
$this->datas = null;
$this->map = null;
$this->charCount = 0;
$this->currentPos = 0;
$this->datasSize = 0;
}
/**
* @see Swift_CharacterStream::importByteStream()
*/
public function importByteStream(Swift_OutputByteStream $os)
{
$this->flushContents();
$blocks = 512;
$os->setReadPointer(0);
while (false !== ($read = $os->read($blocks))) {
$this->write($read);
}
}
/**
* @see Swift_CharacterStream::importString()
*
* @param string $string
*/
public function importString($string)
{
$this->flushContents();
$this->write($string);
}
/**
* @see Swift_CharacterStream::read()
*
* @param int $length
*
* @return string
*/
public function read($length)
{
if ($this->currentPos >= $this->charCount) {
return false;
}
$ret = false;
$length = ($this->currentPos + $length > $this->charCount) ? $this->charCount - $this->currentPos : $length;
switch ($this->mapType) {
case Swift_CharacterReader::MAP_TYPE_FIXED_LEN:
$len = $length * $this->map;
$ret = substr($this->datas,
$this->currentPos * $this->map,
$len);
$this->currentPos += $length;
break;
case Swift_CharacterReader::MAP_TYPE_INVALID:
$ret = '';
for (; $this->currentPos < $length; ++$this->currentPos) {
if (isset($this->map[$this->currentPos])) {
$ret .= '?';
} else {
$ret .= $this->datas[$this->currentPos];
}
}
break;
case Swift_CharacterReader::MAP_TYPE_POSITIONS:
$end = $this->currentPos + $length;
$end = $end > $this->charCount ? $this->charCount : $end;
$ret = '';
$start = 0;
if ($this->currentPos > 0) {
$start = $this->map['p'][$this->currentPos - 1];
}
$to = $start;
for (; $this->currentPos < $end; ++$this->currentPos) {
if (isset($this->map['i'][$this->currentPos])) {
$ret .= substr($this->datas, $start, $to - $start).'?';
$start = $this->map['p'][$this->currentPos];
} else {
$to = $this->map['p'][$this->currentPos];
}
}
$ret .= substr($this->datas, $start, $to - $start);
break;
}
return $ret;
}
/**
* @see Swift_CharacterStream::readBytes()
*
* @param int $length
*
* @return int[]
*/
public function readBytes($length)
{
$read = $this->read($length);
if (false !== $read) {
$ret = array_map('ord', str_split($read, 1));
return $ret;
}
return false;
}
/**
* @see Swift_CharacterStream::setPointer()
*
* @param int $charOffset
*/
public function setPointer($charOffset)
{
if ($this->charCount < $charOffset) {
$charOffset = $this->charCount;
}
$this->currentPos = $charOffset;
}
/**
* @see Swift_CharacterStream::write()
*
* @param string $chars
*/
public function write($chars)
{
if (!isset($this->charReader)) {
$this->charReader = $this->charReaderFactory->getReaderFor(
$this->charset);
$this->map = [];
$this->mapType = $this->charReader->getMapType();
}
$ignored = '';
$this->datas .= $chars;
$this->charCount += $this->charReader->getCharPositions(substr($this->datas, $this->datasSize), $this->datasSize, $this->map, $ignored);
if (false !== $ignored) {
$this->datasSize = strlen($this->datas) - strlen($ignored);
} else {
$this->datasSize = strlen($this->datas);
}
}
} }
...@@ -84,7 +84,7 @@ Swift_DependencyContainer::getInstance() ...@@ -84,7 +84,7 @@ Swift_DependencyContainer::getInstance()
->withDependencies(['mime.charstream']) ->withDependencies(['mime.charstream'])
->register('mime.charstream') ->register('mime.charstream')
->asNewInstanceOf('Swift_CharacterStream_CharacterStream') ->asNewInstanceOf('Swift_CharacterStream_NgCharacterStream')
->withDependencies(['mime.characterreaderfactory', 'properties.charset']) ->withDependencies(['mime.characterreaderfactory', 'properties.charset'])
->register('mime.bytecanonicalizer') ->register('mime.bytecanonicalizer')
......
...@@ -20,7 +20,7 @@ class Swift_Encoder_QpEncoderAcceptanceTest extends \PHPUnit\Framework\TestCase ...@@ -20,7 +20,7 @@ class Swift_Encoder_QpEncoderAcceptanceTest extends \PHPUnit\Framework\TestCase
} }
$encoding = $encodingDir; $encoding = $encodingDir;
$charStream = new Swift_CharacterStream_CharacterStream( $charStream = new Swift_CharacterStream_ArrayCharacterStream(
$this->factory, $encoding); $this->factory, $encoding);
$encoder = new Swift_Encoder_QpEncoder($charStream); $encoder = new Swift_Encoder_QpEncoder($charStream);
......
...@@ -20,7 +20,7 @@ class Swift_Encoder_Rfc2231EncoderAcceptanceTest extends \PHPUnit\Framework\Test ...@@ -20,7 +20,7 @@ class Swift_Encoder_Rfc2231EncoderAcceptanceTest extends \PHPUnit\Framework\Test
} }
$encoding = $encodingDir; $encoding = $encodingDir;
$charStream = new Swift_CharacterStream_CharacterStream( $charStream = new Swift_CharacterStream_ArrayCharacterStream(
$this->factory, $encoding); $this->factory, $encoding);
$encoder = new Swift_Encoder_Rfc2231Encoder($charStream); $encoder = new Swift_Encoder_Rfc2231Encoder($charStream);
......
...@@ -18,10 +18,10 @@ class Swift_Mime_AttachmentAcceptanceTest extends \PHPUnit\Framework\TestCase ...@@ -18,10 +18,10 @@ class Swift_Mime_AttachmentAcceptanceTest extends \PHPUnit\Framework\TestCase
$this->contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder(); $this->contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder();
$headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder( $headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8') new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
); );
$paramEncoder = new Swift_Encoder_Rfc2231Encoder( $paramEncoder = new Swift_Encoder_Rfc2231Encoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8') new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
); );
$this->emailValidator = new EmailValidator(); $this->emailValidator = new EmailValidator();
$this->idGenerator = new Swift_Mime_IdGenerator('example.com'); $this->idGenerator = new Swift_Mime_IdGenerator('example.com');
......
...@@ -25,7 +25,7 @@ class Swift_Mime_ContentEncoder_QpContentEncoderAcceptanceTest extends \PHPUnit\ ...@@ -25,7 +25,7 @@ class Swift_Mime_ContentEncoder_QpContentEncoderAcceptanceTest extends \PHPUnit\
} }
$encoding = $encodingDir; $encoding = $encodingDir;
$charStream = new Swift_CharacterStream_CharacterStream( $charStream = new Swift_CharacterStream_NgCharacterStream(
$this->factory, $encoding); $this->factory, $encoding);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream); $encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
......
...@@ -18,10 +18,10 @@ class Swift_Mime_EmbeddedFileAcceptanceTest extends \PHPUnit\Framework\TestCase ...@@ -18,10 +18,10 @@ class Swift_Mime_EmbeddedFileAcceptanceTest extends \PHPUnit\Framework\TestCase
$this->contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder(); $this->contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder();
$headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder( $headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8') new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
); );
$paramEncoder = new Swift_Encoder_Rfc2231Encoder( $paramEncoder = new Swift_Encoder_Rfc2231Encoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8') new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
); );
$this->emailValidator = new EmailValidator(); $this->emailValidator = new EmailValidator();
$this->idGenerator = new Swift_Mime_IdGenerator('example.com'); $this->idGenerator = new Swift_Mime_IdGenerator('example.com');
......
...@@ -16,7 +16,7 @@ class Swift_Mime_MimePartAcceptanceTest extends \PHPUnit\Framework\TestCase ...@@ -16,7 +16,7 @@ class Swift_Mime_MimePartAcceptanceTest extends \PHPUnit\Framework\TestCase
); );
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory(); $factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$this->contentEncoder = new Swift_Mime_ContentEncoder_QpContentEncoder( $this->contentEncoder = new Swift_Mime_ContentEncoder_QpContentEncoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8'), new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8'),
new Swift_StreamFilters_ByteArrayReplacementFilter( new Swift_StreamFilters_ByteArrayReplacementFilter(
[[0x0D, 0x0A], [0x0D], [0x0A]], [[0x0D, 0x0A], [0x0D], [0x0A]],
[[0x0A], [0x0A], [0x0D, 0x0A]] [[0x0A], [0x0A], [0x0D, 0x0A]]
...@@ -24,10 +24,10 @@ class Swift_Mime_MimePartAcceptanceTest extends \PHPUnit\Framework\TestCase ...@@ -24,10 +24,10 @@ class Swift_Mime_MimePartAcceptanceTest extends \PHPUnit\Framework\TestCase
); );
$headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder( $headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8') new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
); );
$paramEncoder = new Swift_Encoder_Rfc2231Encoder( $paramEncoder = new Swift_Encoder_Rfc2231Encoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8') new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
); );
$this->emailValidator = new EmailValidator(); $this->emailValidator = new EmailValidator();
$this->idGenerator = new Swift_Mime_IdGenerator('example.com'); $this->idGenerator = new Swift_Mime_IdGenerator('example.com');
......
...@@ -10,10 +10,10 @@ class Swift_Bug206Test extends \PHPUnit\Framework\TestCase ...@@ -10,10 +10,10 @@ class Swift_Bug206Test extends \PHPUnit\Framework\TestCase
{ {
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory(); $factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder( $headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8') new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
); );
$paramEncoder = new Swift_Encoder_Rfc2231Encoder( $paramEncoder = new Swift_Encoder_Rfc2231Encoder(
new Swift_CharacterStream_CharacterStream($factory, 'utf-8') new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8')
); );
$emailValidator = new EmailValidator(); $emailValidator = new EmailValidator();
$this->factory = new Swift_Mime_SimpleHeaderFactory($headerEncoder, $paramEncoder, $emailValidator); $this->factory = new Swift_Mime_SimpleHeaderFactory($headerEncoder, $paramEncoder, $emailValidator);
......
...@@ -13,7 +13,7 @@ class Swift_Bug650Test extends \PHPUnit\Framework\TestCase ...@@ -13,7 +13,7 @@ class Swift_Bug650Test extends \PHPUnit\Framework\TestCase
public function testMailboxHeaderEncoding($name, $expectedEncodedName) public function testMailboxHeaderEncoding($name, $expectedEncodedName)
{ {
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory(); $factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$charStream = new Swift_CharacterStream_CharacterStream($factory, 'utf-8'); $charStream = new Swift_CharacterStream_NgCharacterStream($factory, 'utf-8');
$encoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder($charStream); $encoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder($charStream);
$header = new Swift_Mime_Headers_MailboxHeader('To', $encoder, new EmailValidator()); $header = new Swift_Mime_Headers_MailboxHeader('To', $encoder, new EmailValidator());
$header->setCharset('utf-8'); $header->setCharset('utf-8');
......
<?php <?php
/**
* @group legacy
*/
class Swift_CharacterStream_ArrayCharacterStreamTest extends \SwiftMailerTestCase class Swift_CharacterStream_ArrayCharacterStreamTest extends \SwiftMailerTestCase
{ {
public function testValidatorAlgorithmOnImportString() public function testValidatorAlgorithmOnImportString()
......
...@@ -393,7 +393,7 @@ class Swift_Encoder_QpEncoderTest extends \SwiftMailerTestCase ...@@ -393,7 +393,7 @@ class Swift_Encoder_QpEncoderTest extends \SwiftMailerTestCase
private function createEncoder() private function createEncoder()
{ {
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory(); $factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$charStream = new Swift_CharacterStream_CharacterStream($factory, 'utf-8'); $charStream = new Swift_CharacterStream_NgCharacterStream($factory, 'utf-8');
return new Swift_Encoder_QpEncoder($charStream); return new Swift_Encoder_QpEncoder($charStream);
} }
......
...@@ -499,7 +499,7 @@ class Swift_Mime_ContentEncoder_QpContentEncoderTest extends \SwiftMailerTestCas ...@@ -499,7 +499,7 @@ class Swift_Mime_ContentEncoder_QpContentEncoderTest extends \SwiftMailerTestCas
private function createEncoder() private function createEncoder()
{ {
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory(); $factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$charStream = new Swift_CharacterStream_CharacterStream($factory, 'utf-8'); $charStream = new Swift_CharacterStream_NgCharacterStream($factory, 'utf-8');
return new Swift_Mime_ContentEncoder_QpContentEncoder($charStream); return new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
} }
......
...@@ -147,8 +147,8 @@ class Swift_Signers_DKIMSignerTest extends \SwiftMailerTestCase ...@@ -147,8 +147,8 @@ class Swift_Signers_DKIMSignerTest extends \SwiftMailerTestCase
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory(); $factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder(); $contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder();
$headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(new Swift_CharacterStream_CharacterStream($factory, 'utf-8')); $headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8'));
$paramEncoder = new Swift_Encoder_Rfc2231Encoder(new Swift_CharacterStream_CharacterStream($factory, 'utf-8')); $paramEncoder = new Swift_Encoder_Rfc2231Encoder(new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8'));
$emailValidator = new EmailValidator(); $emailValidator = new EmailValidator();
$headers = new Swift_Mime_SimpleHeaderSet(new Swift_Mime_SimpleHeaderFactory($headerEncoder, $paramEncoder, $emailValidator)); $headers = new Swift_Mime_SimpleHeaderSet(new Swift_Mime_SimpleHeaderFactory($headerEncoder, $paramEncoder, $emailValidator));
...@@ -165,8 +165,8 @@ class Swift_Signers_DKIMSignerTest extends \SwiftMailerTestCase ...@@ -165,8 +165,8 @@ class Swift_Signers_DKIMSignerTest extends \SwiftMailerTestCase
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory(); $factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder(); $contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder();
$headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(new Swift_CharacterStream_CharacterStream($factory, 'utf-8')); $headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8'));
$paramEncoder = new Swift_Encoder_Rfc2231Encoder(new Swift_CharacterStream_CharacterStream($factory, 'utf-8')); $paramEncoder = new Swift_Encoder_Rfc2231Encoder(new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8'));
$emailValidator = new EmailValidator(); $emailValidator = new EmailValidator();
$headerFactory = new Swift_Mime_SimpleHeaderFactory($headerEncoder, $paramEncoder, $emailValidator); $headerFactory = new Swift_Mime_SimpleHeaderFactory($headerEncoder, $paramEncoder, $emailValidator);
$headers = $this->getMockery('Swift_Mime_SimpleHeaderSet'); $headers = $this->getMockery('Swift_Mime_SimpleHeaderSet');
......
...@@ -193,9 +193,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable ...@@ -193,9 +193,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
*/ */
public function save() public function save()
{ {
if ($this->isStarted()) { $this->storage->save();
$this->storage->save();
}
} }
/** /**
......
...@@ -1004,14 +1004,15 @@ class ResponseTest extends ResponseTestCase ...@@ -1004,14 +1004,15 @@ class ResponseTest extends ResponseTestCase
$ianaHttpStatusCodes = new \DOMDocument(); $ianaHttpStatusCodes = new \DOMDocument();
libxml_set_streams_context(stream_context_create([ $context = stream_context_create([
'http' => [ 'http' => [
'method' => 'GET', 'method' => 'GET',
'timeout' => 30, 'timeout' => 30,
'user_agent' => __METHOD__,
], ],
])); ]);
$ianaHttpStatusCodes->load('https://www.iana.org/assignments/http-status-codes/http-status-codes.xml'); $ianaHttpStatusCodes->loadXML(file_get_contents('https://www.iana.org/assignments/http-status-codes/http-status-codes.xml', false, $context));
if (!$ianaHttpStatusCodes->relaxNGValidate(__DIR__.'/schema/http-status-codes.rng')) { if (!$ianaHttpStatusCodes->relaxNGValidate(__DIR__.'/schema/http-status-codes.rng')) {
self::fail('Invalid IANA\'s HTTP status code list.'); self::fail('Invalid IANA\'s HTTP status code list.');
} }
......
...@@ -260,14 +260,4 @@ class SessionTest extends TestCase ...@@ -260,14 +260,4 @@ class SessionTest extends TestCase
$flash->get('hello'); $flash->get('hello');
$this->assertTrue($this->session->isEmpty()); $this->assertTrue($this->session->isEmpty());
} }
public function testSaveIfNotStarted()
{
$storage = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface')->getMock();
$session = new Session($storage);
$storage->expects($this->once())->method('isStarted')->willReturn(false);
$storage->expects($this->never())->method('save');
$session->save();
}
} }
...@@ -73,11 +73,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl ...@@ -73,11 +73,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
private $requestStackSize = 0; private $requestStackSize = 0;
private $resetServices = false; private $resetServices = false;
const VERSION = '4.2.7'; const VERSION = '4.2.8';
const VERSION_ID = 40207; const VERSION_ID = 40208;
const MAJOR_VERSION = 4; const MAJOR_VERSION = 4;
const MINOR_VERSION = 2; const MINOR_VERSION = 2;
const RELEASE_VERSION = 7; const RELEASE_VERSION = 8;
const EXTRA_VERSION = ''; const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '07/2019'; const END_OF_MAINTENANCE = '07/2019';
......
...@@ -210,7 +210,7 @@ EOF; ...@@ -210,7 +210,7 @@ EOF;
foreach ($staticRoutes as $url => $routes) { foreach ($staticRoutes as $url => $routes) {
$code .= self::export($url)." => [\n"; $code .= self::export($url)." => [\n";
foreach ($routes as $name => list($route, $hasTrailingSlash)) { foreach ($routes as $name => list($route, $hasTrailingSlash)) {
$code .= $this->compileRoute($route, $name, !$route->compile()->getHostVariables() ? $route->getHost() : $route->compile()->getHostRegex() ?: null, $hasTrailingSlash, false, $conditions); $code .= $this->compileRoute($route, $name, (!$route->compile()->getHostVariables() ? $route->getHost() : $route->compile()->getHostRegex()) ?: null, $hasTrailingSlash, false, $conditions);
} }
$code .= "],\n"; $code .= "],\n";
} }
......
...@@ -15,11 +15,14 @@ use Symfony\Component\Routing\Exception\MethodNotAllowedException; ...@@ -15,11 +15,14 @@ use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\NoConfigurationException; use Symfony\Component\Routing\Exception\NoConfigurationException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface; use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
use Symfony\Component\Routing\RequestContext;
/** /**
* @author Nicolas Grekas <p@tchwork.com> * @author Nicolas Grekas <p@tchwork.com>
* *
* @internal * @internal
*
* @property RequestContext $context
*/ */
trait PhpMatcherTrait trait PhpMatcherTrait
{ {
...@@ -89,13 +92,6 @@ trait PhpMatcherTrait ...@@ -89,13 +92,6 @@ trait PhpMatcherTrait
continue; continue;
} }
if ('/' !== $pathinfo && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {
if ($supportsRedirections && (!$requiredMethods || isset($requiredMethods['GET']))) {
return $allow = $allowSchemes = [];
}
continue;
}
if ($requiredHost) { if ($requiredHost) {
if ('#' !== $requiredHost[0] ? $requiredHost !== $host : !preg_match($requiredHost, $host, $hostMatches)) { if ('#' !== $requiredHost[0] ? $requiredHost !== $host : !preg_match($requiredHost, $host, $hostMatches)) {
continue; continue;
...@@ -106,6 +102,13 @@ trait PhpMatcherTrait ...@@ -106,6 +102,13 @@ trait PhpMatcherTrait
} }
} }
if ('/' !== $pathinfo && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {
if ($supportsRedirections && (!$requiredMethods || isset($requiredMethods['GET']))) {
return $allow = $allowSchemes = [];
}
continue;
}
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]); $hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) { if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
if ($hasRequiredScheme) { if ($hasRequiredScheme) {
...@@ -113,6 +116,7 @@ trait PhpMatcherTrait ...@@ -113,6 +116,7 @@ trait PhpMatcherTrait
} }
continue; continue;
} }
if (!$hasRequiredScheme) { if (!$hasRequiredScheme) {
$allowSchemes += $requiredSchemes; $allowSchemes += $requiredSchemes;
continue; continue;
...@@ -132,7 +136,7 @@ trait PhpMatcherTrait ...@@ -132,7 +136,7 @@ trait PhpMatcherTrait
$hasTrailingVar = $trimmedPathinfo !== $pathinfo && $hasTrailingVar; $hasTrailingVar = $trimmedPathinfo !== $pathinfo && $hasTrailingVar;
if ($hasTrailingVar && ($hasTrailingSlash || '/' !== substr($matches[\count($vars)], -1)) && preg_match($regex, $this->matchHost ? $host.'.'.$trimmedPathinfo : $trimmedPathinfo, $n) && $m === (int) $n['MARK']) { if ($hasTrailingVar && ($hasTrailingSlash || (null === $n = $matches[\count($vars)] ?? null) || '/' !== ($n[-1] ?? '/')) && preg_match($regex, $this->matchHost ? $host.'.'.$trimmedPathinfo : $trimmedPathinfo, $n) && $m === (int) $n['MARK']) {
if ($hasTrailingSlash) { if ($hasTrailingSlash) {
$matches = $n; $matches = $n;
} else { } else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment