Skip to content
This repository was archived by the owner on Aug 22, 2023. It is now read-only.

Commit 4790125

Browse files
committed
Attempt to remove automatic conversion
1 parent 9f1f8f3 commit 4790125

File tree

9 files changed

+48
-100
lines changed

9 files changed

+48
-100
lines changed

src/Eloquent/Builder.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,4 +241,9 @@ protected function ensureOrderForCursorPagination($shouldReverse = false)
241241
];
242242
})->values();
243243
}
244+
245+
public function whereKey($id)
246+
{
247+
return parent::whereKey($this->model->convertKey($id));
248+
}
244249
}

src/Eloquent/Casts/ObjectId.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,8 @@ public function get($model, string $key, $value, array $attributes)
3737
*/
3838
public function set($model, string $key, $value, array $attributes)
3939
{
40-
if ($value instanceof BSONObjectId) {
41-
return $value;
42-
}
40+
$value = $value instanceof BSONObjectId ? $value : new BSONObjectId($value);
4341

44-
return new BSONObjectId($value);
42+
return [$key => $value];
4543
}
4644
}

src/Eloquent/Model.php

Lines changed: 20 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
use Illuminate\Support\Str;
1616
use function in_array;
1717
use Jenssegers\Mongodb\Query\Builder as QueryBuilder;
18-
use MongoDB\BSON\Binary;
19-
use MongoDB\BSON\ObjectID;
2018
use MongoDB\BSON\UTCDateTime;
2119
use function uniqid;
2220

@@ -52,30 +50,6 @@ abstract class Model extends BaseModel
5250
*/
5351
protected $parentRelation;
5452

55-
/**
56-
* Custom accessor for the model's id.
57-
*
58-
* @param mixed $value
59-
* @return mixed
60-
*/
61-
public function getIdAttribute($value = null)
62-
{
63-
// If we don't have a value for 'id', we will use the MongoDB '_id' value.
64-
// This allows us to work with models in a more sql-like way.
65-
if (! $value && array_key_exists('_id', $this->attributes)) {
66-
$value = $this->attributes['_id'];
67-
}
68-
69-
// Convert ObjectID to string.
70-
if ($value instanceof ObjectID) {
71-
return (string) $value;
72-
} elseif ($value instanceof Binary) {
73-
return (string) $value->getData();
74-
}
75-
76-
return $value;
77-
}
78-
7953
/**
8054
* @inheritdoc
8155
*/
@@ -190,12 +164,7 @@ protected function getAttributeFromArray($key)
190164
public function setAttribute($key, $value)
191165
{
192166
// Convert _id to ObjectID.
193-
if ($key == '_id' && is_string($value)) {
194-
$builder = $this->newBaseQueryBuilder();
195-
196-
$value = $builder->convertKey($value);
197-
} // Support keys in dot notation.
198-
elseif (Str::contains($key, '.')) {
167+
if (Str::contains($key, '.')) {
199168
// Store to a temporary key, then move data to the actual key
200169
$uniqueKey = uniqid($key);
201170
parent::setAttribute($uniqueKey, $value);
@@ -209,28 +178,6 @@ public function setAttribute($key, $value)
209178
return parent::setAttribute($key, $value);
210179
}
211180

212-
/**
213-
* @inheritdoc
214-
*/
215-
public function attributesToArray()
216-
{
217-
$attributes = parent::attributesToArray();
218-
219-
// Because the original Eloquent never returns objects, we convert
220-
// MongoDB related objects to a string representation. This kind
221-
// of mimics the SQL behaviour so that dates are formatted
222-
// nicely when your models are converted to JSON.
223-
foreach ($attributes as $key => &$value) {
224-
if ($value instanceof ObjectID) {
225-
$value = (string) $value;
226-
} elseif ($value instanceof Binary) {
227-
$value = (string) $value->getData();
228-
}
229-
}
230-
231-
return $attributes;
232-
}
233-
234181
/**
235182
* @inheritdoc
236183
*/
@@ -568,4 +515,23 @@ protected function addCastAttributesToArray(array $attributes, array $mutatedAtt
568515

569516
return $attributes;
570517
}
518+
519+
/** @internal */
520+
public function convertKey($value)
521+
{
522+
if (! $this->hasCast($this->primaryKey)) {
523+
return $value;
524+
}
525+
526+
return $this->castAttribute($this->primaryKey, $value);
527+
}
528+
529+
protected function getClassCastableAttributeValue($key, $value)
530+
{
531+
// The class cast cache does not play nice with database values that
532+
// already are objects, so we need to manually unset it
533+
unset($this->classCastCache[$key]);
534+
535+
return parent::getClassCastableAttributeValue($key, $value);
536+
}
571537
}

src/Query/Builder.php

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public function hint($index)
188188
*/
189189
public function find($id, $columns = [])
190190
{
191-
return $this->where('_id', '=', $this->convertKey($id))->first($columns);
191+
return parent::find($id, $columns);
192192
}
193193

194194
/**
@@ -884,25 +884,6 @@ protected function performUpdate($query, array $options = [])
884884
return 0;
885885
}
886886

887-
/**
888-
* Convert a key to ObjectID if needed.
889-
*
890-
* @param mixed $id
891-
* @return mixed
892-
*/
893-
public function convertKey($id)
894-
{
895-
if (is_string($id) && strlen($id) === 24 && ctype_xdigit($id)) {
896-
return new ObjectID($id);
897-
}
898-
899-
if (is_string($id) && strlen($id) === 16 && preg_match('~[^\x20-\x7E\t\r\n]~', $id) > 0) {
900-
return new Binary($id, Binary::TYPE_UUID);
901-
}
902-
903-
return $id;
904-
}
905-
906887
/**
907888
* @inheritdoc
908889
*/
@@ -950,19 +931,6 @@ protected function compileWheres(): array
950931
}
951932
}
952933

953-
// Convert id's.
954-
if (isset($where['column']) && ($where['column'] == '_id' || Str::endsWith($where['column'], '._id'))) {
955-
// Multiple values.
956-
if (isset($where['values'])) {
957-
foreach ($where['values'] as &$value) {
958-
$value = $this->convertKey($value);
959-
}
960-
} // Single value.
961-
elseif (isset($where['value'])) {
962-
$where['value'] = $this->convertKey($where['value']);
963-
}
964-
}
965-
966934
// Convert DateTime values to UTCDateTime.
967935
if (isset($where['value'])) {
968936
if (is_array($where['value'])) {

src/Relations/EmbedsOneOrMany.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,7 @@ protected function getForeignKeyValue($id)
245245
$id = $id->getKey();
246246
}
247247

248-
// Convert the id to MongoId if necessary.
249-
return $this->toBase()->convertKey($id);
248+
return $id;
250249
}
251250

252251
/**

tests/EmbeddedRelationsTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function testEmbedsManySave()
6060
$this->assertInstanceOf(DateTime::class, $address->created_at);
6161
$this->assertInstanceOf(DateTime::class, $address->updated_at);
6262
$this->assertNotNull($address->_id);
63-
$this->assertIsString($address->_id);
63+
$this->assertInstanceOf(ObjectId::class, $address->_id);
6464

6565
$raw = $address->getAttributes();
6666
$this->assertInstanceOf(ObjectId::class, $raw['_id']);
@@ -183,7 +183,7 @@ public function testEmbedsManyCreate()
183183
$user = User::create([]);
184184
$address = $user->addresses()->create(['city' => 'Bruxelles']);
185185
$this->assertInstanceOf(Address::class, $address);
186-
$this->assertIsString($address->_id);
186+
$this->assertInstanceOf(ObjectId::class, $address->_id);
187187
$this->assertEquals(['Bruxelles'], $user->addresses->pluck('city')->all());
188188

189189
$raw = $address->getAttributes();

tests/ModelTest.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public function testUpdate(): void
8686

8787
/** @var User $check */
8888
$check = User::find($user->_id);
89+
$this->assertInstanceOf(User::class, $check);
8990
$check->age = 36;
9091
$check->save();
9192

@@ -395,22 +396,24 @@ public static function provideId(): iterable
395396
yield 'ObjectID' => [
396397
'model' => User::class,
397398
'id' => $objectId,
398-
'expected' => (string) $objectId,
399-
'expectedFound' => true,
399+
'expected' => $objectId,
400+
// Not found as the keyType is "string"
401+
'expectedFound' => false,
400402
];
401403

402404
$binaryUuid = new Binary(hex2bin('0c103357380648c9a84b867dcb625cfb'), Binary::TYPE_UUID);
403405
yield 'BinaryUuid' => [
404406
'model' => User::class,
405407
'id' => $binaryUuid,
406-
'expected' => (string) $binaryUuid,
407-
'expectedFound' => true,
408+
'expected' => $binaryUuid,
409+
// Not found as the keyType is "string"
410+
'expectedFound' => false,
408411
];
409412

410413
yield 'cast as BinaryUuid' => [
411414
'model' => IdIsBinaryUuid::class,
412415
'id' => $binaryUuid,
413-
'expected' => (string) $binaryUuid,
416+
'expected' => $binaryUuid,
414417
'expectedFound' => true,
415418
];
416419

tests/Models/Address.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@
44

55
namespace Jenssegers\Mongodb\Tests\Models;
66

7+
use Jenssegers\Mongodb\Eloquent\Casts\ObjectId as ObjectIdCast;
78
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
89
use Jenssegers\Mongodb\Relations\EmbedsMany;
10+
use MongoDB\BSON\ObjectId;
911

1012
class Address extends Eloquent
1113
{
1214
protected $connection = 'mongodb';
1315
protected static $unguarded = true;
16+
protected $keyType = ObjectId::class;
17+
18+
protected $casts = [
19+
'_id' => ObjectIdCast::class,
20+
];
1421

1522
public function addresses(): EmbedsMany
1623
{

tests/Models/User.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Illuminate\Database\Eloquent\Casts\Attribute;
1313
use Illuminate\Notifications\Notifiable;
1414
use Illuminate\Support\Str;
15+
use Jenssegers\Mongodb\Eloquent\Casts\ObjectId as ObjectIdCast;
1516
use Jenssegers\Mongodb\Eloquent\HybridRelations;
1617
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
1718

@@ -38,6 +39,7 @@ class User extends Eloquent implements AuthenticatableContract, CanResetPassword
3839

3940
protected $connection = 'mongodb';
4041
protected $casts = [
42+
'_id' => ObjectIdCast::class,
4143
'birthday' => 'datetime',
4244
'entry.date' => 'datetime',
4345
'member_status' => MemberStatus::class,

0 commit comments

Comments
 (0)