From 28481951106e75cf8c5a8b24100059fa327df1ef Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Fri, 15 Jan 2021 09:38:30 -0600 Subject: [PATCH 01/22] version --- src/Illuminate/Foundation/Application.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index 34523e48057e..1dc26d3e3d16 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -33,7 +33,7 @@ class Application extends Container implements ApplicationContract, CachesConfig * * @var string */ - const VERSION = '7.30.2'; + const VERSION = '7.30.3'; /** * The base path for the Laravel installation. From cc526911b5dc830a39a4039828b871dbeca36ea4 Mon Sep 17 00:00:00 2001 From: Tetiana Blindaruk Date: Tue, 19 Jan 2021 19:46:10 +0200 Subject: [PATCH 02/22] [6.x] update changelog --- CHANGELOG-6.x.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-6.x.md b/CHANGELOG-6.x.md index 3ab00165cccc..570c2d5b9317 100644 --- a/CHANGELOG-6.x.md +++ b/CHANGELOG-6.x.md @@ -1,6 +1,12 @@ # Release Notes for 6.x -## [Unreleased](https://github.com/laravel/framework/compare/v6.20.10...6.x) +## [Unreleased](https://github.com/laravel/framework/compare/v6.20.11...6.x) + + +## [v6.20.11 (2021-01-19)](https://github.com/laravel/framework/compare/v6.20.10...v6.20.11) + +### Fixed +- Limit expected bindings ([#35865](https://github.com/laravel/framework/pull/35865)) ## [v6.20.10 (2021-01-12)](https://github.com/laravel/framework/compare/v6.20.9...v6.20.10) From 19aeb79014b05b76f9e5e016a24f8bd78b59d209 Mon Sep 17 00:00:00 2001 From: Tetiana Blindaruk Date: Tue, 19 Jan 2021 19:49:41 +0200 Subject: [PATCH 03/22] [6.x] update changelog --- CHANGELOG-6.x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG-6.x.md b/CHANGELOG-6.x.md index 570c2d5b9317..ae2f901c392d 100644 --- a/CHANGELOG-6.x.md +++ b/CHANGELOG-6.x.md @@ -3,7 +3,7 @@ ## [Unreleased](https://github.com/laravel/framework/compare/v6.20.11...6.x) -## [v6.20.11 (2021-01-19)](https://github.com/laravel/framework/compare/v6.20.10...v6.20.11) +## [v6.20.11 (2021-01-13)](https://github.com/laravel/framework/compare/v6.20.10...v6.20.11) ### Fixed - Limit expected bindings ([#35865](https://github.com/laravel/framework/pull/35865)) From 45c230e5db764c2cdfd3554131c3d3fc08fd4812 Mon Sep 17 00:00:00 2001 From: Tetiana Blindaruk Date: Tue, 19 Jan 2021 20:02:19 +0200 Subject: [PATCH 04/22] [7.x] update changelog --- CHANGELOG-7.x.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-7.x.md b/CHANGELOG-7.x.md index 2a0534809019..bb6656470920 100644 --- a/CHANGELOG-7.x.md +++ b/CHANGELOG-7.x.md @@ -1,6 +1,19 @@ # Release Notes for 7.x -## [Unreleased](https://github.com/laravel/framework/compare/v7.30.1...7.x) +## [Unreleased](https://github.com/laravel/framework/compare/v7.30.2...7.x) + + +## [v7.30.2 (2021-01-13)](https://github.com/laravel/framework/compare/v7.30.1...v7.30.2) + +### Added +- Added strings to `DetectsLostConnections` ([#35752](https://github.com/laravel/framework/pull/35752)) + +### Fixed +- Fixed error from missing null check on PHP 8 ([#35797](https://github.com/laravel/framework/pull/35797)) +- Limit expected bindings ([#35865](https://github.com/laravel/framework/pull/35865)) + +### Changed +- Retry connection if DNS lookup fails ([#35790](https://github.com/laravel/framework/pull/35790)) ## [v7.30.1 (2020-12-22)](https://github.com/laravel/framework/compare/v7.30.0...v7.30.1) From 80210553c1f88e7ca4b279364c003970b2824076 Mon Sep 17 00:00:00 2001 From: Tetiana Blindaruk Date: Tue, 19 Jan 2021 20:07:06 +0200 Subject: [PATCH 05/22] [8.x] update changelog --- CHANGELOG-8.x.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-8.x.md b/CHANGELOG-8.x.md index 6879551e0a1e..e049474c09b3 100644 --- a/CHANGELOG-8.x.md +++ b/CHANGELOG-8.x.md @@ -1,6 +1,12 @@ # Release Notes for 8.x -## [Unreleased](https://github.com/laravel/framework/compare/v8.22.0...8.x) +## [Unreleased](https://github.com/laravel/framework/compare/v8.22.1...8.x) + + +## [v8.22.1 (2021-01-13)](https://github.com/laravel/framework/compare/v8.22.0...v8.22.1) + +### Fixed +- Limit expected bindings ([#35865](https://github.com/laravel/framework/pull/35865)) ## [v8.22.0 (2021-01-12)](https://github.com/laravel/framework/compare/v8.21.0...v8.22.0) From e4be180ad35a378b8e59e4c0236567995851a3f8 Mon Sep 17 00:00:00 2001 From: Tetiana Blindaruk Date: Tue, 19 Jan 2021 20:10:30 +0200 Subject: [PATCH 06/22] [6.x] update changelog --- CHANGELOG-6.x.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-6.x.md b/CHANGELOG-6.x.md index ae2f901c392d..00a6d2154eea 100644 --- a/CHANGELOG-6.x.md +++ b/CHANGELOG-6.x.md @@ -1,6 +1,9 @@ # Release Notes for 6.x -## [Unreleased](https://github.com/laravel/framework/compare/v6.20.11...6.x) +## [Unreleased](https://github.com/laravel/framework/compare/v6.20.12...6.x) + + +## [v6.20.12 (2021-01-13)](https://github.com/laravel/framework/compare/v6.20.11...v6.20.12) ## [v6.20.11 (2021-01-13)](https://github.com/laravel/framework/compare/v6.20.10...v6.20.11) From 57d148dc399ca192e59f0712875194f57ec768f5 Mon Sep 17 00:00:00 2001 From: Tetiana Blindaruk Date: Tue, 19 Jan 2021 20:13:17 +0200 Subject: [PATCH 07/22] [7.x] update changelog --- CHANGELOG-7.x.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-7.x.md b/CHANGELOG-7.x.md index bb6656470920..36d7fe5e06fc 100644 --- a/CHANGELOG-7.x.md +++ b/CHANGELOG-7.x.md @@ -1,6 +1,9 @@ # Release Notes for 7.x -## [Unreleased](https://github.com/laravel/framework/compare/v7.30.2...7.x) +## [Unreleased](https://github.com/laravel/framework/compare/v7.30.3...7.x) + + +## [v7.30.3 (2021-01-15)](https://github.com/laravel/framework/compare/v7.30.2...v7.30.3) ## [v7.30.2 (2021-01-13)](https://github.com/laravel/framework/compare/v7.30.1...v7.30.2) From f0dc53f3641b51373cc06e5ca3bcf8549c8186dd Mon Sep 17 00:00:00 2001 From: Tetiana Blindaruk Date: Tue, 19 Jan 2021 20:16:32 +0200 Subject: [PATCH 08/22] [6.x] update changelog --- CHANGELOG-6.x.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-6.x.md b/CHANGELOG-6.x.md index 00a6d2154eea..42350000b97c 100644 --- a/CHANGELOG-6.x.md +++ b/CHANGELOG-6.x.md @@ -1,6 +1,12 @@ # Release Notes for 6.x -## [Unreleased](https://github.com/laravel/framework/compare/v6.20.12...6.x) +## [Unreleased](https://github.com/laravel/framework/compare/v6.20.13...6.x) + + +## [v6.20.13 (2021-01-19)](https://github.com/laravel/framework/compare/v6.20.12...v6.20.13) + +### Fixed +- Fixed empty html mail ([#35941](https://github.com/laravel/framework/pull/35941)) ## [v6.20.12 (2021-01-13)](https://github.com/laravel/framework/compare/v6.20.11...v6.20.12) From e6b4974a323cfebe915324d192e5c296c1fa13a4 Mon Sep 17 00:00:00 2001 From: Tetiana Blindaruk Date: Tue, 19 Jan 2021 20:41:58 +0200 Subject: [PATCH 09/22] [8.x] update changelog --- CHANGELOG-8.x.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-8.x.md b/CHANGELOG-8.x.md index e049474c09b3..bbacb405f40f 100644 --- a/CHANGELOG-8.x.md +++ b/CHANGELOG-8.x.md @@ -1,6 +1,22 @@ # Release Notes for 8.x -## [Unreleased](https://github.com/laravel/framework/compare/v8.22.1...8.x) +## [Unreleased](https://github.com/laravel/framework/compare/v8.23.0...8.x) + + +## [v8.23.0 (2021-01-19)](https://github.com/laravel/framework/compare/v8.22.1...v8.23.0) + +### Added +- Added `Illuminate\Database\Concerns\BuildsQueries::sole()` ([#35869](https://github.com/laravel/framework/pull/35869), [29c7dae](https://github.com/laravel/framework/commit/29c7dae9b32af2abffa7489f4758fd67905683c3), [#35908](https://github.com/laravel/framework/pull/35908), [#35902](https://github.com/laravel/framework/pull/35902), [#35912](https://github.com/laravel/framework/pull/35912)) +- Added default parameter to throw_if / throw_unless ([#35890](https://github.com/laravel/framework/pull/35890)) +- Added validation support for TeamSpeak3 URI scheme ([#35933](https://github.com/laravel/framework/pull/35933)) + +### Fixed +- Fixed extra space on blade class components that are inline ([#35874](https://github.com/laravel/framework/pull/35874)) +- Fixed serialization of rate limited middleware ([f3d4dcb](https://github.com/laravel/framework/commit/f3d4dcb21dc66824611fdde95c8075b694825bf5), [#35916](https://github.com/laravel/framework/pull/35916)) + +### Changed +- Allow a specific seeder to be used in tests in `Illuminate\Foundation\Testing\RefreshDatabase::migrateFreshUsing()` ([#35864](https://github.com/laravel/framework/pull/35864)) +- Pass $key to closure in Collection and LazyCollection's reduce method as well ([#35878](https://github.com/laravel/framework/pull/35878)) ## [v8.22.1 (2021-01-13)](https://github.com/laravel/framework/compare/v8.22.0...v8.22.1) From 208c3976f186dcdfa0a434f4092bae7d32928465 Mon Sep 17 00:00:00 2001 From: Tetiana Blindaruk Date: Tue, 19 Jan 2021 20:44:27 +0200 Subject: [PATCH 10/22] [8.x] update changelog --- CHANGELOG-8.x.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-8.x.md b/CHANGELOG-8.x.md index bbacb405f40f..f1e61cd5215f 100644 --- a/CHANGELOG-8.x.md +++ b/CHANGELOG-8.x.md @@ -1,6 +1,12 @@ # Release Notes for 8.x -## [Unreleased](https://github.com/laravel/framework/compare/v8.23.0...8.x) +## [Unreleased](https://github.com/laravel/framework/compare/v8.23.1...8.x) + + +## [v8.23.1 (2021-01-19)](https://github.com/laravel/framework/compare/v8.23.0...v8.23.1) + +### Fixed +- Fixed empty html mail ([#35941](https://github.com/laravel/framework/pull/35941)) ## [v8.23.0 (2021-01-19)](https://github.com/laravel/framework/compare/v8.22.1...v8.23.0) From d08fd806337d991ea14e578a9c85b2f6d4ae990e Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Wed, 20 Jan 2021 13:50:36 +0000 Subject: [PATCH 11/22] Fixed type error (#35956) --- src/Illuminate/Http/Concerns/InteractsWithContentTypes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Http/Concerns/InteractsWithContentTypes.php b/src/Illuminate/Http/Concerns/InteractsWithContentTypes.php index be760a2619d9..25d6ec1e9986 100644 --- a/src/Illuminate/Http/Concerns/InteractsWithContentTypes.php +++ b/src/Illuminate/Http/Concerns/InteractsWithContentTypes.php @@ -31,7 +31,7 @@ public static function matchesType($actual, $type) */ public function isJson() { - return Str::contains($this->header('CONTENT_TYPE'), ['/json', '+json']); + return Str::contains($this->header('CONTENT_TYPE') ?? '', ['/json', '+json']); } /** From fa61b374655f465793feb29a49fbeec9c7878081 Mon Sep 17 00:00:00 2001 From: Andrew Nagy Date: Wed, 20 Jan 2021 06:16:15 -0800 Subject: [PATCH 12/22] Fixes #35947 (#35950) This fixes #35947. Since collections can deal with objects then the method sortByMany taken from Arr should be able to deal with objects as well --- src/Illuminate/Collections/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Collections/Collection.php b/src/Illuminate/Collections/Collection.php index e4549d03ed11..beaac46fe280 100644 --- a/src/Illuminate/Collections/Collection.php +++ b/src/Illuminate/Collections/Collection.php @@ -1168,7 +1168,7 @@ protected function sortByMany(array $comparisons = []) if (is_callable($prop)) { $result = $prop($a, $b); } else { - $values = [Arr::get($a, $prop), Arr::get($b, $prop)]; + $values = [data_get($a, $prop), data_get($b, $prop)]; if (! $ascending) { $values = array_reverse($values); From 9f0180f154fe14cc6d4a2a00b1fc25a684469152 Mon Sep 17 00:00:00 2001 From: Choraimy Kroonstuiver <3661474+axlon@users.noreply.github.com> Date: Wed, 20 Jan 2021 15:18:13 +0100 Subject: [PATCH 13/22] Change cache lock block method return to mixed (#35961) --- src/Illuminate/Cache/Lock.php | 2 +- src/Illuminate/Contracts/Cache/Lock.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Cache/Lock.php b/src/Illuminate/Cache/Lock.php index 271cba50fc58..eb035161ba87 100644 --- a/src/Illuminate/Cache/Lock.php +++ b/src/Illuminate/Cache/Lock.php @@ -105,7 +105,7 @@ public function get($callback = null) * * @param int $seconds * @param callable|null $callback - * @return bool + * @return mixed * * @throws \Illuminate\Contracts\Cache\LockTimeoutException */ diff --git a/src/Illuminate/Contracts/Cache/Lock.php b/src/Illuminate/Contracts/Cache/Lock.php index 7f01b1be3f33..03f633a07a21 100644 --- a/src/Illuminate/Contracts/Cache/Lock.php +++ b/src/Illuminate/Contracts/Cache/Lock.php @@ -17,7 +17,7 @@ public function get($callback = null); * * @param int $seconds * @param callable|null $callback - * @return bool + * @return mixed */ public function block($seconds, $callback = null); From 8eaec037421aa9f3860da9d339986448b4c884eb Mon Sep 17 00:00:00 2001 From: vdauchy <26772554+vdauchy@users.noreply.github.com> Date: Tue, 19 Jan 2021 14:28:18 -0500 Subject: [PATCH 14/22] Add JobQueued event (Follows: https://github.com/laravel/framework/pull/32894) --- src/Illuminate/Queue/Events/JobQueued.php | 29 ++++++++ src/Illuminate/Queue/Queue.php | 25 ++++++- tests/Queue/QueueBeanstalkdQueueTest.php | 65 ++++++++++++------ tests/Queue/QueueDatabaseQueueUnitTest.php | 7 ++ tests/Queue/QueueRedisQueueTest.php | 11 +++ tests/Queue/QueueSqsQueueTest.php | 6 ++ tests/Queue/RedisQueueIntegrationTest.php | 78 +++++++++++++++++++--- 7 files changed, 191 insertions(+), 30 deletions(-) create mode 100644 src/Illuminate/Queue/Events/JobQueued.php diff --git a/src/Illuminate/Queue/Events/JobQueued.php b/src/Illuminate/Queue/Events/JobQueued.php new file mode 100644 index 000000000000..4568cd922fb0 --- /dev/null +++ b/src/Illuminate/Queue/Events/JobQueued.php @@ -0,0 +1,29 @@ +jobId = $jobId; + $this->job = $job; + } +} diff --git a/src/Illuminate/Queue/Queue.php b/src/Illuminate/Queue/Queue.php index b22ed51cd446..bfe8baec8507 100755 --- a/src/Illuminate/Queue/Queue.php +++ b/src/Illuminate/Queue/Queue.php @@ -7,6 +7,7 @@ use Illuminate\Container\Container; use Illuminate\Contracts\Encryption\Encrypter; use Illuminate\Contracts\Queue\ShouldBeEncrypted; +use Illuminate\Queue\Events\JobQueued; use Illuminate\Support\Arr; use Illuminate\Support\InteractsWithTime; use Illuminate\Support\Str; @@ -284,13 +285,17 @@ protected function enqueueUsing($job, $payload, $queue, $delay, $callback) if ($this->shouldDispatchAfterCommit($job) && $this->container->bound('db.transactions')) { return $this->container->make('db.transactions')->addCallback( - function () use ($payload, $queue, $delay, $callback) { - return $callback($payload, $queue, $delay); + function () use ($payload, $queue, $delay, $callback, $job) { + return tap($callback($payload, $queue, $delay), function ($jobId) use ($job) { + $this->raiseJobQueuedEvent($jobId, $job); + }); } ); } - return $callback($payload, $queue, $delay); + return tap($callback($payload, $queue, $delay), function ($jobId) use ($job) { + $this->raiseJobQueuedEvent($jobId, $job); + }); } /** @@ -345,4 +350,18 @@ public function setContainer(Container $container) { $this->container = $container; } + + /** + * Raise the job queued event. + * + * @param string|int|null $jobId + * @param \Closure|string|object $job + * @return void + */ + protected function raiseJobQueuedEvent($jobId, $job) + { + if ($this->container->bound('events')) { + $this->container['events']->dispatch(new JobQueued($jobId, $job)); + } + } } diff --git a/tests/Queue/QueueBeanstalkdQueueTest.php b/tests/Queue/QueueBeanstalkdQueueTest.php index 7134917a2369..534a16141381 100755 --- a/tests/Queue/QueueBeanstalkdQueueTest.php +++ b/tests/Queue/QueueBeanstalkdQueueTest.php @@ -13,6 +13,16 @@ class QueueBeanstalkdQueueTest extends TestCase { + /** + * @var BeanstalkdQueue + */ + private $queue; + + /** + * @var Container|m\LegacyMockInterface|m\MockInterface + */ + private $container; + protected function tearDown(): void { m::close(); @@ -26,14 +36,16 @@ public function testPushProperlyPushesJobOntoBeanstalkd() return $uuid; }); - $queue = new BeanstalkdQueue(m::mock(Pheanstalk::class), 'default', 60); - $pheanstalk = $queue->getPheanstalk(); + $this->setQueue('default', 60); + $pheanstalk = $this->queue->getPheanstalk(); $pheanstalk->shouldReceive('useTube')->once()->with('stack')->andReturn($pheanstalk); $pheanstalk->shouldReceive('useTube')->once()->with('default')->andReturn($pheanstalk); $pheanstalk->shouldReceive('put')->twice()->with(json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'backoff' => null, 'timeout' => null, 'data' => ['data']]), 1024, 0, 60); - $queue->push('foo', ['data'], 'stack'); - $queue->push('foo', ['data']); + $this->queue->push('foo', ['data'], 'stack'); + $this->queue->push('foo', ['data']); + + $this->container->shouldHaveReceived('bound')->with('events')->times(2); Str::createUuidsNormally(); } @@ -46,53 +58,68 @@ public function testDelayedPushProperlyPushesJobOntoBeanstalkd() return $uuid; }); - $queue = new BeanstalkdQueue(m::mock(Pheanstalk::class), 'default', 60); - $pheanstalk = $queue->getPheanstalk(); + $this->setQueue('default', 60); + $pheanstalk = $this->queue->getPheanstalk(); $pheanstalk->shouldReceive('useTube')->once()->with('stack')->andReturn($pheanstalk); $pheanstalk->shouldReceive('useTube')->once()->with('default')->andReturn($pheanstalk); $pheanstalk->shouldReceive('put')->twice()->with(json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'backoff' => null, 'timeout' => null, 'data' => ['data']]), Pheanstalk::DEFAULT_PRIORITY, 5, Pheanstalk::DEFAULT_TTR); - $queue->later(5, 'foo', ['data'], 'stack'); - $queue->later(5, 'foo', ['data']); + $this->queue->later(5, 'foo', ['data'], 'stack'); + $this->queue->later(5, 'foo', ['data']); + + $this->container->shouldHaveReceived('bound')->with('events')->times(2); Str::createUuidsNormally(); } public function testPopProperlyPopsJobOffOfBeanstalkd() { - $queue = new BeanstalkdQueue(m::mock(Pheanstalk::class), 'default', 60); - $queue->setContainer(m::mock(Container::class)); - $pheanstalk = $queue->getPheanstalk(); + $this->setQueue('default', 60); + + $pheanstalk = $this->queue->getPheanstalk(); $pheanstalk->shouldReceive('watchOnly')->once()->with('default')->andReturn($pheanstalk); $job = m::mock(Job::class); $pheanstalk->shouldReceive('reserveWithTimeout')->once()->with(0)->andReturn($job); - $result = $queue->pop(); + $result = $this->queue->pop(); $this->assertInstanceOf(BeanstalkdJob::class, $result); } public function testBlockingPopProperlyPopsJobOffOfBeanstalkd() { - $queue = new BeanstalkdQueue(m::mock(Pheanstalk::class), 'default', 60, 60); - $queue->setContainer(m::mock(Container::class)); - $pheanstalk = $queue->getPheanstalk(); + $this->setQueue('default', 60, 60); + + $pheanstalk = $this->queue->getPheanstalk(); $pheanstalk->shouldReceive('watchOnly')->once()->with('default')->andReturn($pheanstalk); $job = m::mock(Job::class); $pheanstalk->shouldReceive('reserveWithTimeout')->once()->with(60)->andReturn($job); - $result = $queue->pop(); + $result = $this->queue->pop(); $this->assertInstanceOf(BeanstalkdJob::class, $result); } public function testDeleteProperlyRemoveJobsOffBeanstalkd() { - $queue = new BeanstalkdQueue(m::mock(Pheanstalk::class), 'default', 60); - $pheanstalk = $queue->getPheanstalk(); + $this->setQueue('default', 60); + + $pheanstalk = $this->queue->getPheanstalk(); $pheanstalk->shouldReceive('useTube')->once()->with('default')->andReturn($pheanstalk); $pheanstalk->shouldReceive('delete')->once()->with(m::type(Job::class)); - $queue->deleteMessage('default', 1); + $this->queue->deleteMessage('default', 1); + } + + /** + * @param string $default + * @param int $timeToRun + * @param int $blockFor + */ + private function setQueue($default, $timeToRun, $blockFor = 0) + { + $this->queue = new BeanstalkdQueue(m::mock(Pheanstalk::class), $default, $timeToRun, $blockFor); + $this->container = m::spy(Container::class); + $this->queue->setContainer($this->container); } } diff --git a/tests/Queue/QueueDatabaseQueueUnitTest.php b/tests/Queue/QueueDatabaseQueueUnitTest.php index 6fa35eca5708..c87dc754545b 100644 --- a/tests/Queue/QueueDatabaseQueueUnitTest.php +++ b/tests/Queue/QueueDatabaseQueueUnitTest.php @@ -2,6 +2,7 @@ namespace Illuminate\Tests\Queue; +use Illuminate\Container\Container; use Illuminate\Database\Connection; use Illuminate\Queue\DatabaseQueue; use Illuminate\Queue\Queue; @@ -28,6 +29,7 @@ public function testPushProperlyPushesJobOntoDatabase() $queue = $this->getMockBuilder(DatabaseQueue::class)->onlyMethods(['currentTime'])->setConstructorArgs([$database = m::mock(Connection::class), 'table', 'default'])->getMock(); $queue->expects($this->any())->method('currentTime')->willReturn('time'); + $queue->setContainer($container = m::spy(Container::class)); $database->shouldReceive('table')->with('table')->andReturn($query = m::mock(stdClass::class)); $query->shouldReceive('insertGetId')->once()->andReturnUsing(function ($array) use ($uuid) { $this->assertSame('default', $array['queue']); @@ -39,6 +41,8 @@ public function testPushProperlyPushesJobOntoDatabase() $queue->push('foo', ['data']); + $container->shouldHaveReceived('bound')->with('events')->once(); + Str::createUuidsNormally(); } @@ -56,6 +60,7 @@ public function testDelayedPushProperlyPushesJobOntoDatabase() [$database = m::mock(Connection::class), 'table', 'default'] )->getMock(); $queue->expects($this->any())->method('currentTime')->willReturn('time'); + $queue->setContainer($container = m::spy(Container::class)); $database->shouldReceive('table')->with('table')->andReturn($query = m::mock(stdClass::class)); $query->shouldReceive('insertGetId')->once()->andReturnUsing(function ($array) use ($uuid) { $this->assertSame('default', $array['queue']); @@ -67,6 +72,8 @@ public function testDelayedPushProperlyPushesJobOntoDatabase() $queue->later(10, 'foo', ['data']); + $container->shouldHaveReceived('bound')->with('events')->once(); + Str::createUuidsNormally(); } diff --git a/tests/Queue/QueueRedisQueueTest.php b/tests/Queue/QueueRedisQueueTest.php index 2060772d78a8..952384b7f200 100644 --- a/tests/Queue/QueueRedisQueueTest.php +++ b/tests/Queue/QueueRedisQueueTest.php @@ -2,6 +2,7 @@ namespace Illuminate\Tests\Queue; +use Illuminate\Container\Container; use Illuminate\Contracts\Redis\Factory; use Illuminate\Queue\LuaScripts; use Illuminate\Queue\Queue; @@ -28,11 +29,13 @@ public function testPushProperlyPushesJobOntoRedis() $queue = $this->getMockBuilder(RedisQueue::class)->onlyMethods(['getRandomId'])->setConstructorArgs([$redis = m::mock(Factory::class), 'default'])->getMock(); $queue->expects($this->once())->method('getRandomId')->willReturn('foo'); + $queue->setContainer($container = m::spy(Container::class)); $redis->shouldReceive('connection')->once()->andReturn($redis); $redis->shouldReceive('eval')->once()->with(LuaScripts::push(), 2, 'queues:default', 'queues:default:notify', json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'id' => 'foo', 'attempts' => 0])); $id = $queue->push('foo', ['data']); $this->assertSame('foo', $id); + $container->shouldHaveReceived('bound')->with('events')->once(); Str::createUuidsNormally(); } @@ -47,6 +50,7 @@ public function testPushProperlyPushesJobOntoRedisWithCustomPayloadHook() $queue = $this->getMockBuilder(RedisQueue::class)->onlyMethods(['getRandomId'])->setConstructorArgs([$redis = m::mock(Factory::class), 'default'])->getMock(); $queue->expects($this->once())->method('getRandomId')->willReturn('foo'); + $queue->setContainer($container = m::spy(Container::class)); $redis->shouldReceive('connection')->once()->andReturn($redis); $redis->shouldReceive('eval')->once()->with(LuaScripts::push(), 2, 'queues:default', 'queues:default:notify', json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'custom' => 'taylor', 'id' => 'foo', 'attempts' => 0])); @@ -56,6 +60,7 @@ public function testPushProperlyPushesJobOntoRedisWithCustomPayloadHook() $id = $queue->push('foo', ['data']); $this->assertSame('foo', $id); + $container->shouldHaveReceived('bound')->with('events')->once(); Queue::createPayloadUsing(null); @@ -72,6 +77,7 @@ public function testPushProperlyPushesJobOntoRedisWithTwoCustomPayloadHook() $queue = $this->getMockBuilder(RedisQueue::class)->onlyMethods(['getRandomId'])->setConstructorArgs([$redis = m::mock(Factory::class), 'default'])->getMock(); $queue->expects($this->once())->method('getRandomId')->willReturn('foo'); + $queue->setContainer($container = m::spy(Container::class)); $redis->shouldReceive('connection')->once()->andReturn($redis); $redis->shouldReceive('eval')->once()->with(LuaScripts::push(), 2, 'queues:default', 'queues:default:notify', json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'custom' => 'taylor', 'bar' => 'foo', 'id' => 'foo', 'attempts' => 0])); @@ -85,6 +91,7 @@ public function testPushProperlyPushesJobOntoRedisWithTwoCustomPayloadHook() $id = $queue->push('foo', ['data']); $this->assertSame('foo', $id); + $container->shouldHaveReceived('bound')->with('events')->once(); Queue::createPayloadUsing(null); @@ -100,6 +107,7 @@ public function testDelayedPushProperlyPushesJobOntoRedis() }); $queue = $this->getMockBuilder(RedisQueue::class)->onlyMethods(['availableAt', 'getRandomId'])->setConstructorArgs([$redis = m::mock(Factory::class), 'default'])->getMock(); + $queue->setContainer($container = m::spy(Container::class)); $queue->expects($this->once())->method('getRandomId')->willReturn('foo'); $queue->expects($this->once())->method('availableAt')->with(1)->willReturn(2); @@ -112,6 +120,7 @@ public function testDelayedPushProperlyPushesJobOntoRedis() $id = $queue->later(1, 'foo', ['data']); $this->assertSame('foo', $id); + $container->shouldHaveReceived('bound')->with('events')->once(); Str::createUuidsNormally(); } @@ -126,6 +135,7 @@ public function testDelayedPushWithDateTimeProperlyPushesJobOntoRedis() $date = Carbon::now(); $queue = $this->getMockBuilder(RedisQueue::class)->onlyMethods(['availableAt', 'getRandomId'])->setConstructorArgs([$redis = m::mock(Factory::class), 'default'])->getMock(); + $queue->setContainer($container = m::spy(Container::class)); $queue->expects($this->once())->method('getRandomId')->willReturn('foo'); $queue->expects($this->once())->method('availableAt')->with($date)->willReturn(2); @@ -137,6 +147,7 @@ public function testDelayedPushWithDateTimeProperlyPushesJobOntoRedis() ); $queue->later($date, 'foo', ['data']); + $container->shouldHaveReceived('bound')->with('events')->once(); Str::createUuidsNormally(); } diff --git a/tests/Queue/QueueSqsQueueTest.php b/tests/Queue/QueueSqsQueueTest.php index 789084515b0d..60e02b161ebb 100755 --- a/tests/Queue/QueueSqsQueueTest.php +++ b/tests/Queue/QueueSqsQueueTest.php @@ -92,33 +92,39 @@ public function testDelayedPushWithDateTimeProperlyPushesJobOntoSqs() { $now = Carbon::now(); $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'secondsUntil', 'getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock(); + $queue->setContainer($container = m::spy(Container::class)); $queue->expects($this->once())->method('createPayload')->with($this->mockedJob, $this->queueName, $this->mockedData)->willReturn($this->mockedPayload); $queue->expects($this->once())->method('secondsUntil')->with($now)->willReturn(5); $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl); $this->sqs->shouldReceive('sendMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'MessageBody' => $this->mockedPayload, 'DelaySeconds' => 5])->andReturn($this->mockedSendMessageResponseModel); $id = $queue->later($now->addSeconds(5), $this->mockedJob, $this->mockedData, $this->queueName); $this->assertEquals($this->mockedMessageId, $id); + $container->shouldHaveReceived('bound')->with('events')->once(); } public function testDelayedPushProperlyPushesJobOntoSqs() { $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'secondsUntil', 'getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock(); + $queue->setContainer($container = m::spy(Container::class)); $queue->expects($this->once())->method('createPayload')->with($this->mockedJob, $this->queueName, $this->mockedData)->willReturn($this->mockedPayload); $queue->expects($this->once())->method('secondsUntil')->with($this->mockedDelay)->willReturn($this->mockedDelay); $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl); $this->sqs->shouldReceive('sendMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'MessageBody' => $this->mockedPayload, 'DelaySeconds' => $this->mockedDelay])->andReturn($this->mockedSendMessageResponseModel); $id = $queue->later($this->mockedDelay, $this->mockedJob, $this->mockedData, $this->queueName); $this->assertEquals($this->mockedMessageId, $id); + $container->shouldHaveReceived('bound')->with('events')->once(); } public function testPushProperlyPushesJobOntoSqs() { $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock(); + $queue->setContainer($container = m::spy(Container::class)); $queue->expects($this->once())->method('createPayload')->with($this->mockedJob, $this->queueName, $this->mockedData)->willReturn($this->mockedPayload); $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl); $this->sqs->shouldReceive('sendMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'MessageBody' => $this->mockedPayload])->andReturn($this->mockedSendMessageResponseModel); $id = $queue->push($this->mockedJob, $this->mockedData, $this->queueName); $this->assertEquals($this->mockedMessageId, $id); + $container->shouldHaveReceived('bound')->with('events')->once(); } public function testSizeProperlyReadsSqsQueueSize() diff --git a/tests/Queue/RedisQueueIntegrationTest.php b/tests/Queue/RedisQueueIntegrationTest.php index 0380988bd4e1..b0a6a498f99c 100644 --- a/tests/Queue/RedisQueueIntegrationTest.php +++ b/tests/Queue/RedisQueueIntegrationTest.php @@ -3,7 +3,9 @@ namespace Illuminate\Tests\Queue; use Illuminate\Container\Container; +use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis; +use Illuminate\Queue\Events\JobQueued; use Illuminate\Queue\Jobs\RedisJob; use Illuminate\Queue\RedisQueue; use Illuminate\Support\Carbon; @@ -21,6 +23,11 @@ class RedisQueueIntegrationTest extends TestCase */ private $queue; + /** + * @var \Mockery\MockInterface|\Mockery\LegacyMockInterface + */ + private $container; + protected function setUp(): void { Carbon::setTestNow(Carbon::now()); @@ -57,6 +64,8 @@ public function testExpiredJobsArePopped($driver) $this->queue->later(-300, $jobs[2]); $this->queue->later(-100, $jobs[3]); + $this->container->shouldHaveReceived('bound')->with('events')->times(4); + $this->assertEquals($jobs[2], unserialize(json_decode($this->queue->pop()->getRawBody())->data->command)); $this->assertEquals($jobs[1], unserialize(json_decode($this->queue->pop()->getRawBody())->data->command)); $this->assertEquals($jobs[3], unserialize(json_decode($this->queue->pop()->getRawBody())->data->command)); @@ -183,13 +192,14 @@ public function testPopProperlyPopsDelayedJobOffOfRedis($driver) */ public function testPopPopsDelayedJobOffOfRedisWhenExpireNull($driver) { - $this->queue = new RedisQueue($this->redis[$driver], 'default', null, null); - $this->queue->setContainer(m::mock(Container::class)); + $this->setQueue($driver, 'default', null, null); // Push an item into queue $job = new RedisQueueIntegrationTestJob(10); $this->queue->later(-10, $job); + $this->container->shouldHaveReceived('bound')->with('events')->once(); + // Pop and check it is popped correctly $before = $this->currentTime(); $this->assertEquals($job, unserialize(json_decode($this->queue->pop()->getRawBody())->data->command)); @@ -264,12 +274,13 @@ public function testBlockingPopProperlyPopsExpiredJobs($driver) */ public function testNotExpireJobsWhenExpireNull($driver) { - $this->queue = new RedisQueue($this->redis[$driver], 'default', null, null); - $this->queue->setContainer(m::mock(Container::class)); + $this->setQueue($driver, 'default', null, null); // Make an expired reserved job $failed = new RedisQueueIntegrationTestJob(-20); $this->queue->push($failed); + $this->container->shouldHaveReceived('bound')->with('events')->once(); + $beforeFailPop = $this->currentTime(); $this->queue->pop(); $afterFailPop = $this->currentTime(); @@ -277,6 +288,7 @@ public function testNotExpireJobsWhenExpireNull($driver) // Push an item into queue $job = new RedisQueueIntegrationTestJob(10); $this->queue->push($job); + $this->container->shouldHaveReceived('bound')->with('events')->times(2); // Pop and check it is popped correctly $before = $this->currentTime(); @@ -309,12 +321,12 @@ public function testNotExpireJobsWhenExpireNull($driver) */ public function testExpireJobsWhenExpireSet($driver) { - $this->queue = new RedisQueue($this->redis[$driver], 'default', null, 30); - $this->queue->setContainer(m::mock(Container::class)); + $this->setQueue($driver, 'default', null, 30); // Push an item into queue $job = new RedisQueueIntegrationTestJob(10); $this->queue->push($job); + $this->container->shouldHaveReceived('bound')->with('events')->once(); // Pop and check it is popped correctly $before = $this->currentTime(); @@ -455,17 +467,67 @@ public function testSize($driver) $this->assertEquals(2, $this->queue->size()); } + /** + * @dataProvider redisDriverProvider + * + * @param string $driver + */ + public function testPushJobQueuedEvent($driver) + { + $events = m::mock(Dispatcher::class); + $events->shouldReceive('dispatch')->withArgs(function (JobQueued $jobQueued) { + $this->assertInstanceOf(RedisQueueIntegrationTestJob::class, $jobQueued->job); + $this->assertIsString(RedisQueueIntegrationTestJob::class, $jobQueued->jobId); + + return true; + })->andReturnNull()->once(); + + $container = m::mock(Container::class); + $container->shouldReceive('bound')->with('events')->andReturn(true)->once(); + $container->shouldReceive('offsetGet')->with('events')->andReturn($events)->once(); + + $queue = new RedisQueue($this->redis[$driver]); + $queue->setContainer($container); + + $queue->push(new RedisQueueIntegrationTestJob(5)); + } + + /** + * @dataProvider redisDriverProvider + * + * @param string $driver + */ + public function testBulkJobQueuedEvent($driver) + { + $events = m::mock(Dispatcher::class); + $events->shouldReceive('dispatch')->with(m::type(JobQueued::class))->andReturnNull()->times(3); + + $container = m::mock(Container::class); + $container->shouldReceive('bound')->with('events')->andReturn(true)->times(3); + $container->shouldReceive('offsetGet')->with('events')->andReturn($events)->times(3); + + $queue = new RedisQueue($this->redis[$driver]); + $queue->setContainer($container); + + $queue->bulk([ + new RedisQueueIntegrationTestJob(5), + new RedisQueueIntegrationTestJob(10), + new RedisQueueIntegrationTestJob(15), + ]); + } + /** * @param string $driver * @param string $default - * @param string $connection + * @param string|null $connection * @param int $retryAfter * @param int|null $blockFor */ private function setQueue($driver, $default = 'default', $connection = null, $retryAfter = 60, $blockFor = null) { $this->queue = new RedisQueue($this->redis[$driver], $default, $connection, $retryAfter, $blockFor); - $this->queue->setContainer(m::mock(Container::class)); + $this->container = m::spy(Container::class); + $this->queue->setContainer($this->container); } } From 5d572e7a6d479ef68ee92c9d67e2e9465174fb4c Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Wed, 20 Jan 2021 14:18:04 -0600 Subject: [PATCH 15/22] formatting --- src/Illuminate/Queue/Events/JobQueued.php | 25 +++++++++++++++----- src/Illuminate/Queue/Queue.php | 28 +++++++++++------------ tests/Queue/RedisQueueIntegrationTest.php | 2 +- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/Illuminate/Queue/Events/JobQueued.php b/src/Illuminate/Queue/Events/JobQueued.php index 4568cd922fb0..c91d14095963 100644 --- a/src/Illuminate/Queue/Events/JobQueued.php +++ b/src/Illuminate/Queue/Events/JobQueued.php @@ -5,25 +5,38 @@ class JobQueued { /** + * The connection name. + * + * @var string + */ + public $connectionName; + + /** + * The job ID. + * * @var string|int|null */ - public $jobId; + public $id; /** - * @var string|object + * The job instance. + * + * @var \Closure|string|object */ public $job; /** - * JobQueued constructor. + * Create a new event instance. * - * @param string|int|null $jobId + * @param string $connectionName + * @param string|int|null $id * @param \Closure|string|object $job * @return void */ - public function __construct($jobId, $job) + public function __construct($connectionName, $id, $job) { - $this->jobId = $jobId; + $this->connectionName = $connectionName; + $this->id = $id; $this->job = $job; } } diff --git a/src/Illuminate/Queue/Queue.php b/src/Illuminate/Queue/Queue.php index bfe8baec8507..f036f2a871c5 100755 --- a/src/Illuminate/Queue/Queue.php +++ b/src/Illuminate/Queue/Queue.php @@ -317,6 +317,20 @@ protected function shouldDispatchAfterCommit($job) return false; } + /** + * Raise the job queued event. + * + * @param string|int|null $jobId + * @param \Closure|string|object $job + * @return void + */ + protected function raiseJobQueuedEvent($jobId, $job) + { + if ($this->container->bound('events')) { + $this->container['events']->dispatch(new JobQueued($this->connectionName, $jobId, $job)); + } + } + /** * Get the connection name for the queue. * @@ -350,18 +364,4 @@ public function setContainer(Container $container) { $this->container = $container; } - - /** - * Raise the job queued event. - * - * @param string|int|null $jobId - * @param \Closure|string|object $job - * @return void - */ - protected function raiseJobQueuedEvent($jobId, $job) - { - if ($this->container->bound('events')) { - $this->container['events']->dispatch(new JobQueued($jobId, $job)); - } - } } diff --git a/tests/Queue/RedisQueueIntegrationTest.php b/tests/Queue/RedisQueueIntegrationTest.php index b0a6a498f99c..5fbad9311dd4 100644 --- a/tests/Queue/RedisQueueIntegrationTest.php +++ b/tests/Queue/RedisQueueIntegrationTest.php @@ -477,7 +477,7 @@ public function testPushJobQueuedEvent($driver) $events = m::mock(Dispatcher::class); $events->shouldReceive('dispatch')->withArgs(function (JobQueued $jobQueued) { $this->assertInstanceOf(RedisQueueIntegrationTestJob::class, $jobQueued->job); - $this->assertIsString(RedisQueueIntegrationTestJob::class, $jobQueued->jobId); + $this->assertIsString(RedisQueueIntegrationTestJob::class, $jobQueued->id); return true; })->andReturnNull()->once(); From 9d3752ca5f29c4cb1c0384fb01847820b6ac492c Mon Sep 17 00:00:00 2001 From: Kane Cohen Date: Thu, 21 Jan 2021 08:44:52 +0000 Subject: [PATCH 16/22] Limit expected bindingx v2. --- src/Illuminate/Database/Query/Builder.php | 25 +++++++++++++++------ tests/Database/DatabaseQueryBuilderTest.php | 5 +++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 83416d83be02..c8d47e621495 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -307,6 +307,17 @@ public function fromRaw($expression, $bindings = []) return $this; } + /** + * Returns scalar type value from an unknown type of input. + * + * @param mixed $value + * @return mixed + */ + protected function scalarValue($value) + { + return is_array($value) ? head(Arr::flatten($value)) : $value; + } + /** * Creates a subquery and parse it. * @@ -698,7 +709,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' ); if (! $value instanceof Expression) { - $this->addBinding(is_array($value) ? head($value) : $value, 'where'); + $this->addBinding($this->scalarValue($value), 'where'); } return $this; @@ -1043,7 +1054,7 @@ public function whereBetween($column, array $values, $boolean = 'and', $not = fa $this->wheres[] = compact('type', 'column', 'values', 'boolean', 'not'); - $this->addBinding(array_slice($this->cleanBindings($values), 0, 2), 'where'); + $this->addBinding(array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2), 'where'); return $this; } @@ -1111,7 +1122,7 @@ public function whereDate($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); - $value = is_array($value) ? head($value) : $value; + $value = $this->scalarValue($value); if ($value instanceof DateTimeInterface) { $value = $value->format('Y-m-d'); @@ -1152,7 +1163,7 @@ public function whereTime($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); - $value = is_array($value) ? head($value) : $value; + $value = $this->scalarValue($value); if ($value instanceof DateTimeInterface) { $value = $value->format('H:i:s'); @@ -1238,7 +1249,7 @@ public function whereMonth($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); - $value = is_array($value) ? head($value) : $value; + $value = $this->scalarValue($value); if ($value instanceof DateTimeInterface) { $value = $value->format('m'); @@ -1593,7 +1604,7 @@ public function whereJsonLength($column, $operator, $value = null, $boolean = 'a $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean'); if (! $value instanceof Expression) { - $this->addBinding((int) $value); + $this->addBinding((int) $this->scalarValue($value)); } return $this; @@ -1742,7 +1753,7 @@ public function having($column, $operator = null, $value = null, $boolean = 'and $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean'); if (! $value instanceof Expression) { - $this->addBinding(is_array($value) ? head($value) : $value, 'having'); + $this->addBinding($this->scalarValue($value), 'having'); } return $this; diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index f7d20c532223..781bc637b2a4 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -319,6 +319,11 @@ public function testWheresWithArrayValue() $builder->select('*')->from('users')->where('id', '<>', [12, 30]); $this->assertSame('select * from "users" where "id" <> ?', $builder->toSql()); $this->assertEquals([0 => 12], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('id', '=', [[12, 30]]); + $this->assertSame('select * from "users" where "id" = ?', $builder->toSql()); + $this->assertEquals([0 => 12], $builder->getBindings()); } public function testMySqlWrappingProtectsQuotationMarks() From dbbb1c1c8a1fa0a51677b5a74fcfe0e2561ced91 Mon Sep 17 00:00:00 2001 From: Kane Cohen Date: Thu, 21 Jan 2021 10:48:50 +0000 Subject: [PATCH 17/22] Update whereDay and whereYear to clean value. --- src/Illuminate/Database/Query/Builder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index c8d47e621495..85679e9472c0 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -1204,7 +1204,7 @@ public function whereDay($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); - $value = is_array($value) ? head($value) : $value; + $value = $this->scalarValue($value); if ($value instanceof DateTimeInterface) { $value = $value->format('d'); @@ -1294,7 +1294,7 @@ public function whereYear($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); - $value = is_array($value) ? head($value) : $value; + $value = $this->scalarValue($value); if ($value instanceof DateTimeInterface) { $value = $value->format('Y'); From c6b8168e6cbbe339fdc3af5ccdded545779965df Mon Sep 17 00:00:00 2001 From: Kane Cohen Date: Thu, 21 Jan 2021 12:08:38 +0000 Subject: [PATCH 18/22] Add limit bindings for having between + tests. --- src/Illuminate/Database/Query/Builder.php | 2 +- tests/Database/DatabaseQueryBuilderTest.php | 23 +++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 85679e9472c0..8ab17d32b960 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -1791,7 +1791,7 @@ public function havingBetween($column, array $values, $boolean = 'and', $not = f $this->havings[] = compact('type', 'column', 'values', 'boolean', 'not'); - $this->addBinding($this->cleanBindings($values), 'having'); + $this->addBinding(array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2), 'having'); return $this; } diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index 781bc637b2a4..8607434fea1a 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -654,6 +654,16 @@ public function testWhereBetweens() $this->assertSame('select * from "users" where "id" between ? and ?', $builder->toSql()); $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereBetween('id', [[1, 2, 3]]); + $this->assertSame('select * from "users" where "id" between ? and ?', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereBetween('id', [[1], [2, 3]]); + $this->assertSame('select * from "users" where "id" between ? and ?', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + $builder = $this->getBuilder(); $builder->select('*')->from('users')->whereNotBetween('id', [1, 2]); $this->assertSame('select * from "users" where "id" not between ? and ?', $builder->toSql()); @@ -1172,10 +1182,19 @@ public function testHavings() $builder = $this->getBuilder(); $builder->select(['category', new Raw('count(*) as "total"')])->from('item')->where('department', '=', 'popular')->groupBy('category')->having('total', '>', 3); $this->assertSame('select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > ?', $builder->toSql()); + } + public function testHavingBetweens() + { $builder = $this->getBuilder(); - $builder->select('*')->from('users')->havingBetween('last_login_date', ['2018-11-16', '2018-12-16']); - $this->assertSame('select * from "users" having "last_login_date" between ? and ?', $builder->toSql()); + $builder->select('*')->from('users')->havingBetween('id', [1, 2, 3]); + $this->assertSame('select * from "users" having "id" between ? and ?', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->havingBetween('id', [[1, 2], [3, 4]]); + $this->assertSame('select * from "users" having "id" between ? and ?', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); } public function testHavingShortcut() From 006873df411d28bfd03fea5e7f91a2afe3918498 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Thu, 21 Jan 2021 08:07:23 -0600 Subject: [PATCH 19/22] formatting --- src/Illuminate/Database/Query/Builder.php | 38 +++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 8ab17d32b960..c762e8525605 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -307,17 +307,6 @@ public function fromRaw($expression, $bindings = []) return $this; } - /** - * Returns scalar type value from an unknown type of input. - * - * @param mixed $value - * @return mixed - */ - protected function scalarValue($value) - { - return is_array($value) ? head(Arr::flatten($value)) : $value; - } - /** * Creates a subquery and parse it. * @@ -709,7 +698,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' ); if (! $value instanceof Expression) { - $this->addBinding($this->scalarValue($value), 'where'); + $this->addBinding($this->flattenValue($value), 'where'); } return $this; @@ -1122,7 +1111,7 @@ public function whereDate($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); - $value = $this->scalarValue($value); + $value = $this->flattenValue($value); if ($value instanceof DateTimeInterface) { $value = $value->format('Y-m-d'); @@ -1163,7 +1152,7 @@ public function whereTime($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); - $value = $this->scalarValue($value); + $value = $this->flattenValue($value); if ($value instanceof DateTimeInterface) { $value = $value->format('H:i:s'); @@ -1204,7 +1193,7 @@ public function whereDay($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); - $value = $this->scalarValue($value); + $value = $this->flattenValue($value); if ($value instanceof DateTimeInterface) { $value = $value->format('d'); @@ -1249,7 +1238,7 @@ public function whereMonth($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); - $value = $this->scalarValue($value); + $value = $this->flattenValue($value); if ($value instanceof DateTimeInterface) { $value = $value->format('m'); @@ -1294,7 +1283,7 @@ public function whereYear($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); - $value = $this->scalarValue($value); + $value = $this->flattenValue($value); if ($value instanceof DateTimeInterface) { $value = $value->format('Y'); @@ -1604,7 +1593,7 @@ public function whereJsonLength($column, $operator, $value = null, $boolean = 'a $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean'); if (! $value instanceof Expression) { - $this->addBinding((int) $this->scalarValue($value)); + $this->addBinding((int) $this->flattenValue($value)); } return $this; @@ -1753,7 +1742,7 @@ public function having($column, $operator = null, $value = null, $boolean = 'and $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean'); if (! $value instanceof Expression) { - $this->addBinding($this->scalarValue($value), 'having'); + $this->addBinding($this->flattenValue($value), 'having'); } return $this; @@ -2969,6 +2958,17 @@ protected function cleanBindings(array $bindings) })); } + /** + * Get a scalar type value from an unknown type of input. + * + * @param mixed $value + * @return mixed + */ + protected function flattenValue($value) + { + return is_array($value) ? head(Arr::flatten($value)) : $value; + } + /** * Get the default key name of the table. * From d627ce29122404abaa5bd9221d4b14e08fd4fcd2 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Thu, 21 Jan 2021 08:11:10 -0600 Subject: [PATCH 20/22] version --- src/Illuminate/Foundation/Application.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index 0dab37cd18dc..63637a1c60b8 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -33,7 +33,7 @@ class Application extends Container implements ApplicationContract, CachesConfig * * @var string */ - const VERSION = '8.23.1'; + const VERSION = '8.23.2'; /** * The base path for the Laravel installation. From 7689b36264eca2b2a9b5b099fa9735277feacb73 Mon Sep 17 00:00:00 2001 From: Chuangbo Li Date: Thu, 21 Jan 2021 22:18:59 +0800 Subject: [PATCH 21/22] fix serialization of rate limited with redis middleware (#35971) Same as f3d4dcb but for RateLimitedWithRedis --- .../Queue/Middleware/RateLimitedWithRedis.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Illuminate/Queue/Middleware/RateLimitedWithRedis.php b/src/Illuminate/Queue/Middleware/RateLimitedWithRedis.php index 7000e9d55307..af1eac1aa7ff 100644 --- a/src/Illuminate/Queue/Middleware/RateLimitedWithRedis.php +++ b/src/Illuminate/Queue/Middleware/RateLimitedWithRedis.php @@ -88,4 +88,17 @@ protected function getTimeUntilNextRetry($key) { return ($this->decaysAt[$key] - $this->currentTime()) + 3; } + + /** + * Prepare the object after unserialization. + * + * @param array $data + * @return void + */ + public function __unserialize(array $data) + { + parent::__unserialize($data); + + $this->redis = Container::getInstance()->make(Redis::class); + } } From d16e9f875e4d7609a05d5007393e22ba95efd1fc Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Thu, 21 Jan 2021 08:19:21 -0600 Subject: [PATCH 22/22] version --- src/Illuminate/Foundation/Application.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index 63637a1c60b8..4fdb7059931c 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -33,7 +33,7 @@ class Application extends Container implements ApplicationContract, CachesConfig * * @var string */ - const VERSION = '8.23.2'; + const VERSION = '8.24.0'; /** * The base path for the Laravel installation. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy