Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
laravel-mongodb
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sinan
laravel-mongodb
Commits
f249b3be
Commit
f249b3be
authored
Mar 20, 2014
by
Jens Segers
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #164 from duxet/embedded-events
Trigger events in embedded models
parents
d7ac7b07
21d973ad
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
176 additions
and
5 deletions
+176
-5
.travis.yml
.travis.yml
+1
-0
Connection.php
src/Jenssegers/Mongodb/Connection.php
+10
-0
EmbedsMany.php
src/Jenssegers/Mongodb/Relations/EmbedsMany.php
+83
-5
RelationsTest.php
tests/RelationsTest.php
+82
-0
No files found.
.travis.yml
View file @
f249b3be
...
...
@@ -18,6 +18,7 @@ before_script:
-
mysql -e 'create database unittest;'
-
composer self-update
-
composer require satooshi/php-coveralls:dev-master
-
composer require mockery/mockery:dev-master
-
composer install --dev --no-interaction
script
:
...
...
src/Jenssegers/Mongodb/Connection.php
View file @
f249b3be
...
...
@@ -173,6 +173,16 @@ class Connection extends \Illuminate\Database\Connection {
return
parent
::
getElapsedTime
(
$start
);
}
/**
* Get the PDO driver name.
*
* @return string
*/
public
function
getDriverName
()
{
return
''
;
}
/**
* Dynamically pass methods to the connection.
*
...
...
src/Jenssegers/Mongodb/Relations/EmbedsMany.php
View file @
f249b3be
...
...
@@ -133,6 +133,24 @@ class EmbedsMany extends Relation {
return
$this
->
getResults
();
}
/**
* Get the results with given ids.
*
* @param array $ids
* @return \Illuminate\Database\Eloquent\Collection
*/
public
function
find
(
array
$ids
)
{
$documents
=
$this
->
getEmbeddedRecords
();
$primaryKey
=
$this
->
related
->
getKeyName
();
$documents
=
array_filter
(
$documents
,
function
(
$document
)
use
(
$primaryKey
,
$ids
)
{
return
in_array
(
$document
[
$primaryKey
],
$ids
);
});
return
$this
->
toCollection
(
$documents
);
}
/**
* Attach a model instance to the parent model.
*
...
...
@@ -141,19 +159,29 @@ class EmbedsMany extends Relation {
*/
public
function
save
(
Model
$model
)
{
if
(
$this
->
fireModelEvent
(
$model
,
'saving'
)
===
false
)
return
false
;
$this
->
updateTimestamps
(
$model
);
// Insert a new document.
if
(
!
$model
->
exists
)
{
return
$this
->
performInsert
(
$model
);
$result
=
$this
->
performInsert
(
$model
);
}
// Update an existing document.
else
{
return
$this
->
performUpdate
(
$model
);
$result
=
$this
->
performUpdate
(
$model
);
}
if
(
$result
)
{
$this
->
fireModelEvent
(
$result
,
'saved'
,
false
);
return
$result
;
}
return
false
;
}
/**
...
...
@@ -186,13 +214,21 @@ class EmbedsMany extends Relation {
*/
protected
function
performInsert
(
Model
$model
)
{
if
(
$this
->
fireModelEvent
(
$model
,
'creating'
)
===
false
)
return
false
;
// Insert the related model in the parent instance
$this
->
associateNew
(
$model
);
// Push the document to the database.
$result
=
$this
->
query
->
push
(
$this
->
localKey
,
$model
->
getAttributes
(),
true
);
return
$result
?
$model
:
false
;
if
(
$result
)
{
$this
->
fireModelEvent
(
$model
,
'created'
,
false
);
return
$model
;
}
return
false
;
}
/**
...
...
@@ -203,6 +239,8 @@ class EmbedsMany extends Relation {
*/
protected
function
performUpdate
(
Model
$model
)
{
if
(
$this
->
fireModelEvent
(
$model
,
'updating'
)
===
false
)
return
false
;
// Update the related model in the parent instance
$this
->
associateExisting
(
$model
);
...
...
@@ -213,7 +251,13 @@ class EmbedsMany extends Relation {
$result
=
$this
->
query
->
where
(
$this
->
localKey
.
'.'
.
$model
->
getKeyName
(),
$id
)
->
update
(
array
(
$this
->
localKey
.
'.$'
=>
$model
->
getAttributes
()));
return
$result
?
$model
:
false
;
if
(
$result
)
{
$this
->
fireModelEvent
(
$model
,
'updated'
,
false
);
return
$model
;
}
return
false
;
}
/**
...
...
@@ -327,12 +371,23 @@ class EmbedsMany extends Relation {
{
$ids
=
$this
->
getIdsArrayFrom
(
$ids
);
$models
=
$this
->
find
(
$ids
);
$ids
=
array
();
$primaryKey
=
$this
->
related
->
getKeyName
();
// Pull the documents from the database.
foreach
(
$
ids
as
$id
)
foreach
(
$
models
as
$model
)
{
if
(
$this
->
fireModelEvent
(
$model
,
'deleting'
)
===
false
)
continue
;
$id
=
$model
->
getKey
();
$this
->
query
->
pull
(
$this
->
localKey
,
array
(
$primaryKey
=>
$this
->
getForeignKeyValue
(
$id
)));
$ids
[]
=
$id
;
$this
->
fireModelEvent
(
$model
,
'deleted'
,
false
);
}
return
$this
->
dissociate
(
$ids
);
...
...
@@ -511,4 +566,27 @@ class EmbedsMany extends Relation {
return
$this
->
getBaseQuery
()
->
convertKey
(
$id
);
}
/**
* Fire the given event for the given model.
*
* @param string $event
* @param bool $halt
* @return mixed
*/
protected
function
fireModelEvent
(
Model
$model
,
$event
,
$halt
=
true
)
{
$dispatcher
=
$model
->
getEventDispatcher
();
if
(
is_null
(
$dispatcher
))
return
true
;
// We will append the names of the class to the event to distinguish it from
// other model events that are fired, allowing us to listen on each model
// event set individually instead of catching event for all the models.
$event
=
"eloquent.
{
$event
}
: "
.
get_class
(
$model
);
$method
=
$halt
?
'until'
:
'fire'
;
return
$dispatcher
->
$method
(
$event
,
$model
);
}
}
tests/RelationsTest.php
View file @
f249b3be
...
...
@@ -9,6 +9,8 @@ class RelationsTest extends PHPUnit_Framework_TestCase {
public
function
tearDown
()
{
Mockery
::
close
();
User
::
truncate
();
Book
::
truncate
();
Item
::
truncate
();
...
...
@@ -297,7 +299,15 @@ class RelationsTest extends PHPUnit_Framework_TestCase {
$user
=
User
::
create
(
array
(
'name'
=>
'John Doe'
));
$address
=
new
Address
(
array
(
'city'
=>
'London'
));
$address
->
setEventDispatcher
(
$events
=
Mockery
::
mock
(
'Illuminate\Events\Dispatcher'
));
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.saving: '
.
get_class
(
$address
),
$address
)
->
andReturn
(
true
);
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.creating: '
.
get_class
(
$address
),
$address
)
->
andReturn
(
true
);
$events
->
shouldReceive
(
'fire'
)
->
once
()
->
with
(
'eloquent.created: '
.
get_class
(
$address
),
$address
);
$events
->
shouldReceive
(
'fire'
)
->
once
()
->
with
(
'eloquent.saved: '
.
get_class
(
$address
),
$address
);
$address
=
$user
->
addresses
()
->
save
(
$address
);
$address
->
unsetEventDispatcher
();
$this
->
assertNotNull
(
$user
->
_addresses
);
$this
->
assertEquals
(
array
(
'London'
),
$user
->
addresses
->
lists
(
'city'
));
$this
->
assertInstanceOf
(
'DateTime'
,
$address
->
created_at
);
...
...
@@ -309,8 +319,15 @@ class RelationsTest extends PHPUnit_Framework_TestCase {
$user
=
User
::
find
(
$user
->
_id
);
$this
->
assertEquals
(
array
(
'London'
,
'Paris'
),
$user
->
addresses
->
lists
(
'city'
));
$address
->
setEventDispatcher
(
$events
=
Mockery
::
mock
(
'Illuminate\Events\Dispatcher'
));
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.saving: '
.
get_class
(
$address
),
$address
)
->
andReturn
(
true
);
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.updating: '
.
get_class
(
$address
),
$address
)
->
andReturn
(
true
);
$events
->
shouldReceive
(
'fire'
)
->
once
()
->
with
(
'eloquent.updated: '
.
get_class
(
$address
),
$address
);
$events
->
shouldReceive
(
'fire'
)
->
once
()
->
with
(
'eloquent.saved: '
.
get_class
(
$address
),
$address
);
$address
->
city
=
'New York'
;
$user
->
addresses
()
->
save
(
$address
);
$address
->
unsetEventDispatcher
();
$this
->
assertEquals
(
2
,
count
(
$user
->
addresses
));
$this
->
assertEquals
(
2
,
count
(
$user
->
addresses
()
->
get
()));
...
...
@@ -403,9 +420,16 @@ class RelationsTest extends PHPUnit_Framework_TestCase {
$user
->
addresses
()
->
saveMany
(
array
(
new
Address
(
array
(
'city'
=>
'London'
)),
new
Address
(
array
(
'city'
=>
'Bristol'
)),
new
Address
(
array
(
'city'
=>
'Bruxelles'
))));
$address
=
$user
->
addresses
->
first
();
$address
->
setEventDispatcher
(
$events
=
Mockery
::
mock
(
'Illuminate\Events\Dispatcher'
));
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.deleting: '
.
get_class
(
$address
),
Mockery
::
mustBe
(
$address
))
->
andReturn
(
true
);
$events
->
shouldReceive
(
'fire'
)
->
once
()
->
with
(
'eloquent.deleted: '
.
get_class
(
$address
),
Mockery
::
mustBe
(
$address
));
$user
->
addresses
()
->
destroy
(
$address
->
_id
);
$this
->
assertEquals
(
array
(
'Bristol'
,
'Bruxelles'
),
$user
->
addresses
->
lists
(
'city'
));
$address
->
unsetEventDispatcher
();
$address
=
$user
->
addresses
->
first
();
$user
->
addresses
()
->
destroy
(
$address
);
$this
->
assertEquals
(
array
(
'Bruxelles'
),
$user
->
addresses
->
lists
(
'city'
));
...
...
@@ -452,4 +476,62 @@ class RelationsTest extends PHPUnit_Framework_TestCase {
$this
->
assertEquals
(
array
(),
$user
->
addresses
->
lists
(
'city'
));
}
public
function
testEmbedsManyCreatingEventReturnsFalse
()
{
$user
=
User
::
create
(
array
(
'name'
=>
'John Doe'
));
$address
=
new
Address
(
array
(
'city'
=>
'London'
));
$address
->
setEventDispatcher
(
$events
=
Mockery
::
mock
(
'Illuminate\Events\Dispatcher'
));
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.saving: '
.
get_class
(
$address
),
$address
)
->
andReturn
(
true
);
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.creating: '
.
get_class
(
$address
),
$address
)
->
andReturn
(
false
);
$this
->
assertFalse
(
$user
->
addresses
()
->
save
(
$address
));
$address
->
unsetEventDispatcher
();
}
public
function
testEmbedsManySavingEventReturnsFalse
()
{
$user
=
User
::
create
(
array
(
'name'
=>
'John Doe'
));
$address
=
new
Address
(
array
(
'city'
=>
'Paris'
));
$address
->
exists
=
true
;
$address
->
setEventDispatcher
(
$events
=
Mockery
::
mock
(
'Illuminate\Events\Dispatcher'
));
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.saving: '
.
get_class
(
$address
),
$address
)
->
andReturn
(
false
);
$this
->
assertFalse
(
$user
->
addresses
()
->
save
(
$address
));
$address
->
unsetEventDispatcher
();
}
public
function
testEmbedsManyUpdatingEventReturnsFalse
()
{
$user
=
User
::
create
(
array
(
'name'
=>
'John Doe'
));
$address
=
new
Address
(
array
(
'city'
=>
'New York'
));
$address
->
exists
=
true
;
$address
->
setEventDispatcher
(
$events
=
Mockery
::
mock
(
'Illuminate\Events\Dispatcher'
));
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.saving: '
.
get_class
(
$address
),
$address
)
->
andReturn
(
true
);
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.updating: '
.
get_class
(
$address
),
$address
)
->
andReturn
(
false
);
$address
->
city
=
'Warsaw'
;
$this
->
assertFalse
(
$user
->
addresses
()
->
save
(
$address
));
$address
->
unsetEventDispatcher
();
}
public
function
testEmbedsManyDeletingEventReturnsFalse
()
{
$user
=
User
::
create
(
array
(
'name'
=>
'John Doe'
));
$user
->
addresses
()
->
save
(
new
Address
(
array
(
'city'
=>
'New York'
)));
$address
=
$user
->
addresses
->
first
();
$address
->
setEventDispatcher
(
$events
=
Mockery
::
mock
(
'Illuminate\Events\Dispatcher'
));
$events
->
shouldReceive
(
'until'
)
->
once
()
->
with
(
'eloquent.deleting: '
.
get_class
(
$address
),
Mockery
::
mustBe
(
$address
))
->
andReturn
(
false
);
$this
->
assertEquals
(
0
,
$user
->
addresses
()
->
destroy
(
$address
));
$this
->
assertEquals
(
array
(
'New York'
),
$user
->
addresses
->
lists
(
'city'
));
$address
->
unsetEventDispatcher
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment