Commit b7db6c72 by Florian Shllaku

the connection to Central European Bank API is done and the data is stored in table currency

parent dc5a98ff
Showing with 1101 additions and 244 deletions
<?php
use Illuminate\Database\Seeder;
class CurrencyUpdates extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
///This is a PHP(4/5) script example on how eurofxref-daily.xml can be parsed
//Read eurofxref-daily.xml file in memory
//For this command you will need the config
//option allow_url_fopen=On (default)
$XMLContent=file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
//the file is updated at around 16:00 CET
$i = 0;
foreach($XMLContent as $line){
if(preg_match("/currency='([[:alpha:]]+)'/",$line,$currencyCode)){
if(preg_match("/rate='([[:graph:]]+)'/",$line,$rate)){
//Output the value of 1EUR for a currency code
echo'1&euro;='.$rate[1].' '.$currencyCode[1].'<br/>';
$list = array("US dollar", "Japanese yen", "Bulgarian lev", "Czech koruna", "Danish krone", "Pound sterling","Hungarian forint", "Polish zloty", "Romanian leu", "Swedish krona", "Swiss franc", "Icelandic krona", "Norwegian krone", "Croatian kuna", "Russian rouble", "Turkish lira", "Australian dollar", "Brazilian real", "US dollar", "Canadian dollar", "Chinese yuan renminbi", "Hong Kong dollar", "Indonesian rupiah", "Israeli shekel", "Indian rupee", "South Korean won", "Mexican peso", "Malaysian ringgit", "New Zealand dollar", "Philippine peso", "Singapore dollar", "Thai baht", "South African rand");
//--------------------------------------------------
//Here you can add your code for inserting
//$rate[1] and $currencyCode[1] into your database
DB::table('currency')
->updateOrInsert(
['iso' => $currencyCode[1], 'name' => $list[$i]],
['rates' => $rate[1]]
);
++$i;
//--------------------------------------------------
}
}
}
}
}
......@@ -11,6 +11,9 @@ class DatabaseSeeder extends Seeder
*/
public function run()
{
// $this->call(UsersTableSeeder::class);
$this->call(CurrencyUpdates::class);
}
}
......@@ -279,7 +279,7 @@ class ClassLoader
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
......@@ -377,7 +377,7 @@ class ClassLoader
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
......
Format: http://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
Files: *
Copyright: 2016, Nils Adermann <naderman@naderman.de>
2016, Jordi Boggiano <j.boggiano@seld.be>
License: Expat
Copyright (c) Nils Adermann, Jordi Boggiano
Files: src/Composer/Util/TlsHelper.php
Copyright: 2016, Nils Adermann <naderman@naderman.de>
2016, Jordi Boggiano <j.boggiano@seld.be>
2013, Evan Coury <me@evancoury.com>
License: Expat and BSD-2-Clause
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:
License: BSD-2-Clause
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
.
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
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.
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.
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.
......@@ -15,6 +15,8 @@ return array(
'App\\Http\\Controllers\\Auth\\ResetPasswordController' => $baseDir . '/app/Http/Controllers/Auth/ResetPasswordController.php',
'App\\Http\\Controllers\\Auth\\VerificationController' => $baseDir . '/app/Http/Controllers/Auth/VerificationController.php',
'App\\Http\\Controllers\\Controller' => $baseDir . '/app/Http/Controllers/Controller.php',
'App\\Http\\Controllers\\HomeController' => $baseDir . '/app/Http/Controllers/HomeController.php',
'App\\Http\\Controllers\\NewsLetterController' => $baseDir . '/app/Http/Controllers/NewsLetterController.php',
'App\\Http\\Controllers\\SendEmailController' => $baseDir . '/app/Http/Controllers/SendEmailController.php',
'App\\Http\\Kernel' => $baseDir . '/app/Http/Kernel.php',
'App\\Http\\Middleware\\Authenticate' => $baseDir . '/app/Http/Middleware/Authenticate.php',
......@@ -73,6 +75,7 @@ return array(
'Cron\\HoursField' => $vendorDir . '/dragonmantank/cron-expression/src/Cron/HoursField.php',
'Cron\\MinutesField' => $vendorDir . '/dragonmantank/cron-expression/src/Cron/MinutesField.php',
'Cron\\MonthField' => $vendorDir . '/dragonmantank/cron-expression/src/Cron/MonthField.php',
'CurrencyUpdates' => $baseDir . '/database/seeds/CurrencyUpdates.php',
'DatabaseSeeder' => $baseDir . '/database/seeds/DatabaseSeeder.php',
'DeepCopy\\DeepCopy' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/DeepCopy.php',
'DeepCopy\\Exception\\CloneException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php',
......@@ -1041,6 +1044,7 @@ return array(
'Illuminate\\Database\\Schema\\PostgresBuilder' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/PostgresBuilder.php',
'Illuminate\\Database\\Schema\\SQLiteBuilder' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/SQLiteBuilder.php',
'Illuminate\\Database\\Schema\\SqlServerBuilder' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/SqlServerBuilder.php',
'Illuminate\\Database\\Schema\\Types\\TinyInteger' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/Types/TinyInteger.php',
'Illuminate\\Database\\Seeder' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Seeder.php',
'Illuminate\\Database\\SqlServerConnection' => $vendorDir . '/laravel/framework/src/Illuminate/Database/SqlServerConnection.php',
'Illuminate\\Encryption\\Encrypter' => $vendorDir . '/laravel/framework/src/Illuminate/Encryption/Encrypter.php',
......@@ -1497,6 +1501,7 @@ return array(
'Illuminate\\View\\Compilers\\Concerns\\CompilesComponents' => $vendorDir . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesConditionals' => $vendorDir . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesConditionals.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesEchos' => $vendorDir . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesEchos.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesErrors' => $vendorDir . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesErrors.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesHelpers' => $vendorDir . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesHelpers.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesIncludes' => $vendorDir . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesIncludes.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesInjections' => $vendorDir . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesInjections.php',
......
......@@ -8,8 +8,8 @@ $baseDir = dirname($vendorDir);
return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
......
......@@ -9,8 +9,8 @@ class ComposerStaticInitaaf7a2d0aa0540e4f74d52dc30d67caa
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
'2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
......@@ -379,6 +379,8 @@ class ComposerStaticInitaaf7a2d0aa0540e4f74d52dc30d67caa
'App\\Http\\Controllers\\Auth\\ResetPasswordController' => __DIR__ . '/../..' . '/app/Http/Controllers/Auth/ResetPasswordController.php',
'App\\Http\\Controllers\\Auth\\VerificationController' => __DIR__ . '/../..' . '/app/Http/Controllers/Auth/VerificationController.php',
'App\\Http\\Controllers\\Controller' => __DIR__ . '/../..' . '/app/Http/Controllers/Controller.php',
'App\\Http\\Controllers\\HomeController' => __DIR__ . '/../..' . '/app/Http/Controllers/HomeController.php',
'App\\Http\\Controllers\\NewsLetterController' => __DIR__ . '/../..' . '/app/Http/Controllers/NewsLetterController.php',
'App\\Http\\Controllers\\SendEmailController' => __DIR__ . '/../..' . '/app/Http/Controllers/SendEmailController.php',
'App\\Http\\Kernel' => __DIR__ . '/../..' . '/app/Http/Kernel.php',
'App\\Http\\Middleware\\Authenticate' => __DIR__ . '/../..' . '/app/Http/Middleware/Authenticate.php',
......@@ -437,6 +439,7 @@ class ComposerStaticInitaaf7a2d0aa0540e4f74d52dc30d67caa
'Cron\\HoursField' => __DIR__ . '/..' . '/dragonmantank/cron-expression/src/Cron/HoursField.php',
'Cron\\MinutesField' => __DIR__ . '/..' . '/dragonmantank/cron-expression/src/Cron/MinutesField.php',
'Cron\\MonthField' => __DIR__ . '/..' . '/dragonmantank/cron-expression/src/Cron/MonthField.php',
'CurrencyUpdates' => __DIR__ . '/../..' . '/database/seeds/CurrencyUpdates.php',
'DatabaseSeeder' => __DIR__ . '/../..' . '/database/seeds/DatabaseSeeder.php',
'DeepCopy\\DeepCopy' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/DeepCopy.php',
'DeepCopy\\Exception\\CloneException' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php',
......@@ -1405,6 +1408,7 @@ class ComposerStaticInitaaf7a2d0aa0540e4f74d52dc30d67caa
'Illuminate\\Database\\Schema\\PostgresBuilder' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Schema/PostgresBuilder.php',
'Illuminate\\Database\\Schema\\SQLiteBuilder' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Schema/SQLiteBuilder.php',
'Illuminate\\Database\\Schema\\SqlServerBuilder' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Schema/SqlServerBuilder.php',
'Illuminate\\Database\\Schema\\Types\\TinyInteger' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Schema/Types/TinyInteger.php',
'Illuminate\\Database\\Seeder' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Seeder.php',
'Illuminate\\Database\\SqlServerConnection' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/SqlServerConnection.php',
'Illuminate\\Encryption\\Encrypter' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Encryption/Encrypter.php',
......@@ -1861,6 +1865,7 @@ class ComposerStaticInitaaf7a2d0aa0540e4f74d52dc30d67caa
'Illuminate\\View\\Compilers\\Concerns\\CompilesComponents' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesConditionals' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesConditionals.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesEchos' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesEchos.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesErrors' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesErrors.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesHelpers' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesHelpers.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesIncludes' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesIncludes.php',
'Illuminate\\View\\Compilers\\Concerns\\CompilesInjections' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesInjections.php',
......
......@@ -17,12 +17,10 @@ class AuthServiceProvider extends ServiceProvider
public function register()
{
$this->registerAuthenticator();
$this->registerUserResolver();
$this->registerAccessGate();
$this->registerRequestRebindHandler();
$this->registerEventRebindHandler();
}
/**
......@@ -75,7 +73,7 @@ class AuthServiceProvider extends ServiceProvider
}
/**
* Register a resolver for the authenticated user.
* Handle the re-binding of the request binding.
*
* @return void
*/
......@@ -87,4 +85,22 @@ class AuthServiceProvider extends ServiceProvider
});
});
}
/**
* Handle the re-binding of the event dispatcher binding.
*
* @return void
*/
protected function registerEventRebindHandler()
{
$this->app->rebinding('events', function ($app, $dispatcher) {
if (! $app->resolved('auth')) {
return;
}
if (method_exists($guard = $app['auth']->guard(), 'setDispatcher')) {
$guard->setDispatcher($dispatcher);
}
});
}
}
......@@ -15,7 +15,7 @@
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autofocus>
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
......@@ -29,7 +29,7 @@
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required autocomplete="current-password">
@if ($errors->has('password'))
<span class="invalid-feedback" role="alert">
......
......@@ -21,7 +21,7 @@
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required>
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
......
......@@ -17,7 +17,7 @@
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ $email ?? old('email') }}" required autofocus>
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus>
@if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
......@@ -31,7 +31,7 @@
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required autocomplete="new-password">
@if ($errors->has('password'))
<span class="invalid-feedback" role="alert">
......@@ -45,7 +45,7 @@
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>
......
......@@ -15,7 +15,7 @@
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name') }}" required autofocus>
<input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@if ($errors->has('name'))
<span class="invalid-feedback" role="alert">
......@@ -29,7 +29,7 @@
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required>
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autocomplete="email">
@if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
......@@ -43,7 +43,7 @@
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required autocomplete="new-password">
@if ($errors->has('password'))
<span class="invalid-feedback" role="alert">
......@@ -57,7 +57,7 @@
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>
......
......@@ -8,9 +8,10 @@ use Illuminate\Support\Carbon;
use Aws\DynamoDb\DynamoDbClient;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Support\InteractsWithTime;
use Illuminate\Contracts\Cache\LockProvider;
use Aws\DynamoDb\Exception\DynamoDbException;
class DynamoDbStore implements Store
class DynamoDbStore implements Store, LockProvider
{
use InteractsWithTime;
......
......@@ -144,6 +144,13 @@ class Event
public $mutex;
/**
* The exit status code of the command.
*
* @var int|null
*/
public $exitCode;
/**
* Create a new event instance.
*
* @param \Illuminate\Console\Scheduling\EventMutex $mutex
......@@ -208,7 +215,7 @@ class Event
{
$this->callBeforeCallbacks($container);
Process::fromShellCommandline($this->buildCommand(), base_path(), null, null, null)->run();
$this->exitCode = Process::fromShellCommandline($this->buildCommand(), base_path(), null, null, null)->run();
$this->callAfterCallbacks($container);
}
......@@ -411,6 +418,23 @@ class Event
}
/**
* E-mail the results of the scheduled operation if it fails.
*
* @param array|mixed $addresses
* @return $this
*/
public function emailOutputOnFailure($addresses)
{
$this->ensureOutputIsBeingCaptured();
$addresses = Arr::wrap($addresses);
return $this->onFailure(function (Mailer $mailer) use ($addresses) {
$this->emailOutput($mailer, $addresses, false);
});
}
/**
* Ensure that the command output is being captured.
*
* @return void
......@@ -508,6 +532,32 @@ class Event
}
/**
* Register a callback to ping a given URL if the operation succeeds.
*
* @param string $url
* @return $this
*/
public function pingOnSuccess($url)
{
return $this->onSuccess(function () use ($url) {
(new HttpClient)->get($url);
});
}
/**
* Register a callback to ping a given URL if the operation fails.
*
* @param string $url
* @return $this
*/
public function pingOnFailure($url)
{
return $this->onFailure(function () use ($url) {
(new HttpClient)->get($url);
});
}
/**
* State that the command should run in background.
*
* @return $this
......@@ -656,6 +706,36 @@ class Event
}
/**
* Register a callback to be called if the operation succeeds.
*
* @param \Closure $callback
* @return $this
*/
public function onSuccess(Closure $callback)
{
return $this->then(function (Container $container) use ($callback) {
if (0 === $this->exitCode) {
$container->call($callback);
}
});
}
/**
* Register a callback to be called if the operation fails.
*
* @param \Closure $callback
* @return $this
*/
public function onFailure(Closure $callback)
{
return $this->then(function (Container $container) use ($callback) {
if (0 !== $this->exitCode) {
$container->call($callback);
}
});
}
/**
* Set the human-friendly description of the event.
*
* @param string $description
......
......@@ -91,7 +91,7 @@ interface Filesystem
*
* @param string $path
* @param string $data
* @return int
* @return bool
*/
public function prepend($path, $data);
......@@ -100,7 +100,7 @@ interface Filesystem
*
* @param string $path
* @param string $data
* @return int
* @return bool
*/
public function append($path, $data);
......
......@@ -46,12 +46,22 @@ class FactoryMakeCommand extends GeneratorCommand
*/
protected function buildClass($name)
{
$model = $this->option('model')
$namespaceModel = $this->option('model')
? $this->qualifyClass($this->option('model'))
: 'Model';
: trim($this->rootNamespace(), '\\').'\\Model';
$model = class_basename($namespaceModel);
return str_replace(
'DummyModel', $model, parent::buildClass($name)
[
'NamespacedDummyModel',
'DummyModel',
],
[
$namespaceModel,
$model,
],
parent::buildClass($name)
);
}
......
<?php
/* @var $factory \Illuminate\Database\Eloquent\Factory */
use NamespacedDummyModel;
use Faker\Generator as Faker;
$factory->define(DummyModel::class, function (Faker $faker) {
......
......@@ -494,6 +494,19 @@ class Collection extends BaseCollection implements QueueableCollection
}
/**
* Get the comparison function to detect duplicates.
*
* @param bool $strict
* @return \Closure
*/
protected function duplicateComparator($strict)
{
return function ($a, $b) {
return $a->is($b);
};
}
/**
* Get the type of the entities being queued.
*
* @return string|null
......
......@@ -1198,6 +1198,8 @@ class Builder
$value = $value->format('d');
}
$value = str_pad($value, 2, '0', STR_PAD_LEFT);
return $this->addDateBasedWhere('Day', $column, $operator, $value, $boolean);
}
......@@ -1237,6 +1239,8 @@ class Builder
$value = $value->format('m');
}
$value = str_pad($value, 2, '0', STR_PAD_LEFT);
return $this->addDateBasedWhere('Month', $column, $operator, $value, $boolean);
}
......
......@@ -1119,6 +1119,8 @@ class Grammar extends BaseGrammar
*/
protected function wrapJsonPath($value, $delimiter = '->')
{
$value = preg_replace("/([\\\\]+)?\\'/", "\\'", $value);
return '\'$."'.str_replace($delimiter, '"."', $value).'"\'';
}
......
......@@ -21,11 +21,32 @@ class JoinClause extends Builder
public $table;
/**
* The parent query builder instance.
* The connection of the parent query builder.
*
* @var \Illuminate\Database\Query\Builder
* @var \Illuminate\Database\ConnectionInterface
*/
private $parentQuery;
protected $parentConnection;
/**
* The grammar of the parent query builder.
*
* @var \Illuminate\Database\Query\Grammars\Grammar
*/
protected $parentGrammar;
/**
* The processor of the parent query builder.
*
* @var \Illuminate\Database\Query\Processors\Processor
*/
protected $parentProcessor;
/**
* The class name of the parent query builder.
*
* @var string
*/
protected $parentClass;
/**
* Create a new join clause instance.
......@@ -39,10 +60,13 @@ class JoinClause extends Builder
{
$this->type = $type;
$this->table = $table;
$this->parentQuery = $parentQuery;
$this->parentClass = get_class($parentQuery);
$this->parentGrammar = $parentQuery->getGrammar();
$this->parentProcessor = $parentQuery->getProcessor();
$this->parentConnection = $parentQuery->getConnection();
parent::__construct(
$parentQuery->getConnection(), $parentQuery->getGrammar(), $parentQuery->getProcessor()
$this->parentConnection, $this->parentGrammar, $this->parentProcessor
);
}
......@@ -95,7 +119,7 @@ class JoinClause extends Builder
*/
public function newQuery()
{
return new static($this->parentQuery, $this->type, $this->table);
return new static($this->newParentQuery(), $this->type, $this->table);
}
/**
......@@ -105,6 +129,18 @@ class JoinClause extends Builder
*/
protected function forSubQuery()
{
return $this->parentQuery->newQuery();
return $this->newParentQuery()->newQuery();
}
/**
* Create a new parent query instance.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function newParentQuery()
{
$class = $this->parentClass;
return new $class($this->parentConnection, $this->parentGrammar, $this->parentProcessor);
}
}
......@@ -857,6 +857,18 @@ class Blueprint
}
/**
* Create a new set column on the table.
*
* @param string $column
* @param array $allowed
* @return \Illuminate\Database\Schema\ColumnDefinition
*/
public function set($column, array $allowed)
{
return $this->addColumn('set', $column, compact('allowed'));
}
/**
* Create a new json column on the table.
*
* @param string $column
......
......@@ -4,6 +4,7 @@ namespace Illuminate\Database\Schema;
use Closure;
use LogicException;
use Doctrine\DBAL\Types\Type;
use Illuminate\Database\Connection;
class Builder
......@@ -285,6 +286,30 @@ class Builder
}
/**
* Register a custom Doctrine mapping type.
*
* @param string $class
* @param string $name
* @param string $type
* @return void
*
* @throws \Doctrine\DBAL\DBALException
*/
public function registerCustomDoctrineType($class, $name, $type)
{
if (Type::hasType($name)) {
return;
}
Type::addType($name, $class);
$this->connection
->getDoctrineSchemaManager()
->getDatabasePlatform()
->registerDoctrineTypeMapping($type, $name);
}
/**
* Get the database connection instance.
*
* @return \Illuminate\Database\Connection
......
......@@ -591,6 +591,17 @@ class MySqlGrammar extends Grammar
}
/**
* Create the column definition for a set enumeration type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeSet(Fluent $column)
{
return sprintf('set(%s)', $this->quoteString($column->allowed));
}
/**
* Create the column definition for a json type.
*
* @param \Illuminate\Support\Fluent $column
......
......@@ -824,4 +824,19 @@ class SqlServerGrammar extends Grammar
return parent::wrapTable($table);
}
/**
* Quote the given string literal.
*
* @param string|array $value
* @return string
*/
public function quoteString($value)
{
if (is_array($value)) {
return implode(', ', array_map([$this, __FUNCTION__], $value));
}
return "N'$value'";
}
}
......@@ -2,9 +2,27 @@
namespace Illuminate\Database\Schema;
use Illuminate\Database\Connection;
use Illuminate\Database\Schema\Types\TinyInteger;
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.
*
* @param string $table
......@@ -111,4 +129,20 @@ class MySqlBuilder extends Builder
$this->grammar->compileGetAllViews()
);
}
/**
* Register the custom Doctrine mapping types for the MySQL builder.
*
* @return void
*
* @throws \Doctrine\DBAL\DBALException
*/
protected function registerCustomDoctrineTypes()
{
if ($this->connection->isDoctrineAvailable()) {
$this->registerCustomDoctrineType(
TinyInteger::class, TinyInteger::NAME, 'TINYINT'
);
}
}
}
......@@ -160,7 +160,7 @@ class FilesystemManager implements FactoryContract
: LocalAdapter::DISALLOW_LINKS;
return $this->adapt($this->createFlysystem(new LocalAdapter(
$config['root'], LOCK_EX, $links, $permissions
$config['root'], $config['lock'] ?? LOCK_EX, $links, $permissions
), $config));
}
......
......@@ -29,7 +29,7 @@ class Application extends Container implements ApplicationContract, HttpKernelIn
*
* @var string
*/
const VERSION = '5.8.10';
const VERSION = '5.8.13';
/**
* The base path for the Laravel installation.
......
......@@ -2,6 +2,7 @@
namespace Illuminate\Foundation\Console;
use Illuminate\Support\Str;
use Illuminate\Console\Command;
use Illuminate\Foundation\Support\Providers\EventServiceProvider;
......@@ -12,7 +13,7 @@ class EventListCommand extends Command
*
* @var string
*/
protected $signature = 'event:list';
protected $signature = 'event:list {--event= : Filter the events by name}';
/**
* The console command description.
......@@ -28,7 +29,13 @@ class EventListCommand extends Command
*/
public function handle()
{
$this->table(['Event', 'Listeners'], $this->getEvents());
$events = $this->getEvents();
if (empty($events)) {
return $this->error("Your application doesn't have any events matching the given criteria.");
}
$this->table(['Event', 'Listeners'], $events);
}
/**
......@@ -46,8 +53,39 @@ class EventListCommand extends Command
$events = array_merge_recursive($events, $providerEvents);
}
return collect($events)->map(function ($value, $key) {
return ['Event' => $key, 'Listeners' => implode("\n", $value)];
if ($this->filteringByEvent()) {
$events = $this->filterEvents($events);
}
return collect($events)->map(function ($listeners, $event) {
return ['Event' => $event, 'Listeners' => implode(PHP_EOL, $listeners)];
})->sortBy('Event')->values()->toArray();
}
/**
* Filter the given events using the provided event name filter.
*
* @param array $events
* @return array
*/
protected function filterEvents(array $events)
{
if (! $eventName = $this->option('event')) {
return $events;
}
return collect($events)->filter(function ($listeners, $event) use ($eventName) {
return Str::contains($event, $eventName);
})->toArray();
}
/**
* Determine whether the user is filtering by an event name.
*
* @return bool
*/
protected function filteringByEvent()
{
return ! empty($this->option('event'));
}
}
......@@ -224,7 +224,7 @@ class Kernel implements KernelContract
$command = $namespace.str_replace(
['/', '.php'],
['\\', ''],
Str::after($command->getPathname(), app_path().DIRECTORY_SEPARATOR)
Str::after($command->getPathname(), realpath(app_path()).DIRECTORY_SEPARATOR)
);
if (is_subclass_of($command, Command::class) &&
......
......@@ -19,17 +19,11 @@ class DiscoverEvents
*/
public static function within($listenerPath, $basePath)
{
$listenerEvents = collect(static::getListenerEvents((new Finder)
->files()
->in($listenerPath), $basePath));
return $listenerEvents->values()
->zip($listenerEvents->keys()->all())
->reduce(function ($carry, $listenerEventPair) {
$carry[$listenerEventPair[0]][] = $listenerEventPair[1];
return $carry;
}, []);
return collect(static::getListenerEvents(
(new Finder)->files()->in($listenerPath), $basePath
))->mapToDictionary(function ($event, $listener) {
return [$event => $listener];
})->all();
}
/**
......@@ -73,6 +67,10 @@ class DiscoverEvents
{
$class = trim(str_replace($basePath, '', $file->getRealPath()), DIRECTORY_SEPARATOR);
return str_replace(DIRECTORY_SEPARATOR, '\\', ucfirst(Str::replaceLast('.php', '', $class)));
return str_replace(
[DIRECTORY_SEPARATOR, 'App\\'],
['\\', app()->getNamespace()],
ucfirst(Str::replaceLast('.php', '', $class))
);
}
}
......@@ -15,7 +15,7 @@ class CreateSessionsTable extends Migration
{
Schema::create('sessions', function (Blueprint $table) {
$table->string('id')->unique();
$table->unsignedInteger('user_id')->nullable();
$table->unsignedBigInteger('user_id')->nullable();
$table->string('ip_address', 45)->nullable();
$table->text('user_agent')->nullable();
$table->text('payload');
......
......@@ -36,8 +36,6 @@ use Illuminate\Contracts\Support\Arrayable;
* @property-read HigherOrderCollectionProxy $sortByDesc
* @property-read HigherOrderCollectionProxy $sum
* @property-read HigherOrderCollectionProxy $unique
*
* Class Collection
*/
class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate, Jsonable, JsonSerializable
{
......@@ -408,6 +406,64 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
}
/**
* Retrieve duplicate items from the collection.
*
* @param callable|null $callback
* @param bool $strict
* @return static
*/
public function duplicates($callback = null, $strict = false)
{
$items = $this->map($this->valueRetriever($callback));
$uniqueItems = $items->unique(null, $strict);
$compare = $this->duplicateComparator($strict);
$duplicates = new static;
foreach ($items as $key => $value) {
if ($uniqueItems->isNotEmpty() && $compare($value, $uniqueItems->first())) {
$uniqueItems->shift();
} else {
$duplicates[$key] = $value;
}
}
return $duplicates;
}
/**
* Retrieve duplicate items from the collection using strict comparison.
*
* @param callable|null $callback
* @return static
*/
public function duplicatesStrict($callback = null)
{
return $this->duplicates($callback, true);
}
/**
* Get the comparison function to detect duplicates.
*
* @param bool $strict
* @return \Closure
*/
protected function duplicateComparator($strict)
{
if ($strict) {
return function ($a, $b) {
return $a === $b;
};
}
return function ($a, $b) {
return $a == $b;
};
}
/**
* Execute a callback over each item.
*
* @param callable $callback
......
......@@ -212,7 +212,8 @@ class DateFactory
$dateClass = static::$dateClass ?: $defaultClassName;
// Check if date can be created using public class method...
if (method_exists($dateClass, $method)) {
if (method_exists($dateClass, $method) ||
method_exists($dateClass, 'hasMacro') && $dateClass::hasMacro($method)) {
return $dateClass::$method(...$parameters);
}
......
......@@ -6,12 +6,12 @@ use Illuminate\Support\Testing\Fakes\QueueFake;
/**
* @method static int size(string $queue = null)
* @method static mixed push(string|object $job, string $data = '', $queue = null)
* @method static mixed pushOn(string $queue, string|object $job, $data = '')
* @method static mixed push(string|object $job, mixed $data = '', $queue = null)
* @method static mixed pushOn(string $queue, string|object $job, mixed $data = '')
* @method static mixed pushRaw(string $payload, string $queue = null, array $options = [])
* @method static mixed later(\DateTimeInterface|\DateInterval|int $delay, string|object $job, $data = '', string $queue = null)
* @method static mixed laterOn(string $queue, \DateTimeInterface|\DateInterval|int $delay, string|object $job, $data = '')
* @method static mixed bulk(array $jobs, $data = '', string $queue = null)
* @method static mixed later(\DateTimeInterface|\DateInterval|int $delay, string|object $job, mixed $data = '', string $queue = null)
* @method static mixed laterOn(string $queue, \DateTimeInterface|\DateInterval|int $delay, string|object $job, mixed $data = '')
* @method static mixed bulk(array $jobs, mixed $data = '', string $queue = null)
* @method static \Illuminate\Contracts\Queue\Job|null pop(string $queue = null)
* @method static string getConnectionName()
* @method static \Illuminate\Contracts\Queue\Queue setConnectionName(string $name)
......
......@@ -7,9 +7,11 @@ namespace Illuminate\Support\Facades;
* @method static \Illuminate\Database\Schema\Builder drop(string $table)
* @method static \Illuminate\Database\Schema\Builder dropIfExists(string $table)
* @method static \Illuminate\Database\Schema\Builder table(string $table, \Closure $callback)
* @method static \Illuminate\Database\Schema\Builder rename(string $from, string $to)
* @method static void defaultStringLength(int $length)
* @method static \Illuminate\Database\Schema\Builder disableForeignKeyConstraints()
* @method static \Illuminate\Database\Schema\Builder enableForeignKeyConstraints()
* @method static void registerCustomDBALType(string $class, string $name, string $type)
*
* @see \Illuminate\Database\Schema\Builder
*/
......
......@@ -2,6 +2,7 @@
namespace Illuminate\Support\Testing\Fakes;
use BadMethodCallException;
use Illuminate\Queue\QueueManager;
use Illuminate\Contracts\Queue\Queue;
use PHPUnit\Framework\Assert as PHPUnit;
......@@ -357,4 +358,18 @@ class QueueFake extends QueueManager implements Queue
{
return $this;
}
/**
* Override the QueueManager to prevent circular dependency.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
throw new BadMethodCallException(sprintf(
'Call to undefined method %s::%s()', static::class, $method
));
}
}
......@@ -891,7 +891,9 @@ trait ValidatesAttributes
return $this->getSize($attribute, $value) > $parameters[0];
}
$this->requireSameType($value, $comparedToValue);
if (! $this->isSameType($value, $comparedToValue)) {
return false;
}
return $this->getSize($attribute, $value) > $this->getSize($attribute, $comparedToValue);
}
......@@ -916,7 +918,9 @@ trait ValidatesAttributes
return $this->getSize($attribute, $value) < $parameters[0];
}
$this->requireSameType($value, $comparedToValue);
if (! $this->isSameType($value, $comparedToValue)) {
return false;
}
return $this->getSize($attribute, $value) < $this->getSize($attribute, $comparedToValue);
}
......@@ -941,7 +945,9 @@ trait ValidatesAttributes
return $this->getSize($attribute, $value) >= $parameters[0];
}
$this->requireSameType($value, $comparedToValue);
if (! $this->isSameType($value, $comparedToValue)) {
return false;
}
return $this->getSize($attribute, $value) >= $this->getSize($attribute, $comparedToValue);
}
......@@ -966,7 +972,9 @@ trait ValidatesAttributes
return $this->getSize($attribute, $value) <= $parameters[0];
}
$this->requireSameType($value, $comparedToValue);
if (! $this->isSameType($value, $comparedToValue)) {
return false;
}
return $this->getSize($attribute, $value) <= $this->getSize($attribute, $comparedToValue);
}
......@@ -1721,19 +1729,15 @@ trait ValidatesAttributes
}
/**
* Require comparison values to be of the same type.
* Check if the parameters are of the same type.
*
* @param mixed $first
* @param mixed $second
* @return void
*
* @throws \InvalidArgumentException
* @return bool
*/
protected function requireSameType($first, $second)
protected function isSameType($first, $second)
{
if (gettype($first) != gettype($second)) {
throw new InvalidArgumentException('The values under comparison must be of the same type');
}
return gettype($first) == gettype($second);
}
/**
......
......@@ -13,6 +13,7 @@ class BladeCompiler extends Compiler implements CompilerInterface
Concerns\CompilesComponents,
Concerns\CompilesConditionals,
Concerns\CompilesEchos,
Concerns\CompilesErrors,
Concerns\CompilesHelpers,
Concerns\CompilesIncludes,
Concerns\CompilesInjections,
......@@ -122,6 +123,19 @@ class BladeCompiler extends Compiler implements CompilerInterface
$this->files->get($this->getPath())
);
if (! empty($this->getPath())) {
$tokens = $this->getOpenAndClosingPhpTokens($contents);
// If the tokens we retrieved from the compiled contents have at least
// one opening tag and if that last token isn't the closing tag, we
// need to close the statement before adding the path at the end.
if ($tokens->isNotEmpty() && $tokens->last() !== T_CLOSE_TAG) {
$contents .= ' ?>';
}
$contents .= "<?php /**PATH {$this->getPath()} ENDPATH**/ ?>";
}
$this->files->put(
$this->getCompiledPath($this->getPath()), $contents
);
......@@ -129,6 +143,21 @@ class BladeCompiler extends Compiler implements CompilerInterface
}
/**
* Get the open and closing PHP tag tokens from the given string.
*
* @param string $contents
* @return \Illuminate\Support\Collection
*/
protected function getOpenAndClosingPhpTokens($contents)
{
return collect(token_get_all($contents))
->pluck($tokenNumber = 0)
->filter(function ($token) {
return in_array($token, [T_OPEN_TAG, T_OPEN_TAG_WITH_ECHO, T_CLOSE_TAG]);
});
}
/**
* Get the path currently being compiled.
*
* @return string
......
......@@ -301,6 +301,16 @@ class FileViewFinder implements ViewFinderInterface
}
/**
* Get the views that have been located.
*
* @return array
*/
public function getViews()
{
return $this->views;
}
/**
* Get the namespace to file path hints.
*
* @return array
......
......@@ -99,6 +99,14 @@ class DeepCopy
];
}
public function prependFilter(Filter $filter, Matcher $matcher)
{
array_unshift($this->filters, [
'matcher' => $matcher,
'filter' => $filter,
]);
}
public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher)
{
$this->typeFilters[] = [
......
......@@ -28,9 +28,9 @@
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.14 || ^3.0",
"kylekatarnls/multi-tester": "^0.1",
"kylekatarnls/multi-tester": "^1.1",
"phpmd/phpmd": "^2.6",
"phpstan/phpstan": "^0.10.8",
"phpstan/phpstan": "^0.11",
"phpunit/phpunit": "^7.5 || ^8.0",
"squizlabs/php_codesniffer": "^3.4"
},
......
......@@ -615,6 +615,13 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
public function __construct($time = null, $tz = null);
/**
* Show truthy properties on var_dump().
*
* @return array
*/
public function __debugInfo();
/**
* Get a part of the Carbon object
*
* @param string $name
......@@ -1858,6 +1865,8 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
public static function getFormatsToIsoReplacements();
/**
* Return default humanDiff() options (merged flags as integer).
*
* @return int
*/
public static function getHumanDiffOptions();
......@@ -2389,6 +2398,8 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
public function isYesterday();
/**
* Format in the current language using ISO replacement patterns.
*
* @param string $format
* @param string|null $originalFormat provide context if a chunk has been passed alone
*
......
......@@ -179,6 +179,8 @@ class CarbonInterval extends DateInterval
}
/**
* Set default cascading factors for ->cascade() method.
*
* @param array $cascadeFactors
*/
public static function setCascadeFactors(array $cascadeFactors)
......
......@@ -57,7 +57,7 @@ namespace Carbon;
* @method array getDays() Get the days of the week
* @method string|null getFallbackLocale() Get the fallback locale.
* @method array getFormatsToIsoReplacements() List of replacements from date() format to isoFormat().
* @method int getHumanDiffOptions() @return int
* @method int getHumanDiffOptions() Return default humanDiff() options (merged flags as integer).
* @method array getIsoUnits() Returns list of locale units for ISO formatting.
* @method Carbon getLastErrors() {@inheritdoc}
* @method string getLocale() Get the current translator locale.
......
......@@ -57,7 +57,7 @@ namespace Carbon;
* @method array getDays() Get the days of the week
* @method string|null getFallbackLocale() Get the fallback locale.
* @method array getFormatsToIsoReplacements() List of replacements from date() format to isoFormat().
* @method int getHumanDiffOptions() @return int
* @method int getHumanDiffOptions() Return default humanDiff() options (merged flags as integer).
* @method array getIsoUnits() Returns list of locale units for ISO formatting.
* @method CarbonImmutable getLastErrors() {@inheritdoc}
* @method string getLocale() Get the current translator locale.
......
......@@ -14,6 +14,7 @@
* - Atef Ben Ali (atefBB)
* - Ibrahim AshShohail
* - MLTDev
* - Yazan Alnugnugh (yazan-alnugnugh)
*/
$months = [
'يناير',
......@@ -38,6 +39,7 @@ return [
'hour' => implode('|', ['ساعة', 'ساعة', 'ساعتين', 'ساعات'.' :count', 'ساعة'.' :count']),
'minute' => implode('|', ['دقيقة', 'دقيقة', 'دقيقتين', 'دقائق'.' :count', 'دقيقة'.' :count']),
'second' => implode('|', ['ثانية', 'ثانية', 'ثانيتين', 'ثوان'.' :count', 'ثانية'.' :count']),
'a_second' => implode('|', ['{1}'.'بضع ثواني', 'ثانية', 'ثانية', 'ثانيتين', 'ثوان'.' :count', 'ثانية'.' :count']),
'ago' => 'منذ :time',
'from_now' => ':time من الآن',
'after' => 'بعد :time',
......@@ -61,7 +63,7 @@ return [
'meridiem' => ['ص', 'م'],
'weekdays' => ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
'weekdays_short' => ['أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة', 'سبت'],
'weekdays_min' => ['ح', 'ن', 'ث', 'ر', ', 'ج', 'س'],
'weekdays_min' => ['ح', 'اث', 'ثل', 'أر', 'خم', 'ج', 'س'],
'months' => $months,
'months_short' => $months,
'first_day_of_week' => 6,
......
......@@ -16,6 +16,7 @@
* - codenhagen
* - JD Isaacks
* - Jens Herlevsen
* - Ulrik McArdle (mcardle)
*/
return [
'year' => ':count år|:count år',
......@@ -28,8 +29,8 @@ return [
'a_week' => 'en uge|:count uger',
'w' => ':count u.',
'day' => ':count dag|:count dage',
'a_day' => 'en d.',
'd' => ':count dag|:count dage',
'a_day' => ':count dag|:count dage',
'd' => 'en d.',
'hour' => ':count time|:count timer',
'a_hour' => 'en time|:count timer',
'h' => ':count t.',
......
......@@ -41,6 +41,11 @@ return [
'from_now' => 'në :time',
'after' => ':time pas',
'before' => ':time para',
'diff_now' => 'tani',
'diff_yesterday' => 'dje',
'diff_tomorrow' => 'nesër',
'diff_before_yesterday' => 'pardje',
'diff_after_tomorrow' => 'pasnesër',
'formats' => [
'LT' => 'HH:mm',
'LTS' => 'HH:mm:ss',
......
......@@ -18,29 +18,30 @@
* - JD Isaacks
* - Murat Yüksel
* - Baran Şengül
* - Selami (selamialtin)
*/
return [
'year' => ':count yıl',
'a_year' => '{1}bir yıl|]1,Inf[:count yıl',
'y' => ':count yıl',
'y' => ':countyıl',
'month' => ':count ay',
'a_month' => '{1}bir ay|]1,Inf[:count ay',
'm' => ':count ay',
'm' => ':countay',
'week' => ':count hafta',
'a_week' => '{1}bir hafta|]1,Inf[:count hafta',
'w' => ':count hafta',
'w' => ':counth',
'day' => ':count gün',
'a_day' => '{1}bir gün|]1,Inf[:count gün',
'd' => ':count gün',
'd' => ':countg',
'hour' => ':count saat',
'a_hour' => '{1}bir saat|]1,Inf[:count saat',
'h' => ':count saat',
'h' => ':countsa',
'minute' => ':count dakika',
'a_minute' => '{1}bir dakika|]1,Inf[:count dakika',
'min' => ':count dakika',
'min' => ':countdk',
'second' => ':count saniye',
'a_second' => '{1}birkaç saniye|]1,Inf[:count saniye',
's' => ':count saniye',
's' => ':countsn',
'ago' => ':time önce',
'from_now' => ':time sonra',
'after' => ':time sonra',
......
......@@ -76,6 +76,11 @@ class Language implements JsonSerializable
}
}
/**
* Get the list of the known languages.
*
* @return array
*/
public static function all()
{
if (!static::$languagesNames) {
......@@ -85,6 +90,11 @@ class Language implements JsonSerializable
return static::$languagesNames;
}
/**
* Get the list of the known regions.
*
* @return array
*/
public static function regions()
{
if (!static::$regionsNames) {
......@@ -95,6 +105,8 @@ class Language implements JsonSerializable
}
/**
* Get both isoName and nativeName as an array.
*
* @return array
*/
public function getNames(): array
......@@ -110,6 +122,8 @@ class Language implements JsonSerializable
}
/**
* Returns the original locale ID.
*
* @return string
*/
public function getId(): string
......@@ -118,6 +132,8 @@ class Language implements JsonSerializable
}
/**
* Returns the code of the locale "en"/"fr".
*
* @return string
*/
public function getCode(): string
......@@ -126,6 +142,8 @@ class Language implements JsonSerializable
}
/**
* Returns the variant code such as cyrl/latn.
*
* @return string|null
*/
public function getVariant(): ?string
......@@ -134,6 +152,8 @@ class Language implements JsonSerializable
}
/**
* Returns the variant such as Cyrillic/Latin.
*
* @return string|null
*/
public function getVariantName(): ?string
......@@ -150,6 +170,8 @@ class Language implements JsonSerializable
}
/**
* Returns the region part of the locale.
*
* @return string|null
*/
public function getRegion(): ?string
......@@ -158,6 +180,8 @@ class Language implements JsonSerializable
}
/**
* Returns the region name for the current language.
*
* @return string|null
*/
public function getRegionName(): ?string
......@@ -166,6 +190,8 @@ class Language implements JsonSerializable
}
/**
* Returns the long ISO language name.
*
* @return string
*/
public function getFullIsoName(): string
......@@ -178,6 +204,8 @@ class Language implements JsonSerializable
}
/**
* Set the ISO language name.
*
* @param string $isoName
*/
public function setIsoName(string $isoName): self
......@@ -188,6 +216,8 @@ class Language implements JsonSerializable
}
/**
* Return the full name of the language in this language.
*
* @return string
*/
public function getFullNativeName(): string
......@@ -200,6 +230,8 @@ class Language implements JsonSerializable
}
/**
* Set the name of the language in this language.
*
* @param string $nativeName
*/
public function setNativeName(string $nativeName): self
......@@ -210,6 +242,8 @@ class Language implements JsonSerializable
}
/**
* Returns the short ISO language name.
*
* @return string
*/
public function getIsoName(): string
......@@ -220,6 +254,8 @@ class Language implements JsonSerializable
}
/**
* Get the short name of the language in this language.
*
* @return string
*/
public function getNativeName(): string
......@@ -229,6 +265,11 @@ class Language implements JsonSerializable
return trim(strstr($name, ',', true) ?: $name);
}
/**
* Get a string with short ISO name, region in parentheses if applicable, variant in parentheses if applicable.
*
* @return string
*/
public function getIsoDescription()
{
$region = $this->getRegionName();
......@@ -237,6 +278,11 @@ class Language implements JsonSerializable
return $this->getIsoName().($region ? ' ('.$region.')' : '').($variant ? ' ('.$variant.')' : '');
}
/**
* Get a string with short native name, region in parentheses if applicable, variant in parentheses if applicable.
*
* @return string
*/
public function getNativeDescription()
{
$region = $this->getRegionName();
......@@ -245,6 +291,11 @@ class Language implements JsonSerializable
return $this->getNativeName().($region ? ' ('.$region.')' : '').($variant ? ' ('.$variant.')' : '');
}
/**
* Get a string with long ISO name, region in parentheses if applicable, variant in parentheses if applicable.
*
* @return string
*/
public function getFullIsoDescription()
{
$region = $this->getRegionName();
......@@ -253,6 +304,11 @@ class Language implements JsonSerializable
return $this->getFullIsoName().($region ? ' ('.$region.')' : '').($variant ? ' ('.$variant.')' : '');
}
/**
* Get a string with long native name, region in parentheses if applicable, variant in parentheses if applicable.
*
* @return string
*/
public function getFullNativeDescription()
{
$region = $this->getRegionName();
......@@ -261,11 +317,21 @@ class Language implements JsonSerializable
return $this->getFullNativeName().($region ? ' ('.$region.')' : '').($variant ? ' ('.$variant.')' : '');
}
/**
* Returns the original locale ID.
*
* @return string
*/
public function __toString()
{
return $this->getId();
}
/**
* Get a string with short ISO name, region in parentheses if applicable, variant in parentheses if applicable.
*
* @return string
*/
public function jsonSerialize()
{
return $this->getIsoDescription();
......
......@@ -15,8 +15,10 @@ class ServiceProvider extends \Illuminate\Support\ServiceProvider
if (!$this->app->bound('events') || !$this->app->bound('translator')) {
return;
}
$service = $this;
$events = $this->app['events'];
if ($events instanceof EventDispatcher || $events instanceof Dispatcher) {
$events->listen(class_exists('Illuminate\Foundation\Events\LocaleUpdated') ? 'Illuminate\Foundation\Events\LocaleUpdated' : 'locale.changed', function () use ($service) {
$service->updateLocale();
......@@ -28,6 +30,7 @@ class ServiceProvider extends \Illuminate\Support\ServiceProvider
public function updateLocale()
{
$translator = $this->app['translator'];
if ($translator instanceof Translator || $translator instanceof IlluminateTranslator) {
Carbon::setLocale($translator->getLocale());
}
......
......@@ -1939,6 +1939,8 @@ trait Date
}
/**
* Format in the current language using ISO replacement patterns.
*
* @param string $format
* @param string|null $originalFormat provide context if a chunk has been passed alone
*
......
......@@ -454,7 +454,7 @@ trait Difference
{
$hoursDiff = $this->floatDiffInHours($date, $absolute);
return ($hoursDiff < 0 ? -1 : 1) * $this->diffInDays($date) + ($hoursDiff % static::HOURS_PER_DAY) / static::HOURS_PER_DAY;
return ($hoursDiff < 0 ? -1 : 1) * $this->diffInDays($date) + fmod($hoursDiff, static::HOURS_PER_DAY) / static::HOURS_PER_DAY;
}
/**
......@@ -584,7 +584,7 @@ trait Difference
{
$hoursDiff = $this->floatDiffInRealHours($date, $absolute);
return ($hoursDiff < 0 ? -1 : 1) * $this->diffInDays($date) + ($hoursDiff % static::HOURS_PER_DAY) / static::HOURS_PER_DAY;
return ($hoursDiff < 0 ? -1 : 1) * $this->diffInDays($date) + fmod($hoursDiff, static::HOURS_PER_DAY) / static::HOURS_PER_DAY;
}
/**
......
......@@ -83,6 +83,8 @@ trait Localization
}
/**
* Return default humanDiff() options (merged flags as integer).
*
* @return int
*/
public static function getHumanDiffOptions()
......@@ -327,7 +329,7 @@ trait Localization
foreach ($fromTranslations as $index => $word) {
if (preg_match("/^$word\$/i", $chunk)) {
return $toTranslations[$index];
return $toTranslations[$index] ?? '';
}
}
......
......@@ -403,4 +403,16 @@ trait Options
return $settings;
}
/**
* Show truthy properties on var_dump().
*
* @return array
*/
public function __debugInfo()
{
return array_filter(get_object_vars($this), function ($var) {
return $var;
});
}
}
......@@ -365,4 +365,16 @@ class Translator extends Translation\Translator
return false;
}
/**
* Show locale on var_dump().
*
* @return array
*/
public function __debugInfo()
{
return [
'locale' => $this->getLocale(),
];
}
}
......@@ -2,6 +2,12 @@
All notable changes of the PHPUnit 7.5 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [7.5.9] - 2019-04-19
### Fixed
* Fixed [#3607](https://github.com/sebastianbergmann/phpunit/issues/3607): Return value generation interferes with proxying to original method
## [7.5.8] - 2019-03-26
### Fixed
......@@ -87,6 +93,7 @@ All notable changes of the PHPUnit 7.5 release series are documented in this fil
* Fixed [#3429](https://github.com/sebastianbergmann/phpunit/pull/3429): Inefficient loop in `getHookMethods()`
* Fixed [#3437](https://github.com/sebastianbergmann/phpunit/pull/3437): JUnit logger skips PHPT tests
[7.5.9]: https://github.com/sebastianbergmann/phpunit/compare/7.5.8...7.5.9
[7.5.8]: https://github.com/sebastianbergmann/phpunit/compare/7.5.7...7.5.8
[7.5.7]: https://github.com/sebastianbergmann/phpunit/compare/7.5.6...7.5.7
[7.5.6]: https://github.com/sebastianbergmann/phpunit/compare/7.5.5...7.5.6
......
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="phpab" version="^1.25" installed="1.25.3" location="./tools/phpab" copy="true"/>
<phar name="phpab" version="^1.25" installed="1.25.4" location="./tools/phpab" copy="true"/>
<phar name="php-cs-fixer" version="^2.14" installed="2.14.2" location="./tools/php-cs-fixer" copy="true"/>
<phar name="phpdox" version="^0.11" installed="0.12.0" location="./tools/phpdox" copy="true"/>
<phar name="phploc" version="^4.0" installed="4.0.1" location="./tools/phploc" copy="true"/>
......
......@@ -12,11 +12,15 @@
}
}
$this->__phpunit_getInvocationMocker()->invoke(
new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
$__phpunit_invocation = new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
'{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}
)
);
$__phpunit_invocation->setProxiedCall();
$this->__phpunit_getInvocationMocker()->invoke($__phpunit_invocation);
unset($__phpunit_invocation);
return call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $__phpunit_arguments);
}
......@@ -12,11 +12,15 @@
}
}
$this->__phpunit_getInvocationMocker()->invoke(
new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
$__phpunit_invocation = new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
'{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}
)
);
$__phpunit_invocation->setProxiedCall();
$this->__phpunit_getInvocationMocker()->invoke($__phpunit_invocation);
unset($__phpunit_invocation);
call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $__phpunit_arguments);
}
......@@ -71,6 +71,11 @@ class StaticInvocation implements Invocation, SelfDescribing
private $isReturnTypeNullable = false;
/**
* @var bool
*/
private $proxiedCall = false;
/**
* @param string $className
* @param string $methodName
* @param string $returnType
......@@ -138,7 +143,7 @@ class StaticInvocation implements Invocation, SelfDescribing
*/
public function generateReturnValue()
{
if ($this->isReturnTypeNullable) {
if ($this->isReturnTypeNullable || $this->proxiedCall) {
return;
}
......@@ -186,6 +191,11 @@ class StaticInvocation implements Invocation, SelfDescribing
}
}
public function setProxiedCall(): void
{
$this->proxiedCall = true;
}
public function toString(): string
{
$exporter = new Exporter;
......
......@@ -30,7 +30,7 @@ class Version
}
if (self::$version === null) {
$version = new VersionId('7.5.8', \dirname(__DIR__, 2));
$version = new VersionId('7.5.9', \dirname(__DIR__, 2));
self::$version = $version->getVersion();
}
......
......@@ -49,12 +49,16 @@ class ProxyFoo extends Foo implements PHPUnit\Framework\MockObject\MockObject
}
}
$this->__phpunit_getInvocationMocker()->invoke(
new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
$__phpunit_invocation = new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
'Foo', 'bar', $__phpunit_arguments, '', $this, true
)
);
$__phpunit_invocation->setProxiedCall();
$this->__phpunit_getInvocationMocker()->invoke($__phpunit_invocation);
unset($__phpunit_invocation);
return call_user_func_array(array($this->__phpunit_originalObject, "bar"), $__phpunit_arguments);
}
......@@ -71,12 +75,16 @@ class ProxyFoo extends Foo implements PHPUnit\Framework\MockObject\MockObject
}
}
$this->__phpunit_getInvocationMocker()->invoke(
new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
$__phpunit_invocation = new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
'Foo', 'baz', $__phpunit_arguments, '', $this, true
)
);
$__phpunit_invocation->setProxiedCall();
$this->__phpunit_getInvocationMocker()->invoke($__phpunit_invocation);
unset($__phpunit_invocation);
return call_user_func_array(array($this->__phpunit_originalObject, "baz"), $__phpunit_arguments);
}
......
......@@ -35,11 +35,15 @@ print $code;
}
}
$this->__phpunit_getInvocationMocker()->invoke(
new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
$__phpunit_invocation = new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
'Foo', 'bar', $__phpunit_arguments, '', $this, false
)
);
$__phpunit_invocation->setProxiedCall();
$this->__phpunit_getInvocationMocker()->invoke($__phpunit_invocation);
unset($__phpunit_invocation);
return call_user_func_array(array($this->__phpunit_originalObject, "bar"), $__phpunit_arguments);
}
......@@ -35,11 +35,15 @@ private function bar($arg)
}
}
$this->__phpunit_getInvocationMocker()->invoke(
new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
$__phpunit_invocation = new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
'Foo', 'bar', $__phpunit_arguments, '', $this, false
)
);
$__phpunit_invocation->setProxiedCall();
$this->__phpunit_getInvocationMocker()->invoke($__phpunit_invocation);
unset($__phpunit_invocation);
return call_user_func_array(array($this->__phpunit_originalObject, "bar"), $__phpunit_arguments);
}
......@@ -35,11 +35,15 @@ private function bar(...$args)
}
}
$this->__phpunit_getInvocationMocker()->invoke(
new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
$__phpunit_invocation = new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
'Foo', 'bar', $__phpunit_arguments, '', $this, false
)
);
$__phpunit_invocation->setProxiedCall();
$this->__phpunit_getInvocationMocker()->invoke($__phpunit_invocation);
unset($__phpunit_invocation);
return call_user_func_array(array($this->__phpunit_originalObject, "bar"), $__phpunit_arguments);
}
......@@ -35,11 +35,15 @@ print $code;
}
}
$this->__phpunit_getInvocationMocker()->invoke(
new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
$__phpunit_invocation = new \PHPUnit\Framework\MockObject\Invocation\ObjectInvocation(
'Foo', 'bar', $__phpunit_arguments, 'void', $this, false
)
);
$__phpunit_invocation->setProxiedCall();
$this->__phpunit_getInvocationMocker()->invoke($__phpunit_invocation);
unset($__phpunit_invocation);
call_user_func_array(array($this->__phpunit_originalObject, "bar"), $__phpunit_arguments);
}
<?php
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
......@@ -8,34 +8,86 @@
* file that was distributed with this source code.
*/
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
class ProxyObjectTest extends TestCase
final class ProxyObjectTest extends TestCase
{
public function testMockedMethodIsProxiedToOriginalMethod(): void
public function testProxyingWorksForMethodThatReturnsUndeclaredScalarValue(): void
{
$proxy = $this->getMockBuilder(Bar::class)
->enableProxyingToOriginalMethods()
->getMock();
$proxy = $this->createTestProxy(TestProxyFixture::class);
$proxy->expects($this->once())
->method('doSomethingElse');
->method('returnString');
$foo = new Foo;
\assert($proxy instanceof MockObject);
\assert($proxy instanceof TestProxyFixture);
$this->assertEquals('result', $foo->doSomething($proxy));
$this->assertSame('result', $proxy->returnString());
}
public function testMockedMethodWithReferenceIsProxiedToOriginalMethod(): void
public function testProxyingWorksForMethodThatReturnsDeclaredScalarValue(): void
{
$proxy = $this->getMockBuilder(MethodCallbackByReference::class)
->enableProxyingToOriginalMethods()
->getMock();
$proxy = $this->createTestProxy(TestProxyFixture::class);
$a = $b = $c = 0;
$proxy->expects($this->once())
->method('returnTypedString');
\assert($proxy instanceof MockObject);
\assert($proxy instanceof TestProxyFixture);
$this->assertSame('result', $proxy->returnTypedString());
}
public function testProxyingWorksForMethodThatReturnsUndeclaredObject(): void
{
$proxy = $this->createTestProxy(TestProxyFixture::class);
$proxy->expects($this->once())
->method('returnObject');
\assert($proxy instanceof MockObject);
\assert($proxy instanceof TestProxyFixture);
$this->assertSame('bar', $proxy->returnObject()->foo);
}
public function testProxyingWorksForMethodThatReturnsDeclaredObject(): void
{
$proxy = $this->createTestProxy(TestProxyFixture::class);
$proxy->expects($this->once())
->method('returnTypedObject');
\assert($proxy instanceof MockObject);
\assert($proxy instanceof TestProxyFixture);
$this->assertSame('bar', $proxy->returnTypedObject()->foo);
}
public function testProxyingWorksForMethodThatReturnsUndeclaredObjectOfFinalClass(): void
{
$proxy = $this->createTestProxy(TestProxyFixture::class);
$proxy->expects($this->once())
->method('returnObjectOfFinalClass');
\assert($proxy instanceof MockObject);
\assert($proxy instanceof TestProxyFixture);
$this->assertSame('value', $proxy->returnObjectOfFinalClass()->value());
}
public function testProxyingWorksForMethodThatReturnsDeclaredObjectOfFinalClass(): void
{
$proxy = $this->createTestProxy(TestProxyFixture::class);
$proxy->expects($this->once())
->method('returnTypedObjectOfFinalClass');
$proxy->callback($a, $b, $c);
\assert($proxy instanceof MockObject);
\assert($proxy instanceof TestProxyFixture);
$this->assertEquals(1, $b);
$this->assertSame('value', $proxy->returnTypedObjectOfFinalClass()->value());
}
}
......@@ -263,9 +263,13 @@ class OutputFormatter implements WrappableOutputFormatterInterface
}
$lines = explode("\n", $text);
if ($width === $currentLineLength = \strlen(end($lines))) {
foreach ($lines as $line) {
$currentLineLength += \strlen($line);
if ($width <= $currentLineLength) {
$currentLineLength = 0;
}
}
if ($this->isDecorated()) {
foreach ($lines as $i => $line) {
......
......@@ -49,7 +49,13 @@ class QuestionHelper extends Helper
if (!$input->isInteractive()) {
$default = $question->getDefault();
if (null !== $default && $question instanceof ChoiceQuestion) {
if (null === $default) {
return $default;
}
if ($validator = $question->getValidator()) {
return \call_user_func($question->getValidator(), $default);
} elseif ($question instanceof ChoiceQuestion) {
$choices = $question->getChoices();
if (!$question->isMultiselect()) {
......@@ -215,6 +221,7 @@ class QuestionHelper extends Helper
// as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false.
if (false === $c || ('' === $ret && '' === $c && null === $question->getDefault())) {
shell_exec(sprintf('stty %s', $sttyMode));
throw new RuntimeException('Aborted.');
} elseif ("\177" === $c) { // Backspace Character
if (0 === $numMatches && 0 !== $i) {
......
......@@ -13,6 +13,7 @@ namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\WrappableOutputFormatterInterface;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;
......@@ -522,16 +523,20 @@ class Table
// Remove any new line breaks and replace it with a new line
foreach ($rows[$rowKey] as $column => $cell) {
$colspan = $cell instanceof TableCell ? $cell->getColspan() : 1;
if (isset($this->columnMaxWidths[$column]) && Helper::strlenWithoutDecoration($formatter, $cell) > $this->columnMaxWidths[$column]) {
$cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column]);
$cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan);
}
if (!strstr($cell, "\n")) {
continue;
}
$escaped = implode("\n", array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode("\n", $cell)));
$cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped;
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
foreach ($lines as $lineKey => $line) {
if ($cell instanceof TableCell) {
$line = new TableCell($line, ['colspan' => $cell->getColspan()]);
if ($colspan > 1) {
$line = new TableCell($line, ['colspan' => $colspan]);
}
if (0 === $lineKey) {
$rows[$rowKey][$column] = $line;
......
......@@ -41,6 +41,21 @@ class ApplicationTest extends TestCase
{
protected static $fixturesPath;
private $colSize;
protected function setUp()
{
$this->colSize = getenv('COLUMNS');
}
protected function tearDown()
{
putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS');
putenv('SHELL_VERBOSITY');
unset($_ENV['SHELL_VERBOSITY']);
unset($_SERVER['SHELL_VERBOSITY']);
}
public static function setUpBeforeClass()
{
self::$fixturesPath = realpath(__DIR__.'/Fixtures/');
......@@ -384,6 +399,7 @@ class ApplicationTest extends TestCase
*/
public function testFindWithAmbiguousAbbreviations($abbreviation, $expectedExceptionMessage)
{
putenv('COLUMNS=120');
if (method_exists($this, 'expectException')) {
$this->expectException('Symfony\Component\Console\Exception\CommandNotFoundException');
$this->expectExceptionMessage($expectedExceptionMessage);
......@@ -515,6 +531,7 @@ class ApplicationTest extends TestCase
public function testFindAlternativeExceptionMessageMultiple()
{
putenv('COLUMNS=120');
$application = new Application();
$application->add(new \FooCommand());
$application->add(new \Foo1Command());
......@@ -1740,13 +1757,6 @@ class ApplicationTest extends TestCase
$tester = new ApplicationTester($application);
$tester->run(['command' => 'foo']);
}
protected function tearDown()
{
putenv('SHELL_VERBOSITY');
unset($_ENV['SHELL_VERBOSITY']);
unset($_SERVER['SHELL_VERBOSITY']);
}
}
class CustomApplication extends Application
......
......@@ -332,6 +332,9 @@ EOF
$this->assertSame("pre\e[37;41m\e[39;49m\n\e[37;41mfoo\e[39;49m\n\e[37;41mbar\e[39;49m\n\e[37;41mbaz\e[39;49m\npos\nt", $formatter->formatAndWrap('pre <error>foo bar baz</error> post', 3));
$this->assertSame("pre \e[37;41m\e[39;49m\n\e[37;41mfoo \e[39;49m\n\e[37;41mbar \e[39;49m\n\e[37;41mbaz\e[39;49m \npost", $formatter->formatAndWrap('pre <error>foo bar baz</error> post', 4));
$this->assertSame("pre \e[37;41mf\e[39;49m\n\e[37;41moo ba\e[39;49m\n\e[37;41mr baz\e[39;49m\npost", $formatter->formatAndWrap('pre <error>foo bar baz</error> post', 5));
$this->assertSame("Lore\nm \e[37;41mip\e[39;49m\n\e[37;41msum\e[39;49m \ndolo\nr \e[32msi\e[39m\n\e[32mt\e[39m am\net", $formatter->formatAndWrap('Lorem <error>ipsum</error> dolor <info>sit</info> amet', 4));
$this->assertSame("Lorem \e[37;41mip\e[39;49m\n\e[37;41msum\e[39;49m dolo\nr \e[32msit\e[39m am\net", $formatter->formatAndWrap('Lorem <error>ipsum</error> dolor <info>sit</info> amet', 8));
$this->assertSame("Lorem \e[37;41mipsum\e[39;49m dolor \e[32m\e[39m\n\e[32msit\e[39m, \e[37;41mamet\e[39;49m et \e[32mlauda\e[39m\n\e[32mntium\e[39m architecto", $formatter->formatAndWrap('Lorem <error>ipsum</error> dolor <info>sit</info>, <error>amet</error> et <info>laudantium</info> architecto', 18));
$formatter = new OutputFormatter();
......
......@@ -23,6 +23,19 @@ use Symfony\Component\Console\Output\StreamOutput;
*/
class ProgressBarTest extends TestCase
{
private $colSize;
protected function setUp()
{
$this->colSize = getenv('COLUMNS');
putenv('COLUMNS=120');
}
protected function tearDown()
{
putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS');
}
public function testMultipleStart()
{
$bar = new ProgressBar($output = $this->getOutputStream());
......
......@@ -137,6 +137,9 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
$question->setMultiselect(true);
$this->assertNull($questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
$question = new ChoiceQuestion('Who are your favorite superheros?', ['a' => 'Batman', 'b' => 'Superman'], 'a');
$this->assertSame('a', $questionHelper->ask($this->createStreamableInputInterfaceMock('', false), $this->createOutputInterface(), $question), 'ChoiceQuestion validator returns the key if it\'s a string');
try {
$question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, '');
$question->setMultiselect(true);
......
......@@ -1077,6 +1077,26 @@ TABLE;
$this->assertEquals($expected, $this->getOutputContent($output));
}
public function testColumnMaxWidthsWithTrailingBackslash()
{
(new Table($output = $this->getOutputStream()))
->setColumnMaxWidth(0, 5)
->setRows([['1234\6']])
->render()
;
$expected =
<<<'TABLE'
+-------+
| 1234\ |
| 6 |
+-------+
TABLE;
$this->assertEquals($expected, $this->getOutputContent($output));
}
public function testBoxedStyleWithColspan()
{
$boxed = new TableStyle();
......@@ -1124,4 +1144,56 @@ TABLE;
return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
}
public function testWithColspanAndMaxWith(): void
{
$table = new Table($output = $this->getOutputStream());
$table->setColumnMaxWidth(0, 15);
$table->setColumnMaxWidth(1, 15);
$table->setColumnMaxWidth(2, 15);
$table->setRows([
[new TableCell('Lorem ipsum dolor sit amet, <fg=white;bg=green>consectetur</> adipiscing elit, <fg=white;bg=red>sed</> do <fg=white;bg=red>eiusmod</> tempor', ['colspan' => 3])],
new TableSeparator(),
[new TableCell('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor', ['colspan' => 3])],
new TableSeparator(),
[new TableCell('Lorem ipsum <fg=white;bg=red>dolor</> sit amet, consectetur ', ['colspan' => 2]), 'hello world'],
new TableSeparator(),
['hello <fg=white;bg=green>world</>', new TableCell('Lorem ipsum dolor sit amet, <fg=white;bg=green>consectetur</> adipiscing elit', ['colspan' => 2])],
new TableSeparator(),
['hello ', new TableCell('world', ['colspan' => 1]), 'Lorem ipsum dolor sit amet, consectetur'],
new TableSeparator(),
['Symfony ', new TableCell('Test', ['colspan' => 1]), 'Lorem <fg=white;bg=green>ipsum</> dolor sit amet, consectetur'],
])
;
$table->render();
$expected =
<<<TABLE
+-----------------+-----------------+-----------------+
| Lorem ipsum dolor sit amet, consectetur adipi |
| scing elit, sed do eiusmod tempor |
+-----------------+-----------------+-----------------+
| Lorem ipsum dolor sit amet, consectetur adipi |
| scing elit, sed do eiusmod tempor |
+-----------------+-----------------+-----------------+
| Lorem ipsum dolor sit amet, co | hello world |
| nsectetur | |
+-----------------+-----------------+-----------------+
| hello world | Lorem ipsum dolor sit amet, co |
| | nsectetur adipiscing elit |
+-----------------+-----------------+-----------------+
| hello | world | Lorem ipsum dol |
| | | or sit amet, co |
| | | nsectetur |
+-----------------+-----------------+-----------------+
| Symfony | Test | Lorem ipsum dol |
| | | or sit amet, co |
| | | nsectetur |
+-----------------+-----------------+-----------------+
TABLE;
$this->assertSame($expected, $this->getOutputContent($output));
}
}
......@@ -26,9 +26,11 @@ class SymfonyStyleTest extends TestCase
protected $command;
/** @var CommandTester */
protected $tester;
private $colSize;
protected function setUp()
{
$this->colSize = getenv('COLUMNS');
putenv('COLUMNS=121');
$this->command = new Command('sfstyle');
$this->tester = new CommandTester($this->command);
......@@ -36,7 +38,7 @@ class SymfonyStyleTest extends TestCase
protected function tearDown()
{
putenv('COLUMNS');
putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS');
$this->command = null;
$this->tester = null;
}
......
......@@ -16,6 +16,21 @@ use Symfony\Component\Console\Terminal;
class TerminalTest extends TestCase
{
private $colSize;
private $lineSize;
protected function setUp()
{
$this->colSize = getenv('COLUMNS');
$this->lineSize = getenv('LINES');
}
protected function tearDown()
{
putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS');
putenv($this->lineSize ? 'LINES' : 'LINES='.$this->lineSize);
}
public function test()
{
putenv('COLUMNS=100');
......
......@@ -481,7 +481,7 @@ class ErrorHandlerTest extends TestCase
public function testHandleErrorException()
{
$exception = new \Error("Class 'Foo' not found");
$exception = new \Error("Class 'IReallyReallyDoNotExistAnywhereInTheRepositoryISwear' not found");
$handler = new ErrorHandler();
$handler->setExceptionHandler(function () use (&$args) {
......@@ -491,7 +491,7 @@ class ErrorHandlerTest extends TestCase
$handler->handleException($exception);
$this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $args[0]);
$this->assertStringStartsWith("Attempted to load class \"Foo\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage());
$this->assertStringStartsWith("Attempted to load class \"IReallyReallyDoNotExistAnywhereInTheRepositoryISwear\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage());
}
/**
......
......@@ -304,10 +304,6 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
if (null !== $this->logger) {
$this->logger->debug('Notified event "{event}" to listener "{listener}".', $context);
}
if (!isset($this->called[$eventName])) {
$this->called[$eventName] = new \SplObjectStorage();
}
} else {
$this->callStack->detach($listener);
}
......
......@@ -883,6 +883,10 @@ class FinderTest extends Iterator\RealIteratorTestCase
public function testInWithGlobBrace()
{
if (!\defined('GLOB_BRACE')) {
$this->markTestSkipped('Glob brace is not supported on this system.');
}
$finder = $this->buildFinder();
$finder->in([__DIR__.'/Fixtures/{A,copy/A}/B/C'])->getIterator();
......
......@@ -808,6 +808,12 @@ class MimeTypeExtensionGuesser implements ExtensionGuesserInterface
*/
public function guess($mimeType)
{
return isset($this->defaultExtensions[$mimeType]) ? $this->defaultExtensions[$mimeType] : null;
if (isset($this->defaultExtensions[$mimeType])) {
return $this->defaultExtensions[$mimeType];
}
$lcMimeType = strtolower($mimeType);
return isset($this->defaultExtensions[$lcMimeType]) ? $this->defaultExtensions[$lcMimeType] : null;
}
}
......@@ -1214,22 +1214,37 @@ class Request
*/
public function getMethod()
{
if (null === $this->method) {
if (null !== $this->method) {
return $this->method;
}
$this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
if ('POST' === $this->method) {
if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
$this->method = strtoupper($method);
} elseif (self::$httpMethodParameterOverride) {
if ('POST' !== $this->method) {
return $this->method;
}
$method = $this->headers->get('X-HTTP-METHOD-OVERRIDE');
if (!$method && self::$httpMethodParameterOverride) {
$method = $this->request->get('_method', $this->query->get('_method', 'POST'));
if (\is_string($method)) {
$this->method = strtoupper($method);
}
if (!\is_string($method)) {
return $this->method;
}
$method = strtoupper($method);
if (\in_array($method, ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'PATCH', 'PURGE', 'TRACE'], true)) {
return $this->method = $method;
}
if (!preg_match('/^[A-Z]++$/D', $method)) {
throw new SuspiciousOperationException(sprintf('Invalid method override "%s".', $method));
}
return $this->method;
return $this->method = $method;
}
/**
......
......@@ -94,6 +94,18 @@ class UploadedFileTest extends TestCase
$this->assertEquals('jpeg', $file->guessClientExtension());
}
public function testCaseSensitiveMimeType()
{
$file = new UploadedFile(
__DIR__.'/Fixtures/case-sensitive-mime-type.xlsm',
'test.xlsm',
'application/vnd.ms-excel.sheet.macroEnabled.12',
null
);
$this->assertEquals('xlsm', $file->guessClientExtension());
}
public function testErrorIsOkByDefault()
{
$file = new UploadedFile(
......
......@@ -127,9 +127,13 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
return [];
}
if ('' === $logContent = trim(file_get_contents($file))) {
return [];
}
$bootTime = filemtime($file);
$logs = [];
foreach (unserialize(file_get_contents($file)) as $log) {
foreach (unserialize($logContent) as $log) {
$log['context'] = ['exception' => new SilencedErrorContext($log['type'], $log['file'], $log['line'], $log['trace'], $log['count'])];
$log['timestamp'] = $bootTime;
$log['priority'] = 100;
......
......@@ -47,6 +47,7 @@ class TimeDataCollector extends DataCollector implements LateDataCollectorInterf
'token' => $response->headers->get('X-Debug-Token'),
'start_time' => $startTime * 1000,
'events' => [],
'stopwatch_installed' => \class_exists(Stopwatch::class, false),
];
}
......@@ -140,6 +141,14 @@ class TimeDataCollector extends DataCollector implements LateDataCollectorInterf
}
/**
* @return bool whether or not the stopwatch component is installed
*/
public function isStopwatchInstalled()
{
return $this->data['stopwatch_installed'];
}
/**
* {@inheritdoc}
*/
public function getName()
......
......@@ -19,6 +19,7 @@ use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\ExceptionHandler;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\KernelEvents;
......@@ -45,7 +46,7 @@ class DebugHandlersListener implements EventSubscriberInterface
* @param array|int $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants
* @param int|null $throwAt Thrown errors in a bit field of E_* constants, or null to keep the current value
* @param bool $scream Enables/disables screaming mode, where even silenced errors are logged
* @param string|array $fileLinkFormat The format for links to source files
* @param string|FileLinkFormatter|null $fileLinkFormat The format for links to source files
* @param bool $scope Enables/disables scoping mode
*/
public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, ?int $throwAt = E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true)
......
......@@ -40,7 +40,8 @@ class SessionListener extends AbstractSessionListener
if ($this->container->has('session_storage')
&& ($storage = $this->container->get('session_storage')) instanceof NativeSessionStorage
&& $this->container->get('request_stack')->getMasterRequest()->isSecure()
&& ($masterRequest = $this->container->get('request_stack')->getMasterRequest())
&& $masterRequest->isSecure()
) {
$storage->setOptions(['cookie_secure' => true]);
}
......
......@@ -73,11 +73,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
private $requestStackSize = 0;
private $resetServices = false;
const VERSION = '4.2.5';
const VERSION_ID = 40205;
const VERSION = '4.2.7';
const VERSION_ID = 40207;
const MAJOR_VERSION = 4;
const MINOR_VERSION = 2;
const RELEASE_VERSION = 5;
const RELEASE_VERSION = 7;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '07/2019';
......
......@@ -51,21 +51,7 @@
<div id="next">
<h2>What's next?</h2>
<p>
<svg id="icon-book" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="-12.5 9 64 64" enable-background="new -12.5 9 64 64" xml:space="preserve">
<path fill="#AAA" d="M6.8,40.8c2.4,0.8,4.5-0.7,4.9-2.5c0.2-1.2-0.3-2.1-1.3-3.2l-0.8-0.8c-0.4-0.5-0.6-1.3-0.2-1.9
c0.4-0.5,0.9-0.8,1.8-0.5c1.3,0.4,1.9,1.3,2.9,2.2c-0.4,1.4-0.7,2.9-0.9,4.2l-0.2,1c-0.7,4-1.3,6.2-2.7,7.5
c-0.3,0.3-0.7,0.5-1.3,0.6c-0.3,0-0.4-0.3-0.4-0.3c0-0.3,0.2-0.3,0.3-0.4c0.2-0.1,0.5-0.3,0.4-0.8c0-0.7-0.6-1.3-1.3-1.3
c-0.6,0-1.4,0.6-1.4,1.7s1,1.9,2.4,1.8c0.8,0,2.5-0.3,4.2-2.5c2-2.5,2.5-5.4,2.9-7.4l0.5-2.8c0.3,0,0.5,0.1,0.8,0.1
c2.4,0.1,3.7-1.3,3.7-2.3c0-0.6-0.3-1.2-0.9-1.2c-0.4,0-0.8,0.3-1,0.8c-0.1,0.6,0.8,1.1,0.1,1.5c-0.5,0.3-1.4,0.6-2.7,0.4l0.3-1.3
c0.5-2.6,1-5.7,3.2-5.8c0.2,0,0.8,0,0.8,0.4c0,0.2,0,0.2-0.2,0.5c-0.2,0.3-0.3,0.4-0.2,0.7c0,0.7,0.5,1.1,1.2,1.1
c0.9,0,1.2-1,1.2-1.4c0-1.2-1.2-1.8-2.6-1.8c-1.5,0.1-2.8,0.9-3.7,2.1c-1.1,1.3-1.8,2.9-2.3,4.5c-0.9-0.8-1.6-1.8-3.1-2.3
c-1.1-0.7-2.3-0.5-3.4,0.3c-0.5,0.4-0.8,1-1,1.6c-0.4,1.5,0.4,2.9,0.8,3.4l0.9,1c0.2,0.2,0.6,0.8,0.4,1.5c-0.3,0.8-1.2,1.3-2.1,1
c-0.4-0.2-1-0.5-0.9-0.9c0.1-0.2,0.2-0.3,0.3-0.5s0.1-0.3,0.1-0.3c0.2-0.6-0.1-1.4-0.7-1.6c-0.6-0.2-1.2,0-1.3,0.8
C4.3,38.4,4.7,40,6.8,40.8z M46.1,20.9c0-4.2-3.2-7.5-7.1-7.5h-3.8C34.8,10.8,32.7,9,30.2,9L-2.3,9.1c-2.8,0.1-4.9,2.4-4.9,5.4
L-7,58.6c0,4.8,8.1,13.9,11.6,14.1l34.7-0.1c3.9,0,7-3.4,7-7.6L46.1,20.9z M-0.3,36.4c0-8.6,6.5-15.6,14.5-15.6
c8,0,14.5,7,14.5,15.6S22.1,52,14.2,52C6.1,52-0.3,45-0.3,36.4z M42.1,65.1c0,1.8-1.5,3.1-3.1,3.1H4.6c-0.7,0-3-1.8-4.5-4.4h30.4
c2.8,0,5-2.4,5-5.4V17.9h3.7c1.6,0,2.9,1.4,2.9,3.1V65.1L42.1,65.1z"/>
</svg>
<svg id="icon-book" xmlns="http://www.w3.org/2000/svg" viewBox="-12.5 9 64 64"><path fill="#AAA" d="M6.8 40.8c2.4.8 4.5-.7 4.9-2.5.2-1.2-.3-2.1-1.3-3.2l-.8-.8c-.4-.5-.6-1.3-.2-1.9.4-.5.9-.8 1.8-.5 1.3.4 1.9 1.3 2.9 2.2-.4 1.4-.7 2.9-.9 4.2l-.2 1c-.7 4-1.3 6.2-2.7 7.5-.3.3-.7.5-1.3.6-.3 0-.4-.3-.4-.3 0-.3.2-.3.3-.4.2-.1.5-.3.4-.8 0-.7-.6-1.3-1.3-1.3-.6 0-1.4.6-1.4 1.7s1 1.9 2.4 1.8c.8 0 2.5-.3 4.2-2.5 2-2.5 2.5-5.4 2.9-7.4l.5-2.8c.3 0 .5.1.8.1 2.4.1 3.7-1.3 3.7-2.3 0-.6-.3-1.2-.9-1.2-.4 0-.8.3-1 .8-.1.6.8 1.1.1 1.5-.5.3-1.4.6-2.7.4l.3-1.3c.5-2.6 1-5.7 3.2-5.8.2 0 .8 0 .8.4 0 .2 0 .2-.2.5s-.3.4-.2.7c0 .7.5 1.1 1.2 1.1.9 0 1.2-1 1.2-1.4 0-1.2-1.2-1.8-2.6-1.8-1.5.1-2.8.9-3.7 2.1-1.1 1.3-1.8 2.9-2.3 4.5-.9-.8-1.6-1.8-3.1-2.3-1.1-.7-2.3-.5-3.4.3-.5.4-.8 1-1 1.6-.4 1.5.4 2.9.8 3.4l.9 1c.2.2.6.8.4 1.5-.3.8-1.2 1.3-2.1 1-.4-.2-1-.5-.9-.9.1-.2.2-.3.3-.5s.1-.3.1-.3c.2-.6-.1-1.4-.7-1.6-.6-.2-1.2 0-1.3.8 0 .7.4 2.3 2.5 3.1zm39.3-19.9c0-4.2-3.2-7.5-7.1-7.5h-3.8c-.4-2.6-2.5-4.4-5-4.4l-32.5.1c-2.8.1-4.9 2.4-4.9 5.4l.2 44.1c0 4.8 8.1 13.9 11.6 14.1l34.7-.1c3.9 0 7-3.4 7-7.6l-.2-44.1zM-.3 36.4c0-8.6 6.5-15.6 14.5-15.6s14.5 7 14.5 15.6S22.1 52 14.2 52C6.1 52-.3 45-.3 36.4zm42.4 28.7c0 1.8-1.5 3.1-3.1 3.1H4.6c-.7 0-3-1.8-4.5-4.4h30.4c2.8 0 5-2.4 5-5.4V17.9h3.7c1.6 0 2.9 1.4 2.9 3.1v44.1z"/></svg>
Read the documentation to learn
<a href="https://symfony.com/doc/<?php echo $docVersion; ?>/page_creation.html">
......
......@@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\TimeDataCollector;
use Symfony\Component\Stopwatch\Stopwatch;
/**
* @group time-sensitive
......@@ -51,5 +52,6 @@ class TimeDataCollectorTest extends TestCase
$c->collect($request, new Response());
$this->assertEquals(123456000, $c->getStartTime());
$this->assertSame(\class_exists(Stopwatch::class, false), $c->isStopwatchInstalled());
}
}
......@@ -15,8 +15,10 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
......@@ -41,8 +43,16 @@ class SessionListenerTest extends TestCase
{
$session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock();
$requestStack = $this->getMockBuilder(RequestStack::class)->getMock();
$requestStack->expects($this->once())->method('getMasterRequest')->willReturn(null);
$sessionStorage = $this->getMockBuilder(NativeSessionStorage::class)->getMock();
$sessionStorage->expects($this->never())->method('setOptions')->with(['cookie_secure' => true]);
$container = new Container();
$container->set('session', $session);
$container->set('request_stack', $requestStack);
$container->set('session_storage', $sessionStorage);
$request = new Request();
$listener = new SessionListener($container);
......
......@@ -51,7 +51,7 @@ class ExecutableFinder
public function find($name, $default = null, array $extraDirs = [])
{
if (ini_get('open_basedir')) {
$searchPath = explode(PATH_SEPARATOR, ini_get('open_basedir'));
$searchPath = array_merge(explode(PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs);
$dirs = [];
foreach ($searchPath as $path) {
// Silencing against https://bugs.php.net/69240
......
......@@ -196,7 +196,7 @@ abstract class AnnotationClassLoader implements LoaderInterface
continue;
}
foreach ($paths as $locale => $path) {
if (false !== strpos($path, sprintf('{%s}', $param->name))) {
if (preg_match(sprintf('/\{%s(?:<.*?>)?\}/', preg_quote($param->name)), $path)) {
$defaults[$param->name] = $param->getDefaultValue();
break;
}
......
......@@ -131,6 +131,15 @@ trait PhpMatcherTrait
}
$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 ($hasTrailingSlash) {
$matches = $n;
} else {
$hasTrailingVar = false;
}
}
if ('/' !== $pathinfo && !$hasTrailingVar && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {
if ($supportsRedirections && (!$requiredMethods || isset($requiredMethods['GET']))) {
return $allow = $allowSchemes = [];
......@@ -138,10 +147,6 @@ trait PhpMatcherTrait
continue;
}
if ($hasTrailingSlash && $hasTrailingVar && preg_match($regex, $this->matchHost ? $host.'.'.$trimmedPathinfo : $trimmedPathinfo, $n) && $m === (int) $n['MARK']) {
$matches = $n;
}
foreach ($vars as $i => $v) {
if (isset($matches[1 + $i])) {
$ret[$v] = $matches[1 + $i];
......
......@@ -158,6 +158,14 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
$hasTrailingVar = $trimmedPathinfo !== $pathinfo && preg_match('#\{\w+\}/?$#', $route->getPath());
if ($hasTrailingVar && ($hasTrailingSlash || '/' !== substr($matches[(\count($matches) - 1) >> 1], -1)) && preg_match($regex, $trimmedPathinfo, $m)) {
if ($hasTrailingSlash) {
$matches = $m;
} else {
$hasTrailingVar = false;
}
}
if ('/' !== $pathinfo && !$hasTrailingVar && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {
if ($supportsTrailingSlash && (!$requiredMethods || \in_array('GET', $requiredMethods))) {
return $this->allow = $this->allowSchemes = [];
......@@ -166,10 +174,6 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
continue;
}
if ($hasTrailingSlash && $hasTrailingVar && preg_match($regex, $trimmedPathinfo, $m)) {
$matches = $m;
}
$hostMatches = [];
if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
continue;
......
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