Skip to content
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

CollectionProxy::count() enhancements and various fixes/improvements #252

Merged
merged 8 commits into from
Feb 23, 2018
4 changes: 3 additions & 1 deletion src/EntityMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,9 @@ public function getEmbeddables(): array
*/
public function getProperties(): array
{
return $this->properties;
return get_parent_class(__CLASS__) !== false
? array_unique(array_merge($this->properties, parent::getProperties()))
: $this->properties;
}

/**
Expand Down
50 changes: 41 additions & 9 deletions src/System/Proxies/CollectionProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Analogue\ORM\System\Proxies;

use Analogue\ORM\EntityCollection;
use Analogue\ORM\Relationships\Relationship;
use Analogue\ORM\System\Manager;
use CachingIterator;
use Illuminate\Support\Collection;
Expand Down Expand Up @@ -73,18 +74,28 @@ public function initializeProxy() : bool
return true;
}

$relation = $this->relationshipMethod;
$entity = $this->parentEntity;

$entityMap = Manager::getMapper($entity)->getEntityMap();

$this->items = $entityMap->$relation($entity)->getResults($relation)->all() + $this->addedItems;
$this->items = $this->getRelationshipInstance()
->getResults($this->relationshipMethod)->all() + $this->addedItems;

$this->relationshipLoaded = true;

return true;
}

/**
* Return instance of the underlying relationship.
*
* @return Relationship
*/
protected function getRelationshipInstance() : Relationship
{
$relation = $this->relationshipMethod;
$entity = $this->parentEntity;
$entityMap = Manager::getMapper($entity)->getEntityMap();

return $entityMap->$relation($entity);
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -187,6 +198,18 @@ public function diff($items)
return $parent->diff($items);
}

/**
* {@inheritdoc}
*/
public function diffUsing($items, callable $callback)
{
$this->initializeProxy();

$parent = $this->toBaseCollection();

return $parent->diff($items, $callback);
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -1109,10 +1132,19 @@ public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING)
*/
public function count()
{
// TODO rely on QB if not initialized
$this->initializeProxy();
return $this->relationshipLoaded
? parent::count()
: $this->countUsingDatabaseQuery();
}

return parent::count();
/**
* Do a count query and return the result.
*
* @return int
*/
protected function countUsingDatabaseQuery() : int
{
return $this->getRelationshipInstance()->count();
}

/**
Expand Down
36 changes: 35 additions & 1 deletion tests/cases/CollectionProxyTest.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php


use Analogue\ORM\System\Proxies\CollectionProxy;
use Illuminate\Support\Collection;
use TestApp\User;

class CollectionProxyTest extends DomainTestCase
{
Expand Down Expand Up @@ -57,6 +57,18 @@ public function all_collection_methods_are_overloaded()
$this->assertTrue(true);
}

/** @test */
public function we_can_do_a_count_operation_on_proxy_without_loading_it()
{
$id = $this->createRelatedSet(3);
$user = mapper(User::class)->find($id);
$this->assertFalse($user->groups->isProxyInitialized());
$this->assertEquals(3, $user->groups->count());
$this->assertFalse($user->groups->isProxyInitialized());
$this->assertCount(3, $user->groups->all());
$this->assertTrue($user->groups->isProxyInitialized());
}

/** @test */
public function we_can_push_to_a_collection_proxy_without_loading_it()
{
Expand All @@ -66,4 +78,26 @@ public function we_can_push_to_a_collection_proxy_without_loading_it()
public function we_can_remove_from_a_lazy_collection_without_loading_it()
{
}

/**
* Create a random related set.
*
* @return int
*/
protected function createRelatedSet($relatedCount = 1)
{
$userId = $this->insertUser();
for ($x = 1; $x <= $relatedCount; $x++) {
$groupId = $this->rawInsert('groups', [
'id' => $this->randId(),
'name' => $this->faker()->sentence,
]);
$this->rawInsert('groups_users', [
'user_id' => $userId,
'group_id' => $groupId,
]);
}

return $userId;
}
}