From 55c1aa7bd1b65598dd1b05769a117cc9c42bc36a Mon Sep 17 00:00:00 2001 From: Gunther Konig Date: Sat, 12 Jul 2014 10:13:25 +0300 Subject: [PATCH 1/2] use LegacyValidator --- Manager/FilterValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Manager/FilterValidator.php b/Manager/FilterValidator.php index 246a411..6f435b6 100644 --- a/Manager/FilterValidator.php +++ b/Manager/FilterValidator.php @@ -46,7 +46,7 @@ public function validateFilters(array &$filters) } } - public function setValidator(Validator $validator) + public function setValidator(Validator\LegacyValidator $validator) { $this->validator = $validator; } From 15c667044367e56b2fdfc2196a5cd8c2cfed2bdb Mon Sep 17 00:00:00 2001 From: Gunther Konig Date: Sat, 12 Jul 2014 12:06:39 +0300 Subject: [PATCH 2/2] Implement directional connections in ConnectionManager::connect. userA follows userB doesn't imply userB follows userA (one way connection) but userA is friend with userB (hopefully :D) does (two way connection) --- Manager/ConnectionManager.php | 12 +++---- Manager/FilterValidator.php | 24 ++++++++----- Model/ConnectionInterface.php | 3 ++ .../DoctrineMongoDBConnectionRepository.php | 22 ++++++------ .../DoctrineOrmConnectionRepository.php | 31 ++++++++++------- ...octrineMongoDBConnectionRepositoryTest.php | 34 +++++++++++++++++++ .../DoctrineOrmConnectionRepositoryTest.php | 34 +++++++++++++++++++ 7 files changed, 124 insertions(+), 36 deletions(-) diff --git a/Manager/ConnectionManager.php b/Manager/ConnectionManager.php index bc4d475..d658ea0 100644 --- a/Manager/ConnectionManager.php +++ b/Manager/ConnectionManager.php @@ -34,9 +34,9 @@ class ConnectionManager implements ConnectionManagerInterface * * @throws AlreadyConnectedException When connection from source to destination already exists */ - public function connect(NodeInterface $source, NodeInterface $destination, $type) + public function connect(NodeInterface $source, NodeInterface $destination, $type, $direction = ConnectionInterface::DIRECTION_TWO_WAYS) { - $connection = $this->createConnection($source, $destination, $type); + $connection = $this->createConnection($source, $destination, $type, $direction); $this->getConnectionRepository()->update($connection); if ($this->dispatcher) { @@ -113,11 +113,11 @@ public function destroy(ConnectionInterface $connection) /** * {@inheritDoc} */ - public function areConnected(NodeInterface $nodeA, NodeInterface $nodeB, array $filters = array()) + public function areConnected(NodeInterface $nodeA, NodeInterface $nodeB, array $filters = array(), $direction = null) { $this->filterValidator->validateFilters($filters); - return $this->getConnectionRepository()->areConnected($nodeA, $nodeB, $filters); + return $this->getConnectionRepository()->areConnected($nodeA, $nodeB, $filters, $direction); } /** @@ -185,9 +185,9 @@ public function getConnections(NodeInterface $node, array $filters = array()) * @return \Kitano\ConnectionBundle\Model\ConnectionInterface * @throws \Kitano\ConnectionBundle\Exception\AlreadyConnectedException */ - protected function createConnection(NodeInterface $source, NodeInterface $destination, $type) + protected function createConnection(NodeInterface $source, NodeInterface $destination, $type, $direction = ConnectionInterface::DIRECTION_TWO_WAYS) { - if ($this->areConnected($source, $destination, array('type' => $type))) { + if ($this->areConnected($source, $destination, array('type' => $type, 'direction' => $direction))) { throw new AlreadyConnectedException( sprintf('Objects %s (%s) and %s (%s) are already connected', get_class($source), diff --git a/Manager/FilterValidator.php b/Manager/FilterValidator.php index 6f435b6..b54ff07 100644 --- a/Manager/FilterValidator.php +++ b/Manager/FilterValidator.php @@ -4,8 +4,9 @@ use Kitano\ConnectionBundle\Exception\InvalidFilterException; +use Kitano\ConnectionBundle\Model\ConnectionInterface; +use Symfony\Component\Validator\Constraints\Choice; use Symfony\Component\Validator\Validator; - use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\Type; @@ -23,16 +24,23 @@ class FilterValidator */ public function validateFilters(array &$filters) { + $direction = new Choice(); + $direction->choices = array( + ConnectionInterface::DIRECTION_ONE_WAY, + ConnectionInterface::DIRECTION_TWO_WAYS + ); $filterConstraint = new Collection(array( - 'type' => array( - new NotBlank(), - new NotNull(), - ), - 'depth' => new Type('integer'), - )); + 'type' => array( + new NotBlank(), + new NotNull(), + ), + 'direction' => $direction, + 'depth' => new Type('integer'), + )); $filtersDefault = array( - 'depth' => 1, + 'direction' => ConnectionInterface::DIRECTION_TWO_WAYS, + 'depth' => 1 ); $filters = array_merge($filtersDefault, $filters); diff --git a/Model/ConnectionInterface.php b/Model/ConnectionInterface.php index 2c51a7a..307b0bd 100644 --- a/Model/ConnectionInterface.php +++ b/Model/ConnectionInterface.php @@ -4,6 +4,9 @@ interface ConnectionInterface { + const DIRECTION_ONE_WAY = 'one-way'; + const DIRECTION_TWO_WAYS = 'two-ways'; + /** * Returns the Node from where the Connection (edge) start * diff --git a/Repository/DoctrineMongoDBConnectionRepository.php b/Repository/DoctrineMongoDBConnectionRepository.php index 85d6f16..6379560 100644 --- a/Repository/DoctrineMongoDBConnectionRepository.php +++ b/Repository/DoctrineMongoDBConnectionRepository.php @@ -88,16 +88,18 @@ public function areConnected(NodeInterface $nodeA, NodeInterface $nodeB, array $ { $qb = $this->createQueryBuilder('Connection'); - $qb->addOr( - $qb->expr() - ->field("source")->references($nodeA) - ->field("destination")->references($nodeB) - ) - ->addOr( - $qb->expr() - ->field("source")->references($nodeB) - ->field("destination")->references($nodeA) - ) ; + $sourceAExpr = $qb->expr() + ->field("source")->references($nodeA) + ->field("destination")->references($nodeB); + $sourceBExpr = $qb->expr() + ->field("source")->references($nodeB) + ->field("destination")->references($nodeA); + + $qb->addOr($sourceAExpr); + + if (!isset($filters['direction']) || $filters['direction'] == ConnectionInterface::DIRECTION_TWO_WAYS) { + $qb->addOr($sourceBExpr); + } if (array_key_exists('type', $filters)) { $qb->field('type')->equals($filters['type']); diff --git a/Repository/DoctrineOrmConnectionRepository.php b/Repository/DoctrineOrmConnectionRepository.php index 7b58682..2cc67e3 100644 --- a/Repository/DoctrineOrmConnectionRepository.php +++ b/Repository/DoctrineOrmConnectionRepository.php @@ -136,19 +136,26 @@ public function areConnected(NodeInterface $nodeA, NodeInterface $nodeB, array $ $queryBuilder = $this->createQueryBuilder('connection'); - $queryBuilder->select('COUNT (connection)') - ->where( - $queryBuilder->expr()->orX( - $queryBuilder->expr()->andX( - $queryBuilder->expr()->andX("connection.sourceObjectId = :nodeAId", "connection.sourceObjectClass = :nodeAClass"), - $queryBuilder->expr()->andX("connection.destinationObjectId = :nodeBId", "connection.destinationObjectClass = :nodeBClass") - ), - $queryBuilder->expr()->andX( - $queryBuilder->expr()->andX("connection.sourceObjectId = :nodeBId", "connection.sourceObjectClass = :nodeBClass"), - $queryBuilder->expr()->andX("connection.destinationObjectId = :nodeAId", "connection.destinationObjectClass = :nodeAClass") - ) - ) + $sourceAExpr = $queryBuilder->expr()->andX( + $queryBuilder->expr()->andX("connection.sourceObjectId = :nodeAId", "connection.sourceObjectClass = :nodeAClass"), + $queryBuilder->expr()->andX("connection.destinationObjectId = :nodeBId", "connection.destinationObjectClass = :nodeBClass") + ); + $sourceBExpr = $queryBuilder->expr()->andX( + $queryBuilder->expr()->andX("connection.sourceObjectId = :nodeBId", "connection.sourceObjectClass = :nodeBClass"), + $queryBuilder->expr()->andX("connection.destinationObjectId = :nodeAId", "connection.destinationObjectClass = :nodeAClass") + ); + + if (!isset($filters['direction']) || $filters['direction'] == ConnectionInterface::DIRECTION_TWO_WAYS) { + $whereExpr = $queryBuilder->expr()->orX( + $sourceAExpr, + $sourceBExpr ); + } else { + $whereExpr = $sourceAExpr; + } + + $queryBuilder->select('COUNT (connection)') + ->where($whereExpr); $queryBuilder->setParameters(array( 'nodeAClass' => $nodeAInformations['object_class'], diff --git a/Tests/Repository/DoctrineMongoDBConnectionRepositoryTest.php b/Tests/Repository/DoctrineMongoDBConnectionRepositoryTest.php index b21bbfa..9211346 100644 --- a/Tests/Repository/DoctrineMongoDBConnectionRepositoryTest.php +++ b/Tests/Repository/DoctrineMongoDBConnectionRepositoryTest.php @@ -2,6 +2,7 @@ namespace Kitano\ConnectionBundle\Tests\Repository; +use Kitano\ConnectionBundle\Model\ConnectionInterface; use Kitano\ConnectionBundle\Repository\DoctrineMongoDBConnectionRepository; use Kitano\ConnectionBundle\Model\NodeInterface; use Kitano\ConnectionBundle\Tests\MongoDBTestCase; @@ -197,6 +198,39 @@ public function testAreConnected() $this->assertFalse($this->repository->areConnected($node2, $node3, array('type' => self::CONNECTION_TYPE))); } + /** + * @group odm + */ + public function testAreConnectedOneWay() + { + $node1 = new Node(455); + $node2 = new Node(4412); + $node3 = new Node(4244); + + $this->getDocumentManager()->persist($node1); + $this->getDocumentManager()->persist($node2); + $this->getDocumentManager()->persist($node3); + $this->getDocumentManager()->flush(); + + $connection1 = $this->createConnection($node1, $node2, self::CONNECTION_TYPE, ConnectionInterface::DIRECTION_ONE_WAY); + $connection2 = $this->createConnection($node2, $node1, self::CONNECTION_TYPE, ConnectionInterface::DIRECTION_ONE_WAY); + $connection3 = $this->createConnection($node1, $node3, self::CONNECTION_TYPE, ConnectionInterface::DIRECTION_ONE_WAY); + + $this->repository->update($connection1); + $this->repository->update($connection2); + $this->repository->update($connection3); + + $filters = array( + 'type' => self::CONNECTION_TYPE, + 'direction' => ConnectionInterface::DIRECTION_ONE_WAY + ); + $this->assertTrue($this->repository->areConnected($node1, $node2, $filters)); + $this->assertTrue($this->repository->areConnected($node2, $node1, $filters)); + $this->assertTrue($this->repository->areConnected($node1, $node3, $filters)); + $this->assertFalse($this->repository->areConnected($node2, $node3, $filters)); + $this->assertFalse($this->repository->areConnected($node3, $node1, $filters)); + } + /** * @group odm */ diff --git a/Tests/Repository/DoctrineOrmConnectionRepositoryTest.php b/Tests/Repository/DoctrineOrmConnectionRepositoryTest.php index fd407df..4e828b4 100644 --- a/Tests/Repository/DoctrineOrmConnectionRepositoryTest.php +++ b/Tests/Repository/DoctrineOrmConnectionRepositoryTest.php @@ -2,6 +2,7 @@ namespace Kitano\ConnectionBundle\Tests\Repository; +use Kitano\ConnectionBundle\Model\ConnectionInterface; use Kitano\ConnectionBundle\Tests\Fixtures\Doctrine\Entity\Node; use Kitano\ConnectionBundle\Tests\OrmTestCase; use Kitano\ConnectionBundle\Repository\DoctrineOrmConnectionRepository; @@ -199,6 +200,39 @@ public function testAreConnected() $this->assertFalse($this->repository->areConnected($node2, $node3, array('type' => self::CONNECTION_TYPE))); } + /** + * @group orm + */ + public function testAreConnectedOneWay() + { + $node1 = new Node(455); + $node2 = new Node(4412); + $node3 = new Node(4244); + + $this->getEntityManager()->persist($node1); + $this->getEntityManager()->persist($node2); + $this->getEntityManager()->persist($node3); + $this->getEntityManager()->flush(); + + $connection1 = $this->createConnection($node1, $node2, self::CONNECTION_TYPE, ConnectionInterface::DIRECTION_ONE_WAY); + $connection2 = $this->createConnection($node2, $node1, self::CONNECTION_TYPE, ConnectionInterface::DIRECTION_ONE_WAY); + $connection3 = $this->createConnection($node1, $node3, self::CONNECTION_TYPE, ConnectionInterface::DIRECTION_ONE_WAY); + + $this->repository->update($connection1); + $this->repository->update($connection2); + $this->repository->update($connection3); + + $filters = array( + 'type' => self::CONNECTION_TYPE, + 'direction' => ConnectionInterface::DIRECTION_ONE_WAY + ); + $this->assertTrue($this->repository->areConnected($node1, $node2, $filters)); + $this->assertTrue($this->repository->areConnected($node2, $node1, $filters)); + $this->assertTrue($this->repository->areConnected($node1, $node3, $filters)); + $this->assertFalse($this->repository->areConnected($node2, $node3, $filters)); + $this->assertFalse($this->repository->areConnected($node3, $node1, $filters)); + } + /** * @group orm */