Skip to content

Commit e75ab68

Browse files
committed
PHPORM-229 Make Query\Builder return objects instead of array to match Laravel's behavior
1 parent a453f8a commit e75ab68

File tree

11 files changed

+186
-168
lines changed

11 files changed

+186
-168
lines changed

docs/includes/query-builder/QueryBuilderTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -519,11 +519,11 @@ public function testUpsert(): void
519519

520520
$this->assertSame(2, $result);
521521

522-
$this->assertSame(119, DB::table('movies')->where('title', 'Inspector Maigret')->first()['runtime']);
523-
$this->assertSame(false, DB::table('movies')->where('title', 'Inspector Maigret')->first()['recommended']);
522+
$this->assertSame(119, DB::table('movies')->where('title', 'Inspector Maigret')->first()->runtime);
523+
$this->assertSame(false, DB::table('movies')->where('title', 'Inspector Maigret')->first()->recommended);
524524

525-
$this->assertSame(true, DB::table('movies')->where('title', 'Petit Maman')->first()['recommended']);
526-
$this->assertSame(72, DB::table('movies')->where('title', 'Petit Maman')->first()['runtime']);
525+
$this->assertSame(true, DB::table('movies')->where('title', 'Petit Maman')->first()->recommended);
526+
$this->assertSame(72, DB::table('movies')->where('title', 'Petit Maman')->first()->runtime);
527527
}
528528

529529
public function testUpdateUpsert(): void

src/Query/Builder.php

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use MongoDB\Driver\Cursor;
2626
use Override;
2727
use RuntimeException;
28+
use stdClass;
2829

2930
use function array_fill_keys;
3031
use function array_is_list;
@@ -46,18 +47,21 @@
4647
use function func_get_args;
4748
use function func_num_args;
4849
use function get_debug_type;
50+
use function get_object_vars;
4951
use function implode;
5052
use function in_array;
5153
use function is_array;
5254
use function is_bool;
5355
use function is_callable;
5456
use function is_float;
5557
use function is_int;
58+
use function is_object;
5659
use function is_string;
5760
use function md5;
5861
use function preg_match;
5962
use function preg_quote;
6063
use function preg_replace;
64+
use function property_exists;
6165
use function serialize;
6266
use function sprintf;
6367
use function str_ends_with;
@@ -392,7 +396,7 @@ public function toMql(): array
392396
}
393397

394398
$options = [
395-
'typeMap' => ['root' => 'array', 'document' => 'array'],
399+
'typeMap' => ['root' => 'object', 'document' => 'array'],
396400
];
397401

398402
// Add custom query options
@@ -451,8 +455,7 @@ public function toMql(): array
451455
$options['projection'] = $projection;
452456
}
453457

454-
// Fix for legacy support, converts the results to arrays instead of objects.
455-
$options['typeMap'] = ['root' => 'array', 'document' => 'array'];
458+
$options['typeMap'] = ['root' => 'object', 'document' => 'array'];
456459

457460
// Add custom query options
458461
if (count($this->options)) {
@@ -517,7 +520,7 @@ public function getFresh($columns = [], $returnLazy = false)
517520
}
518521

519522
foreach ($result as &$document) {
520-
if (is_array($document)) {
523+
if (is_array($document) || is_object($document)) {
521524
$document = $this->aliasIdForResult($document);
522525
}
523526
}
@@ -1651,16 +1654,31 @@ private function aliasIdForQuery(array $values): array
16511654
return $values;
16521655
}
16531656

1654-
private function aliasIdForResult(array $values): array
1657+
private function aliasIdForResult(array|object $values): array|object
16551658
{
1656-
if (array_key_exists('_id', $values) && ! array_key_exists('id', $values)) {
1657-
$values['id'] = $values['_id'];
1658-
//unset($values['_id']);
1659+
if (is_array($values)) {
1660+
if (array_key_exists('_id', $values) && ! array_key_exists('id', $values)) {
1661+
$values['id'] = $values['_id'];
1662+
//unset($values['_id']);
1663+
}
1664+
1665+
foreach ($values as $key => $value) {
1666+
if (is_array($value) || is_object($value)) {
1667+
$values[$key] = $this->aliasIdForResult($value);
1668+
}
1669+
}
16591670
}
16601671

1661-
foreach ($values as $key => $value) {
1662-
if (is_array($value)) {
1663-
$values[$key] = $this->aliasIdForResult($value);
1672+
if ($values instanceof stdClass) {
1673+
if (property_exists($values, '_id') && ! property_exists($values, 'id')) {
1674+
$values->id = $values->_id;
1675+
//unset($values->_id);
1676+
}
1677+
1678+
foreach (get_object_vars($values) as $key => $value) {
1679+
if (is_array($value) || is_object($value)) {
1680+
$values->{$key} = $this->aliasIdForResult($value);
1681+
}
16641682
}
16651683
}
16661684

src/Queue/Failed/MongoFailedJobProvider.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ public function log($connection, $queue, $payload, $exception)
4343
*/
4444
public function all()
4545
{
46-
$all = $this->getTable()->orderBy('_id', 'desc')->get()->all();
46+
$all = $this->getTable()->orderBy('id', 'desc')->get()->all();
4747

4848
$all = array_map(function ($job) {
49-
$job['id'] = (string) $job['_id'];
49+
$job->id = (string) $job->id;
5050

51-
return (object) $job;
51+
return $job;
5252
}, $all);
5353

5454
return $all;
@@ -69,9 +69,9 @@ public function find($id)
6969
return null;
7070
}
7171

72-
$job['id'] = (string) $job['_id'];
72+
$job->id = (string) $job->id;
7373

74-
return (object) $job;
74+
return $job;
7575
}
7676

7777
/**

src/Queue/MongoQueue.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ protected function releaseJobsThatHaveBeenReservedTooLong($queue)
116116
->get();
117117

118118
foreach ($reserved as $job) {
119-
$this->releaseJob($job['_id'], $job['attempts']);
119+
$this->releaseJob($job->id, $job->attempts);
120120
}
121121
}
122122

tests/AuthTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ function ($actualUser, $actualToken) use ($user, &$token) {
6161

6262
$this->assertEquals(1, DB::table('password_reset_tokens')->count());
6363
$reminder = DB::table('password_reset_tokens')->first();
64-
$this->assertEquals('john.doe@example.com', $reminder['email']);
65-
$this->assertNotNull($reminder['token']);
66-
$this->assertInstanceOf(UTCDateTime::class, $reminder['created_at']);
64+
$this->assertEquals('john.doe@example.com', $reminder->email);
65+
$this->assertNotNull($reminder->token);
66+
$this->assertInstanceOf(UTCDateTime::class, $reminder->created_at);
6767

6868
$credentials = [
6969
'email' => 'john.doe@example.com',

tests/Query/BuilderTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ public function testMql(array $expected, Closure $build): void
3939

4040
// Operations that return a Cursor expect a "typeMap" option.
4141
if (isset($expected['find'][1])) {
42-
$expected['find'][1]['typeMap'] = ['root' => 'array', 'document' => 'array'];
42+
$expected['find'][1]['typeMap'] = ['root' => 'object', 'document' => 'array'];
4343
}
4444

4545
if (isset($expected['aggregate'][1])) {
46-
$expected['aggregate'][1]['typeMap'] = ['root' => 'array', 'document' => 'array'];
46+
$expected['aggregate'][1]['typeMap'] = ['root' => 'object', 'document' => 'array'];
4747
}
4848

4949
// Compare with assertEquals because the query can contain BSON objects.

0 commit comments

Comments
 (0)