From a0ce23885280dff4913dcd0bf112c9565c37781b Mon Sep 17 00:00:00 2001 From: Ash Allen Date: Fri, 1 Apr 2022 18:48:27 +0100 Subject: [PATCH 1/5] [10.x] Added `assertClosurePushed` and `assertClosureNotPushed` (#41713) * Added `assertClosurePushed` and `assertClosureNotPushed`. * Styles updates. * Added docblocks to facade. * Update QueueFake.php Co-authored-by: Taylor Otwell --- src/Illuminate/Support/Facades/Queue.php | 2 ++ .../Support/Testing/Fakes/QueueFake.php | 27 +++++++++++++++++ tests/Support/SupportTestingQueueFakeTest.php | 29 +++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/src/Illuminate/Support/Facades/Queue.php b/src/Illuminate/Support/Facades/Queue.php index 4b67884fd5ab..bb9b356c037d 100755 --- a/src/Illuminate/Support/Facades/Queue.php +++ b/src/Illuminate/Support/Facades/Queue.php @@ -17,8 +17,10 @@ * @method static mixed pushRaw(string $payload, string $queue = null, array $options = []) * @method static string getConnectionName() * @method static void assertNotPushed(string|\Closure $job, callable $callback = null) + * @method static void assertClosureNotPushed(callable $callback = null) * @method static void assertNothingPushed() * @method static void assertPushed(string|\Closure $job, callable|int $callback = null) + * @method static void assertClosurePushed(callable|int $callback = null) * @method static void assertPushedOn(string $queue, string|\Closure $job, callable $callback = null) * @method static void assertPushedWithChain(string $job, array $expectedChain = [], callable $callback = null) * diff --git a/src/Illuminate/Support/Testing/Fakes/QueueFake.php b/src/Illuminate/Support/Testing/Fakes/QueueFake.php index 3e2444ae9e5f..4adff0f3de62 100644 --- a/src/Illuminate/Support/Testing/Fakes/QueueFake.php +++ b/src/Illuminate/Support/Testing/Fakes/QueueFake.php @@ -5,6 +5,7 @@ use BadMethodCallException; use Closure; use Illuminate\Contracts\Queue\Queue; +use Illuminate\Queue\CallQueuedClosure; use Illuminate\Queue\QueueManager; use Illuminate\Support\Collection; use Illuminate\Support\Traits\ReflectsClosures; @@ -201,6 +202,28 @@ protected function assertPushedWithChainOfClasses($job, $expectedChain, $callbac ); } + /** + * Assert if a closure was pushed based on a truth-test callback. + * + * @param callable|int|null $callback + * @return void + */ + public function assertClosurePushed($callback = null) + { + $this->assertPushed(CallQueuedClosure::class, $callback); + } + + /** + * Assert that a closure was not pushed based on a truth-test callback. + * + * @param callable|null $callback + * @return void + */ + public function assertClosureNotPushed($callback = null) + { + $this->assertNotPushed(CallQueuedClosure::class, $callback); + } + /** * Determine if the given chain is entirely composed of objects. * @@ -311,6 +334,10 @@ public function size($queue = null) public function push($job, $data = '', $queue = null) { if ($this->shouldFakeJob($job)) { + if ($job instanceof Closure) { + $job = CallQueuedClosure::create($job); + } + $this->jobs[is_object($job) ? get_class($job) : $job][] = [ 'job' => $job, 'queue' => $queue, diff --git a/tests/Support/SupportTestingQueueFakeTest.php b/tests/Support/SupportTestingQueueFakeTest.php index 049482452aaa..060bb47cdece 100644 --- a/tests/Support/SupportTestingQueueFakeTest.php +++ b/tests/Support/SupportTestingQueueFakeTest.php @@ -314,6 +314,35 @@ public function testCallUndefinedMethodErrorHandling() ))); } } + + public function testAssertClosurePushed() + { + $this->fake->push(function () { + // Do nothing + }); + + $this->fake->assertClosurePushed(); + } + + public function testAssertClosurePushedWithTimes() + { + $this->fake->push(function () { + // Do nothing + }); + + $this->fake->push(function () { + // Do nothing + }); + + $this->fake->assertClosurePushed(2); + } + + public function testAssertClosureNotPushed() + { + $this->fake->push($this->job); + + $this->fake->assertClosureNotPushed(); + } } class JobStub From 35736731d08cea06b6e317b8e8f0a86da5c2ea5d Mon Sep 17 00:00:00 2001 From: Andrew Bashtannik Date: Mon, 28 Mar 2022 18:57:33 +0300 Subject: [PATCH 2/5] [9.x] Add exclude_with validation rule (#41691) * Add exclude_with validation rule (#41686) * Fix code style --- .../Concerns/ValidatesAttributes.php | 19 ++++++++++++++++++ src/Illuminate/Validation/Validator.php | 3 ++- tests/Validation/ValidationValidatorTest.php | 20 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php index 544c3ce01242..8eaff396eae9 100644 --- a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php @@ -1687,6 +1687,25 @@ public function validateRequiredUnless($attribute, $value, $parameters) return true; } + /** + * Indicate that an attribute should be excluded when another attribute presents. + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + public function validateExcludeWith($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'exclude_with'); + + if (! Arr::has($this->data, $parameters[0])) { + return true; + } + + return false; + } + /** * Indicate that an attribute should be excluded when another attribute is missing. * diff --git a/src/Illuminate/Validation/Validator.php b/src/Illuminate/Validation/Validator.php index ba8ac8f39a49..c085d00ec5f3 100644 --- a/src/Illuminate/Validation/Validator.php +++ b/src/Illuminate/Validation/Validator.php @@ -231,6 +231,7 @@ class Validator implements ValidatorContract 'Different', 'ExcludeIf', 'ExcludeUnless', + 'ExcludeWith', 'ExcludeWithout', 'Gt', 'Gte', @@ -257,7 +258,7 @@ class Validator implements ValidatorContract * * @var string[] */ - protected $excludeRules = ['Exclude', 'ExcludeIf', 'ExcludeUnless', 'ExcludeWithout']; + protected $excludeRules = ['Exclude', 'ExcludeIf', 'ExcludeUnless', 'ExcludeWith', 'ExcludeWithout']; /** * The size related validation rules. diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index 009b776add20..57db1f7aaabd 100644 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -7013,6 +7013,26 @@ public function testExcludeValuesAreReallyRemoved() $this->assertSame(['mouse' => null], $validator->invalid()); } + public function testExcludeWithValuesAreReallyRemoved() + { + $validator = new Validator( + $this->getIlluminateArrayTranslator(), + [ + 'cat' => 'Tom', + 'mouse' => 'Jerry', + ], + [ + 'cat' => 'string', + 'mouse' => 'string|exclude_with:cat', + ] + ); + + $this->assertTrue($validator->passes()); + $this->assertSame(['cat' => 'Tom'], $validator->validated()); + $this->assertSame(['cat' => 'Tom'], $validator->valid()); + $this->assertSame([], $validator->invalid()); + } + public function testValidateFailsWithAsterisksAsDataKeys() { $post = ['data' => [0 => ['date' => '2019-01-24'], 1 => ['date' => 'blah'], '*' => ['date' => 'blah']]]; From 4a70dd18c0f340fe4e29f69936b46337b140e4ff Mon Sep 17 00:00:00 2001 From: Dwight Watson Date: Mon, 4 Apr 2022 01:14:41 +1000 Subject: [PATCH 3/5] [9.x] Add String::squish() helper (#41791) * Add squish helper * Additional test case * Add squish to Stringable * Fix code formatting * Make more consistent * formatting Co-authored-by: Taylor Otwell --- src/Illuminate/Support/Str.php | 11 +++++++++++ src/Illuminate/Support/Stringable.php | 10 ++++++++++ tests/Support/SupportStrTest.php | 11 +++++++++++ tests/Support/SupportStringableTest.php | 11 +++++++++++ 4 files changed, 43 insertions(+) diff --git a/src/Illuminate/Support/Str.php b/src/Illuminate/Support/Str.php index 03513ef37a54..7e884ee44dd3 100644 --- a/src/Illuminate/Support/Str.php +++ b/src/Illuminate/Support/Str.php @@ -897,6 +897,17 @@ public static function snake($value, $delimiter = '_') return static::$snakeCache[$key][$delimiter] = $value; } + /** + * Remove all "extra" blank space from the given string. + * + * @param string $value + * @return string + */ + public static function squish($value) + { + return preg_replace('/\s+/', ' ', trim($value)); + } + /** * Determine if a given string starts with a given substring. * diff --git a/src/Illuminate/Support/Stringable.php b/src/Illuminate/Support/Stringable.php index 184d4e8c003e..345c6164b2a6 100644 --- a/src/Illuminate/Support/Stringable.php +++ b/src/Illuminate/Support/Stringable.php @@ -626,6 +626,16 @@ public function scan($format) return collect(sscanf($this->value, $format)); } + /** + * Remove all "extra" blank space from the given string. + * + * @return static + */ + public function squish() + { + return new static(Str::squish($this->value)); + } + /** * Begin a string with a single instance of a given value. * diff --git a/tests/Support/SupportStrTest.php b/tests/Support/SupportStrTest.php index f18051a62816..de19d8ed7ff6 100644 --- a/tests/Support/SupportStrTest.php +++ b/tests/Support/SupportStrTest.php @@ -540,6 +540,17 @@ public function testSnake() $this->assertSame('żółtałódka', Str::snake('ŻółtaŁódka')); } + public function testSquish() + { + $this->assertSame('laravel php framework', Str::squish(' laravel php framework ')); + $this->assertSame('laravel php framework', Str::squish("laravel\t\tphp\n\nframework")); + $this->assertSame('laravel php framework', Str::squish(' + laravel + php + framework + ')); + } + public function testStudly() { $this->assertSame('LaravelPHPFramework', Str::studly('laravel_p_h_p_framework')); diff --git a/tests/Support/SupportStringableTest.php b/tests/Support/SupportStringableTest.php index 7786f2a66117..f3480970b779 100644 --- a/tests/Support/SupportStringableTest.php +++ b/tests/Support/SupportStringableTest.php @@ -611,6 +611,17 @@ public function testSlug() $this->assertSame('', (string) $this->stringable('')->slug()); } + public function testSquish() + { + $this->assertSame('words with spaces', (string) $this->stringable(' words with spaces ')->squish()); + $this->assertSame('words with spaces', (string) $this->stringable("words\t\twith\n\nspaces")->squish()); + $this->assertSame('words with spaces', (string) $this->stringable(' + words + with + spaces + ')->squish()); + } + public function testStart() { $this->assertSame('/test/string', (string) $this->stringable('test/string')->start('/')); From f891d808d6cce548be4d770d0095e93cf98b4697 Mon Sep 17 00:00:00 2001 From: "OMAR.A" <58332033+civilcoder55@users.noreply.github.com> Date: Mon, 4 Apr 2022 18:12:30 +0200 Subject: [PATCH 4/5] =?UTF-8?q?[9.x]=20Enable=20dispatchAfterResponse=20fo?= =?UTF-8?q?r=20batch=20=F0=9F=94=A5=20(#41787)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [9.x] Enable dispatchAfterResponse for batch 🔥 [before] batch can't be dispatched after response sent to user. [after] batch can be dipatched and all jobs will be saved to storage after response. - added dispatchAfterResponse method to: 1- store batch itself into database 2- register a terminating callback to dispatch batch jobs 3- return created batch - added private dispatchAlreadyCreated method to: 1- dispatch batch jobs and fire BatchDispatched event like before but without creating batch because we already created it in dispatchAfterResponse * formatting Co-authored-by: Taylor Otwell --- src/Illuminate/Bus/PendingBatch.php | 45 +++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/Illuminate/Bus/PendingBatch.php b/src/Illuminate/Bus/PendingBatch.php index 8e784c2a58e6..95c763d87c8a 100644 --- a/src/Illuminate/Bus/PendingBatch.php +++ b/src/Illuminate/Bus/PendingBatch.php @@ -282,4 +282,49 @@ public function dispatch() return $batch; } + + /** + * Dispatch the batch after the response is sent to the browser. + * + * @return \Illuminate\Bus\Batch + */ + public function dispatchAfterResponse() + { + $repository = $this->container->make(BatchRepository::class); + + $batch = $repository->store($this); + + if ($batch) { + $this->container->terminating(function () use ($batch) { + $this->dispatchExistingBatch($batch); + }); + } + + return $batch; + } + + /** + * Dispatch an existing batch. + * + * @param \Illuminate\Bus\Batch $batch + * @return void + * + * @throws \Throwable + */ + protected function dispatchExistingBatch($batch) + { + try { + $batch = $batch->add($this->jobs); + } catch (Throwable $e) { + if (isset($batch)) { + $batch->delete(); + } + + throw $e; + } + + $this->container->make(EventDispatcher::class)->dispatch( + new BatchDispatched($batch) + ); + } } From 147f19be67e957d7458ee711c43802d1fc39c5eb Mon Sep 17 00:00:00 2001 From: Saya Date: Tue, 5 Apr 2022 10:40:40 +0800 Subject: [PATCH 5/5] bc --- src/Illuminate/Bus/PendingBatch.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Illuminate/Bus/PendingBatch.php b/src/Illuminate/Bus/PendingBatch.php index 95c763d87c8a..8c95528709df 100644 --- a/src/Illuminate/Bus/PendingBatch.php +++ b/src/Illuminate/Bus/PendingBatch.php @@ -315,7 +315,12 @@ protected function dispatchExistingBatch($batch) { try { $batch = $batch->add($this->jobs); + } catch (\Exception $e) { + } catch (\Error $e) { } catch (Throwable $e) { + } + + if (isset($e)) { if (isset($batch)) { $batch->delete(); }