-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #10 - Refactoring of SimpleCascadeStrategy into smaller classes…
…, better separation of concerns, and more testable Added tests too
- Loading branch information
Showing
7 changed files
with
434 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
<?php | ||
|
||
namespace MyCLabs\ACL\ResourceGraph; | ||
|
||
use Doctrine\ORM\EntityManager; | ||
use MyCLabs\ACL\Model\CascadingResource; | ||
use MyCLabs\ACL\Model\ResourceInterface; | ||
|
||
/** | ||
* Traverser for resources implementing CascadingResource. | ||
* | ||
* CascadingResource don't return all sub-resources (only the direct ones), so we need to do | ||
* the traversal recursively in this class. | ||
* | ||
* @author Matthieu Napoli <[email protected]> | ||
*/ | ||
class CascadingResourceGraphTraverser implements ResourceGraphTraverser | ||
{ | ||
/** | ||
* @var EntityManager | ||
*/ | ||
private $entityManager; | ||
|
||
/** | ||
* @var ResourceGraphTraverser | ||
*/ | ||
private $parentTraverser; | ||
|
||
/** | ||
* @param EntityManager $entityManager | ||
* @param ResourceGraphTraverser $parentTraverser We need the parent traverser to use it | ||
* to recursively traverse resources. This is because CascadingResource returns | ||
* returns only its direct parent and sub-resources. | ||
*/ | ||
public function __construct(EntityManager $entityManager, ResourceGraphTraverser $parentTraverser) | ||
{ | ||
$this->entityManager = $entityManager; | ||
$this->parentTraverser = $parentTraverser; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getAllParentResources(ResourceInterface $resource) | ||
{ | ||
if (! $resource instanceof CascadingResource) { | ||
return []; | ||
} | ||
|
||
$parentResources = []; | ||
|
||
foreach ($resource->getParentResources($this->entityManager) as $parentResource) { | ||
$parentResources[] = $parentResource; | ||
|
||
// Recursively get its sub-resources | ||
$parentResources = array_merge( | ||
$parentResources, | ||
$this->parentTraverser->getAllParentResources($parentResource) | ||
); | ||
} | ||
|
||
return $this->unique($parentResources); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getAllSubResources(ResourceInterface $resource) | ||
{ | ||
if (! $resource instanceof CascadingResource) { | ||
return []; | ||
} | ||
|
||
$subResources = []; | ||
|
||
foreach ($resource->getSubResources($this->entityManager) as $subResource) { | ||
$subResources[] = $subResource; | ||
|
||
// Recursively get its sub-resources | ||
$subResources = array_merge( | ||
$subResources, | ||
$this->parentTraverser->getAllSubResources($subResource) | ||
); | ||
} | ||
|
||
return $this->unique($subResources); | ||
} | ||
|
||
/** | ||
* Array unique but with objects. | ||
* | ||
* @param array $array | ||
* | ||
* @return array | ||
*/ | ||
private function unique(array $array) | ||
{ | ||
$result = []; | ||
|
||
foreach ($array as $item) { | ||
if (! in_array($item, $result, true)) { | ||
$result[] = $item; | ||
} | ||
} | ||
|
||
return $result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?php | ||
|
||
namespace MyCLabs\ACL\ResourceGraph; | ||
|
||
use Doctrine\Common\Util\ClassUtils; | ||
use MyCLabs\ACL\Model\ResourceInterface; | ||
|
||
/** | ||
* This is a traverser that dispatches to other traversers based on the resource class. | ||
* | ||
* @author Matthieu Napoli <[email protected]> | ||
*/ | ||
class ResourceGraphTraverserDispatcher implements ResourceGraphTraverser | ||
{ | ||
/** | ||
* @var ResourceGraphTraverser[] | ||
*/ | ||
private $traversers = []; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getAllParentResources(ResourceInterface $resource) | ||
{ | ||
$traverser = $this->getResourceGraphTraverser($resource); | ||
if (!$traverser) { | ||
return []; | ||
} | ||
|
||
return $traverser->getAllParentResources($resource); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getAllSubResources(ResourceInterface $resource) | ||
{ | ||
$traverser = $this->getResourceGraphTraverser($resource); | ||
if (!$traverser) { | ||
return []; | ||
} | ||
|
||
return $traverser->getAllSubResources($resource); | ||
} | ||
|
||
/** | ||
* @param string $entityClass | ||
* @param ResourceGraphTraverser $resourceGraphTraverser | ||
*/ | ||
public function setResourceGraphTraverser($entityClass, ResourceGraphTraverser $resourceGraphTraverser) | ||
{ | ||
$this->traversers[$entityClass] = $resourceGraphTraverser; | ||
} | ||
|
||
/** | ||
* @param object $resource | ||
* @return ResourceGraphTraverser|null | ||
*/ | ||
private function getResourceGraphTraverser($resource) | ||
{ | ||
$entityClass = ClassUtils::getClass($resource); | ||
|
||
if (isset($this->traversers[$entityClass])) { | ||
return $this->traversers[$entityClass]; | ||
} | ||
|
||
// We also try using instanceof so that we cover inheritance and interfaces | ||
foreach ($this->traversers as $class => $traverser) { | ||
if ($resource instanceof $class) { | ||
return $traverser; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.