Skip to content

Commit

Permalink
More finegrained control over unreferenced entity trimming
Browse files Browse the repository at this point in the history
  • Loading branch information
prewk committed Oct 27, 2016
1 parent 1f2a557 commit 3a8569e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
29 changes: 25 additions & 4 deletions src/Seriquent.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace Prewk;

use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Container\Container;
use Prewk\Seriquent\Deserialization\BookKeeper as DeserializeBookKeeper;
Expand Down Expand Up @@ -99,7 +100,7 @@ public static function make($prefix = "@")
* @param array $trimUnreferenced Remove unreferenced entities from the serialization tree before returning it,
* by providing this parameter with an array of FQCNs
* @return array
* @throws \Exception
* @throws Exception
*/
public function serialize(Model $model, array $customRules = [], array $trimUnreferenced = [])
{
Expand All @@ -111,21 +112,41 @@ public function serialize(Model $model, array $customRules = [], array $trimUnre

// Trim unreferenced entities?
if (count($trimUnreferenced) > 0) {
// Yep, get the ref count
// Support both [.., "FQCN", ..] and [.., "FQCN" => Closure, ..]
$trimmables = [];
foreach ($trimUnreferenced as $key => $value) {
if (is_int($key) && is_string($value)) {
$trimmables[] = $value;
} else if (is_string($key) && $value instanceof Closure) {
$trimmables[] = $key;
} else {
throw new Exception("Invalid trimUnreferenced array item given, expected int=>string or string=>closure");
}
}

// Get the ref count
$refCount = $this->serializer->getRefCount();
$trimmed = [];
// Iterate through all entity types
foreach ($serialization as $fqcn => $entities) {
// Look for possible trimming here?
if (in_array($fqcn, $trimUnreferenced)) {
if (in_array($fqcn, $trimmables)) {
// Yes
$trimmed[$fqcn] = [];
// Iterate through all the entities of this FQCN
foreach ($entities as $entity) {
$id = $entity["@id"];
// Any refs for this id?
if (isset($refCount[$id])) {
// Reference found - keep
// Reference found - keep?
if (isset($trimUnreferenced[$fqcn]) && $trimUnreferenced[$fqcn]($entity, true)) {
// Callable decided it should stay
$trimmed[$fqcn][] = $entity;
} else {
// Keep
$trimmed[$fqcn][] = $entity;
}
} else if (isset($trimUnreferenced[$fqcn]) && $trimUnreferenced[$fqcn]($entity, false)) {
$trimmed[$fqcn][] = $entity;
}
}
Expand Down
14 changes: 10 additions & 4 deletions tests/integration/SeriquentIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1265,15 +1265,21 @@ public function test_serialize_with_unreferenced_entity_trimming()
$root = Root::findOrFail($books["@1"]);

// Re-serialize and trim away unreferenced Polys and Bars
$reserialization = $seriquent->serialize($root, [], ["Prewk\\Seriquent\\Models\\Poly", "Prewk\\Seriquent\\Models\\Bar"]);
$reserialization = $seriquent->serialize($root, [], ["Prewk\\Seriquent\\Models\\Poly" => function($entity, $referenceFound) {
// Assert that there are no references
$this->assertFalse($referenceFound);

// Only save poly if test equals Four
return $entity["test"] === "Four";
}, "Prewk\\Seriquent\\Models\\Bar"]);

// Assert
// There should be no Polys left in the serialization
$this->assertEquals(0, count($reserialization["Prewk\\Seriquent\\Models\\Poly"]));
// There should be one Poly left in the serialization
$this->assertEquals(1, count($reserialization["Prewk\\Seriquent\\Models\\Poly"]));
$this->assertEquals("Four", $reserialization["Prewk\\Seriquent\\Models\\Poly"][0]["test"]);
// There should be a Bar left, because it was referenced
$this->assertTrue(isset($reserialization["Prewk\\Seriquent\\Models\\Bar"]));
$this->assertTrue(isset($reserialization["Prewk\\Seriquent\\Models\\Bar"][0]));
$this->assertEquals("Test test", $reserialization["Prewk\\Seriquent\\Models\\Bar"][0]["test"]);
}

}

0 comments on commit 3a8569e

Please sign in to comment.