Skip to content

Commit 437114e

Browse files
committed
Merge branch '5.5' of github.com:laravel/framework into 5.5
2 parents 4894e4d + c6d85c9 commit 437114e

File tree

11 files changed

+336
-8
lines changed

11 files changed

+336
-8
lines changed

CHANGELOG-5.5.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Release Notes for 5.5.x
22

3+
## [Unreleased]
4+
5+
## Changed
6+
- Added "kin" as uncountable word ([#21843](https://github.com/laravel/framework/pull/21843))
7+
8+
## Fixed
9+
- Fixed `BroadcastController` namespace issue ([#21844](https://github.com/laravel/framework/pull/21844))
10+
11+
312
## v5.5.19 (2017-10-25)
413

514
### Added

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
"nexmo/client": "Required to use the Nexmo transport (~1.0).",
116116
"pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).",
117117
"predis/predis": "Required to use the redis cache and queue drivers (~1.0).",
118-
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0).",
118+
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~3.0).",
119119
"symfony/css-selector": "Required to use some of the crawler integration testing tools (~3.3).",
120120
"symfony/dom-crawler": "Required to use most of the crawler integration testing tools (~3.3).",
121121
"symfony/psr-http-message-bridge": "Required to psr7 bridging features (~1.0)."

src/Illuminate/Bus/Queueable.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@ trait Queueable
1818
*/
1919
public $queue;
2020

21+
/**
22+
* The name of the connection the chain should be sent to.
23+
*
24+
* @var string|null
25+
*/
26+
public $chainConnection;
27+
28+
/**
29+
* The name of the queue the chain should be sent to.
30+
*
31+
* @var string|null
32+
*/
33+
public $chainQueue;
34+
2135
/**
2236
* The number of seconds before the job should be made available.
2337
*
@@ -58,6 +72,34 @@ public function onQueue($queue)
5872
return $this;
5973
}
6074

75+
/**
76+
* Set the desired connection for the chain.
77+
*
78+
* @param string|null $connection
79+
* @return $this
80+
*/
81+
public function allOnConnection($connection)
82+
{
83+
$this->chainConnection = $connection;
84+
$this->connection = $connection;
85+
86+
return $this;
87+
}
88+
89+
/**
90+
* Set the desired queue for the chain.
91+
*
92+
* @param string|null $queue
93+
* @return $this
94+
*/
95+
public function allOnQueue($queue)
96+
{
97+
$this->chainQueue = $queue;
98+
$this->queue = $queue;
99+
100+
return $this;
101+
}
102+
61103
/**
62104
* Set the desired delay for the job.
63105
*
@@ -96,6 +138,12 @@ public function dispatchNextJobInChain()
96138
if (! empty($this->chained)) {
97139
dispatch(tap(unserialize(array_shift($this->chained)), function ($next) {
98140
$next->chained = $this->chained;
141+
142+
$next->onConnection($next->connection ?: $this->chainConnection);
143+
$next->onQueue($next->queue ?: $this->chainQueue);
144+
145+
$next->chainConnection = $this->chainConnection;
146+
$next->chainQueue = $this->chainQueue;
99147
}));
100148
}
101149
}

src/Illuminate/Database/Eloquent/Relations/HasManyThrough.php

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ class HasManyThrough extends Relation
5252
*/
5353
protected $secondLocalKey;
5454

55+
/**
56+
* The count of self joins.
57+
*
58+
* @var int
59+
*/
60+
protected static $selfJoinCount = 0;
61+
5562
/**
5663
* Create a new has many through relationship instance.
5764
*
@@ -178,7 +185,7 @@ public function match(array $models, Collection $results, $relation)
178185
// link them up with their children using the keyed dictionary to make the
179186
// matching very convenient and easy work. Then we'll just return them.
180187
foreach ($models as $model) {
181-
if (isset($dictionary[$key = $model->getKey()])) {
188+
if (isset($dictionary[$key = $model->getAttribute($this->localKey)])) {
182189
$model->setRelation(
183190
$relation, $this->related->newCollection($dictionary[$key])
184191
);
@@ -425,13 +432,52 @@ protected function shouldSelect(array $columns = ['*'])
425432
*/
426433
public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
427434
{
435+
if ($parentQuery->getQuery()->from == $query->getQuery()->from) {
436+
return $this->getRelationExistenceQueryForSelfRelation($query, $parentQuery, $columns);
437+
}
438+
428439
$this->performJoin($query);
429440

430441
return $query->select($columns)->whereColumn(
431442
$this->getExistenceCompareKey(), '=', $this->getQualifiedFirstKeyName()
432443
);
433444
}
434445

446+
/**
447+
* Add the constraints for a relationship query on the same table.
448+
*
449+
* @param \Illuminate\Database\Eloquent\Builder $query
450+
* @param \Illuminate\Database\Eloquent\Builder $parentQuery
451+
* @param array|mixed $columns
452+
* @return \Illuminate\Database\Eloquent\Builder
453+
*/
454+
public function getRelationExistenceQueryForSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])
455+
{
456+
$query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash());
457+
458+
$query->join($this->throughParent->getTable(), $this->getQualifiedParentKeyName(), '=', $hash.'.'.$this->secondLocalKey);
459+
460+
if ($this->throughParentSoftDeletes()) {
461+
$query->whereNull($this->throughParent->getQualifiedDeletedAtColumn());
462+
}
463+
464+
$query->getModel()->setTable($hash);
465+
466+
return $query->select($columns)->whereColumn(
467+
$parentQuery->getQuery()->from.'.'.$query->getModel()->getKeyName(), '=', $this->getQualifiedFirstKeyName()
468+
);
469+
}
470+
471+
/**
472+
* Get a relationship join table hash.
473+
*
474+
* @return string
475+
*/
476+
public function getRelationCountHash()
477+
{
478+
return 'laravel_reserved_'.static::$selfJoinCount++;
479+
}
480+
435481
/**
436482
* Get the key for comparing against the parent key in "has" query.
437483
*

src/Illuminate/Foundation/Bus/PendingDispatch.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,32 @@ public function onQueue($queue)
5050
return $this;
5151
}
5252

53+
/**
54+
* Set the desired connection for the chain.
55+
*
56+
* @param string|null $connection
57+
* @return $this
58+
*/
59+
public function allOnConnection($connection)
60+
{
61+
$this->job->allOnConnection($connection);
62+
63+
return $this;
64+
}
65+
66+
/**
67+
* Set the desired queue for the chain.
68+
*
69+
* @param string|null $queue
70+
* @return $this
71+
*/
72+
public function allOnQueue($queue)
73+
{
74+
$this->job->allOnQueue($queue);
75+
76+
return $this;
77+
}
78+
5379
/**
5480
* Set the desired delay for the job.
5581
*

src/Illuminate/Foundation/Testing/TestResponse.php

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,21 +359,26 @@ public function assertJsonFragment(array $data)
359359
* Assert that the response does not contain the given JSON fragment.
360360
*
361361
* @param array $data
362+
* @param bool $exact
362363
* @return $this
363364
*/
364-
public function assertJsonMissing(array $data)
365+
public function assertJsonMissing(array $data, $exact = false)
365366
{
367+
if ($exact) {
368+
return $this->assertJsonMissingExact($data);
369+
}
370+
366371
$actual = json_encode(Arr::sortRecursive(
367372
(array) $this->decodeResponseJson()
368373
));
369374

370375
foreach (Arr::sortRecursive($data) as $key => $value) {
371-
$expected = substr(json_encode([$key => $value]), 1, -1);
376+
$unexpected = substr(json_encode([$key => $value]), 1, -1);
372377

373378
PHPUnit::assertFalse(
374-
Str::contains($actual, $expected),
379+
Str::contains($actual, $unexpected),
375380
'Found unexpected JSON fragment: '.PHP_EOL.PHP_EOL.
376-
"[{$expected}]".PHP_EOL.PHP_EOL.
381+
"[{$unexpected}]".PHP_EOL.PHP_EOL.
377382
'within'.PHP_EOL.PHP_EOL.
378383
"[{$actual}]."
379384
);
@@ -382,6 +387,34 @@ public function assertJsonMissing(array $data)
382387
return $this;
383388
}
384389

390+
/**
391+
* Assert that the response does not contain the exact JSON fragment.
392+
*
393+
* @param array $data
394+
* @return $this
395+
*/
396+
public function assertJsonMissingExact(array $data)
397+
{
398+
$actual = json_encode(Arr::sortRecursive(
399+
(array) $this->decodeResponseJson()
400+
));
401+
402+
foreach (Arr::sortRecursive($data) as $key => $value) {
403+
$unexpected = substr(json_encode([$key => $value]), 1, -1);
404+
405+
if (! Str::contains($actual, $unexpected)) {
406+
return $this;
407+
}
408+
}
409+
410+
PHPUnit::fail(
411+
'Found unexpected JSON fragment: '.PHP_EOL.PHP_EOL.
412+
'['.json_encode($data).']'.PHP_EOL.PHP_EOL.
413+
'within'.PHP_EOL.PHP_EOL.
414+
"[{$actual}]."
415+
);
416+
}
417+
385418
/**
386419
* Assert that the response has a given JSON structure.
387420
*

src/Illuminate/Support/Traits/Macroable.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use ReflectionClass;
77
use ReflectionMethod;
88
use BadMethodCallException;
9-
use Illuminate\Contracts\Support\Macro;
109

1110
trait Macroable
1211
{

tests/Database/DatabaseEloquentHasManyThroughIntegrationTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ public function testItLoadsARelationWithCustomIntermediateAndLocalKey()
100100
$this->assertCount(2, $posts);
101101
}
102102

103+
public function testEagerLoadingARelationWithCustomIntermediateAndLocalKey()
104+
{
105+
$this->seedData();
106+
$posts = HasManyThroughIntermediateTestCountry::with('posts')->first()->posts;
107+
108+
$this->assertEquals('A title', $posts[0]->title);
109+
$this->assertCount(2, $posts);
110+
}
111+
103112
/**
104113
* @expectedException \Illuminate\Database\Eloquent\ModelNotFoundException
105114
* @expectedExceptionMessage No query results for model [Illuminate\Tests\Database\HasManyThroughTestPost].
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace Illuminate\Tests\Integration\Database\EloquentHasManyThroughTest;
4+
5+
use Orchestra\Testbench\TestCase;
6+
use Illuminate\Support\Facades\Schema;
7+
use Illuminate\Database\Eloquent\Model;
8+
9+
/**
10+
* @group integration
11+
*/
12+
class EloquentHasManyThroughTest extends TestCase
13+
{
14+
protected function getEnvironmentSetUp($app)
15+
{
16+
$app['config']->set('app.debug', 'true');
17+
18+
$app['config']->set('database.default', 'testbench');
19+
20+
$app['config']->set('database.connections.testbench', [
21+
'driver' => 'sqlite',
22+
'database' => ':memory:',
23+
'prefix' => '',
24+
]);
25+
}
26+
27+
public function setUp()
28+
{
29+
parent::setUp();
30+
31+
Schema::create('users', function ($table) {
32+
$table->increments('id');
33+
$table->integer('team_id')->nullable();
34+
$table->string('name');
35+
});
36+
37+
Schema::create('teams', function ($table) {
38+
$table->increments('id');
39+
$table->integer('owner_id');
40+
});
41+
}
42+
43+
/**
44+
* @test
45+
*/
46+
public function basic_create_and_retrieve()
47+
{
48+
$user = User::create(['name' => str_random()]);
49+
50+
$team1 = Team::create(['owner_id' => $user->id]);
51+
$team2 = Team::create(['owner_id' => $user->id]);
52+
53+
$mate1 = User::create(['name' => str_random(), 'team_id' => $team1->id]);
54+
$mate2 = User::create(['name' => str_random(), 'team_id' => $team2->id]);
55+
56+
$notMember = User::create(['name' => str_random()]);
57+
58+
$this->assertEquals([$mate1->id, $mate2->id], $user->teamMates->pluck('id')->toArray());
59+
$this->assertEquals([$user->id], User::has('teamMates')->pluck('id')->toArray());
60+
}
61+
}
62+
63+
class User extends Model
64+
{
65+
public $table = 'users';
66+
public $timestamps = false;
67+
protected $guarded = ['id'];
68+
69+
public function teamMates()
70+
{
71+
return $this->hasManyThrough(self::class, Team::class, 'owner_id', 'team_id');
72+
}
73+
}
74+
75+
class Team extends Model
76+
{
77+
public $table = 'teams';
78+
public $timestamps = false;
79+
protected $guarded = ['id'];
80+
}

0 commit comments

Comments
 (0)