Skip to content

Commit

Permalink
support queueing collections
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed May 31, 2016
1 parent d5bbda9 commit d159f02
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/Illuminate/Contracts/Database/ModelIdentifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class ModelIdentifier
/**
* The unique identifier of the model.
*
* This may be either a single ID or an array of IDs.
*
* @var mixed
*/
public $id;
Expand Down
36 changes: 35 additions & 1 deletion src/Illuminate/Database/Eloquent/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace Illuminate\Database\Eloquent;

use LogicException;
use Illuminate\Support\Arr;
use Illuminate\Contracts\Queue\QueueableCollection;
use Illuminate\Support\Collection as BaseCollection;

class Collection extends BaseCollection
class Collection extends BaseCollection implements QueueableCollection
{
/**
* Find a model in the collection by key.
Expand Down Expand Up @@ -321,6 +323,38 @@ public function flip()
return $this->toBase()->flip();
}

/**
* Get the type of the entities being queued.
*
* @return string|null
*/
public function getQueueableClass()
{
if ($this->count() === 0) {
return;
}

$class = get_class($this->first());

$this->each(function ($model) use ($class) {
if (get_class($model) !== $class) {
throw new LogicException("Queueing collections with multiple model types is not supported.");
}
});

return $class;
}

/**
* Get the identifiers for all of the entities.
*
* @return array
*/
public function getQueueableIds()
{
return $this->modelKeys();
}

/**
* Get a base Support collection instance from this collection.
*
Expand Down
41 changes: 36 additions & 5 deletions src/Illuminate/Queue/SerializesModels.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
use ReflectionProperty;
use Illuminate\Contracts\Queue\QueueableEntity;
use Illuminate\Contracts\Database\ModelIdentifier;
use Illuminate\Contracts\Queue\QueueableCollection;
use Illuminate\Database\Eloquent\Collection as EloquentCollection;

trait SerializesModels
{
Expand Down Expand Up @@ -51,8 +53,15 @@ public function __wakeup()
*/
protected function getSerializedPropertyValue($value)
{
return $value instanceof QueueableEntity
? new ModelIdentifier(get_class($value), $value->getQueueableId()) : $value;
if ($value instanceof QueueableCollection) {
return new ModelIdentifier($value->getQueueableClass(), $value->getQueueableIds());
}

if ($value instanceof QueueableEntity) {
return new ModelIdentifier(get_class($value), $value->getQueueableId());
}

return $value;
}

/**
Expand All @@ -63,9 +72,31 @@ protected function getSerializedPropertyValue($value)
*/
protected function getRestoredPropertyValue($value)
{
return $value instanceof ModelIdentifier
? (new $value->class)->newQuery()->useWritePdo()->findOrFail($value->id)
: $value;
if (! $value instanceof ModelIdentifier) {
return $value;
}

return is_array($value->id)
? $this->restoreCollection($value)
: (new $value->class)->newQuery()->useWritePdo()->findOrFail($value->id);
}

/**
* Restore a queueable collection instance.
*
* @param \Illuminate\Contracts\Database\ModelIdentifier $value
* @return \Illuminate\Database\Eloquent\Collection
*/
protected function restoreCollection($value)
{
if (! $value->class || count($value->id) === 0) {
return new EloquentCollection;
}

$model = new $value->class;

return $model->newQuery()->useWritePdo()
->whereIn($model->getKeyName(), $value->id)->get();
}

/**
Expand Down
15 changes: 15 additions & 0 deletions tests/Database/DatabaseEloquentCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,21 @@ public function testMakeVisibleRemovesHiddenAndIncludesVisible()
$this->assertEquals([], $c[0]->getHidden());
$this->assertEquals(['visible', 'hidden'], $c[0]->getVisible());
}

public function testQueueableCollectionImplementation()
{
$c = new Collection([new TestEloquentCollectionModel, new TestEloquentCollectionModel]);
$this->assertEquals(TestEloquentCollectionModel::class, $c->getQueueableClass());
}

/**
* @expectedException LogicException
*/
public function testQueueableCollectionImplementationThrowsExceptionOnMultipleModelTypes()
{
$c = new Collection([new TestEloquentCollectionModel, (object) ['id' => 'something']]);
$c->getQueueableClass();
}
}

class TestEloquentCollectionModel extends Illuminate\Database\Eloquent\Model
Expand Down

0 comments on commit d159f02

Please sign in to comment.