-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cast data before saving it into database and mongoId as Relationships #834
Closed
Closed
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
afc57a0
add save cast to cast data before saving data into mongoDB
RTLer 81d2279
fix addHasWhere to always have string in array_count_values
RTLer dc20406
fix addHasWhere to get proper id's from castAttribute
RTLer 8ce502a
overwrite eloquent cast methods to make that work for set data too
RTLer ecf8feb
fix BelongsTo's match method
RTLer 0aa0297
add HasOneOrManyTrait trait
RTLer 879f087
set one and many relations to use HasOneOrManyTrait
RTLer c7f7f37
set test to run with use_mongo_id:true
RTLer 427582e
add morph one and many classes to make it use HasOneOrManyTrait
RTLer 6b0d504
fix buildDictionary in EloquentMorphTo class
RTLer c5aef81
cleanup Model class
RTLer b886303
add useMongoId to check if driver uses mongoId in relations
RTLer d05d237
add relation tests that tests new cast part
RTLer dd6923e
cleanup the code
RTLer dbbab06
add setter for casts
RTLer 1bf882f
cleanup
RTLer 68e798d
Merge branch 'jenssegers/master' into cast-data-befor-saving
RTLer 67775a2
Merge branch 'jenssegers/master' into cast-data-befor-saving
RTLer 27e36bb
Merge branch 'jenssegers/master' into cast-data-befor-saving
RTLer b3340b4
Merge branch 'jenssegers/master' into cast-data-befor-saving
RTLer 5029a4f
fix RelationsWithMongoIdTest
RTLer 54b9266
"StyleCI" code style fix
RTLer 2c70388
remove unnecessary use_mongo_id that enable use_mongo_id for all tests
RTLer 78707c0
remove missed patch file
RTLer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
diff --git a/src/Jenssegers/Mongodb/Eloquent/Model.php b/src/Jenssegers/Mongodb/Eloquent/Model.php | ||
index 3707c86cb7f732c97908d8ca3754118f4256e422..4a17b0f8c045b2d02f3f834ae0b207dccd2be311 100644 | ||
--- a/src/Jenssegers/Mongodb/Eloquent/Model.php | ||
+++ b/src/Jenssegers/Mongodb/Eloquent/Model.php | ||
@@ -615,7 +615,7 @@ abstract class Model extends BaseModel | ||
public function castAttribute($key, $value, $castType = 'get') | ||
{ | ||
if (is_null($value)) { | ||
- return null; | ||
+ return; | ||
} | ||
|
||
if (!$this->hasCast($key, null, $castType)) { | ||
diff --git a/tests/RelationsWithMongoIdTest.php b/tests/RelationsWithMongoIdTest.php | ||
index 8e78bf592b016b7a85609e699c6f0fa24c55dc0e..517c3be993b8eb68bae2349a061c6677be3cbfa7 100644 | ||
--- a/tests/RelationsWithMongoIdTest.php | ||
+++ b/tests/RelationsWithMongoIdTest.php | ||
@@ -533,15 +533,15 @@ class RelationsWithMongoIdTest extends TestCase | ||
$user = new User; | ||
$user->setCasts([ | ||
'last_seen' => 'UTCDatetime', | ||
- 'age'=>'int', | ||
- 'name'=>'string', | ||
- 'rate'=>'float', | ||
- 'birthday'=>'timestamp', | ||
- 'isActive'=>'bool', | ||
- 'default'=>'default', | ||
+ 'age' => 'int', | ||
+ 'name' => 'string', | ||
+ 'rate' => 'float', | ||
+ 'birthday' => 'timestamp', | ||
+ 'isActive' => 'bool', | ||
+ 'default' => 'default', | ||
], 'set'); | ||
$user->setCasts([ | ||
- 'name'=>'string', | ||
+ 'name' => 'string', | ||
]); | ||
$carbon = Carbon\Carbon::now(); | ||
$UTCDateTime = new \MongoDB\BSON\UTCDateTime($carbon->timestamp * 1000); | ||
@@ -562,5 +562,4 @@ class RelationsWithMongoIdTest extends TestCase | ||
$test = $user->castAttribute('default', 'test', 'set'); | ||
$this->assertEquals('test', $test); | ||
} | ||
- | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,13 @@ abstract class Model extends BaseModel | |
*/ | ||
protected $parentRelation; | ||
|
||
/** | ||
* The attributes that should be cast to native types. | ||
* | ||
* @var array | ||
*/ | ||
protected $saveCasts = []; | ||
|
||
/** | ||
* Custom accessor for the model's id. | ||
* | ||
|
@@ -290,15 +297,13 @@ protected function getAttributeFromArray($key) | |
*/ | ||
public function setAttribute($key, $value) | ||
{ | ||
// Convert _id to ObjectID. | ||
if ($key == '_id' and is_string($value)) { | ||
$builder = $this->newBaseQueryBuilder(); | ||
|
||
$value = $builder->convertKey($value); | ||
} | ||
// cast data for saving. | ||
// set _id to converted into ObjectID if its possible. | ||
$this->setRelationCast($key); | ||
$value = $this->castAttribute($key, $value, 'set'); | ||
|
||
// Support keys in dot notation. | ||
elseif (str_contains($key, '.')) { | ||
if (str_contains($key, '.')) { | ||
if (in_array($key, $this->getDates()) && $value) { | ||
$value = $this->fromDateTime($value); | ||
} | ||
|
@@ -340,16 +345,6 @@ public function attributesToArray() | |
return $attributes; | ||
} | ||
|
||
/** | ||
* Get the casts array. | ||
* | ||
* @return array | ||
*/ | ||
public function getCasts() | ||
{ | ||
return $this->casts; | ||
} | ||
|
||
/** | ||
* Determine if the new and old values for a given key are numerically equivalent. | ||
* | ||
|
@@ -552,4 +547,163 @@ public function __call($method, $parameters) | |
|
||
return parent::__call($method, $parameters); | ||
} | ||
|
||
/** | ||
* setter for casts | ||
* @param $cast | ||
* @param string $castType | ||
* @return void | ||
*/ | ||
public function setCasts($cast, $castType = 'get') | ||
{ | ||
if ($castType == 'set') { | ||
$this->saveCasts = $cast; | ||
return; | ||
} | ||
$this->casts = $cast; | ||
} | ||
|
||
/** | ||
* Get the casts array. | ||
* | ||
* @param string $castType | ||
* @return array | ||
*/ | ||
public function getCasts($castType = 'get') | ||
{ | ||
if ($castType == 'set') { | ||
return $this->saveCasts; | ||
} | ||
return $this->casts; | ||
} | ||
|
||
/** | ||
* Get the type of save cast for a model attribute. | ||
* | ||
* @param string $key | ||
* @param string $castType | ||
* @return string | ||
*/ | ||
protected function getCastType($key, $castType = 'get') | ||
{ | ||
return trim(strtolower($this->getCasts($castType)[$key])); | ||
} | ||
|
||
/** | ||
* Determine whether an attribute should be cast to a native type. | ||
* | ||
* @param string $key | ||
* @param array|string|null $types | ||
* @param string $castType | ||
* @return bool | ||
*/ | ||
public function hasCast($key, $types = null, $castType = 'get') | ||
{ | ||
if (array_key_exists($key, $this->getCasts($castType))) { | ||
return $types ? in_array($this->getCastType($key, $castType), (array) $types, true) : true; | ||
} | ||
|
||
return false; | ||
} | ||
/** | ||
* check if driver uses mongoId in relations. | ||
* | ||
* @return bool | ||
*/ | ||
public function useMongoId() | ||
{ | ||
return (bool) config('database.connections.mongodb.use_mongo_id', false); | ||
} | ||
|
||
/** | ||
* Cast an attribute to a mongo type. | ||
* | ||
* @param string $key | ||
* @param mixed $value | ||
* @param string $castType | ||
* @return mixed | ||
*/ | ||
public function castAttribute($key, $value, $castType = 'get') | ||
{ | ||
if (is_null($value)) { | ||
return; | ||
} | ||
|
||
if (!$this->hasCast($key, null, $castType)) { | ||
return $value; | ||
} | ||
|
||
switch ($this->getCastType($key, $castType)) { | ||
case 'int': | ||
case 'integer': | ||
return (int) $value; | ||
case 'real': | ||
case 'float': | ||
case 'double': | ||
return (float) $value; | ||
case 'string': | ||
return (string) $value; | ||
case 'bool': | ||
case 'boolean': | ||
return (bool) $value; | ||
case 'date': | ||
case 'utcdatetime': | ||
case 'mongodate': | ||
return $this->asMongoDate($value); | ||
case 'mongoid': | ||
case 'objectid': | ||
return $this->asMongoID($value); | ||
case 'timestamp': | ||
return $this->asTimeStamp($value); | ||
default: | ||
return $value; | ||
} | ||
} | ||
|
||
/** | ||
* convert value into ObjectID if its possible | ||
* | ||
* @param $value | ||
* @return UTCDatetime | ||
*/ | ||
protected function asMongoID($value) | ||
{ | ||
if (is_string($value) and strlen($value) === 24 and ctype_xdigit($value)) { | ||
return new ObjectID($value); | ||
} | ||
return $value; | ||
} | ||
|
||
/** | ||
* convert value into UTCDatetime | ||
* @param $value | ||
* @return UTCDatetime | ||
*/ | ||
protected function asMongoDate($value) | ||
{ | ||
if ($value instanceof UTCDatetime) { | ||
return $value; | ||
} | ||
|
||
return new UTCDatetime($this->asTimeStamp($value) * 1000); | ||
} | ||
|
||
/** | ||
* add relation that ended with _id into objectId | ||
* if config allow it | ||
* | ||
* @param $key | ||
*/ | ||
public function setRelationCast($key) | ||
{ | ||
if ($key == '_id') { | ||
$this->saveCasts['_id'] = 'ObjectID'; | ||
return; | ||
} | ||
if ($this->useMongoId()) { | ||
if (ends_with($key, '_id')) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about relations ending with |
||
$this->saveCasts[$key] = 'ObjectID'; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not this diff patch file be excluded from commit ?