Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Show file tree
Hide file tree
Showing 5 changed files with 592 additions and 0 deletions.
175 changes: 175 additions & 0 deletions src/Assertion/AssertionAggregate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Permissions\Acl\Assertion;

use Zend\Permissions\Acl\Acl;
use Zend\Permissions\Acl\Role\RoleInterface;
use Zend\Permissions\Acl\Resource\ResourceInterface;
use Zend\Permissions\Acl\Exception\InvalidArgumentException;
use Zend\Permissions\Acl\Exception\RuntimeException;

class AssertionAggregate implements AssertionInterface
{

const MODE_ALL = 'all';

const MODE_AT_LEAST_ONE = 'at_least_one';

protected $assertions = array();

/**
*
* @var $manager AssertionManager
*/
protected $assertionManager;

protected $mode = self::MODE_ALL;

/**
* Stacks an assertion in aggregate
*
* @param AssertionInterface|string $assertion
* if string, must match a AssertionManager declared service (checked later)
*
* @return self
*/
public function addAssertion($assertion)
{
$this->assertions[] = $assertion;

return $this;
}

public function addAssertions(array $assertions)
{
foreach ($assertions as $assertion) {
$this->addAssertion($assertion);
}

return $this;
}

/**
* Empties assertions stack
*
* @return self
*/
public function clearAssertions()
{
$this->assertions = array();

return $this;
}

/**
*
* @param AssertionManager $manager
*
* @return self
*/
public function setAssertionManager(AssertionManager $manager)
{
$this->assertionManager = $manager;

return $this;
}

public function getAssertionManager()
{
return $this->assertionManager;
}

/**
* Set assertion chain behavior
*
* AssertionAggregate should assert to true when:
*
* - all assertions are true with MODE_ALL
* - at least one assertion is true with MODE_AT_LEAST_ONE
*
* @param string $mode
* indicates how assertion chain result should interpreted (either 'all' or 'at_least_one')
* @throws Exception
*
* @return self
*/
public function setMode($mode)
{
if ($mode != self::MODE_ALL && $mode != self::MODE_AT_LEAST_ONE) {
throw new InvalidArgumentException('invalid assertion aggregate mode');
}

$this->mode = $mode;

return $this;
}

/**
* Return current mode
*
* @return string
*/
public function getMode()
{
return $this->mode;
}

/**
* @see \Zend\Permissions\Acl\Assertion\AssertionInterface::assert()
*
* @throws RuntimeException
* @return bool
*/
public function assert(Acl $acl, RoleInterface $role = null, ResourceInterface $resource = null, $privilege = null)
{
// check if assertions are set
if (! $this->assertions) {
throw new RuntimeException('no assertion have been aggregated to this AssertionAggregate');
}

foreach ($this->assertions as $assertion) {

// jit assertion mloading
if (! $assertion instanceof AssertionInterface) {
if (class_exists($assertion)) {
$assertion = new $assertion();
} else {
if ($manager = $this->getAssertionManager()) {
try {
$assertion = $manager->get($assertion);
} catch (\Exception $e) {
throw new Exception\InvalidAssertionException('assertion "' . $assertion . '" is not defined in assertion manager');
}
} else {
throw new RuntimeException('no assertion manager is set - cannot look up for assertions');
}
}
}

$result = (bool) $assertion->assert($acl, $role, $resource, $privilege);

if ($this->getMode() == self::MODE_ALL && ! $result) {
// on false is enough
return false;
}

if ($this->getMode() == self::MODE_AT_LEAST_ONE && $result) {
// one true is enough
return true;
}
}

if ($this->getMode() == self::MODE_ALL) {
// none of the assertions returned false
return true;
} else {
return false;
}
}
}
39 changes: 39 additions & 0 deletions src/Assertion/AssertionManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Permissions\Acl\Assertion;

use Zend\ServiceManager\AbstractPluginManager;
use Zend\Permissions\Acl\Exception\InvalidArgumentException;

class AssertionManager extends AbstractPluginManager
{

protected $sharedByDefault = true;

/**
* Validate the plugin
*
* Checks that the element is an instance of AssertionInterface
*
* @param mixed $plugin
*
* @throws InvalidArgumentException
* @return bool
*/
public function validatePlugin($plugin)
{
if (! $plugin instanceof AssertionInterface) {
throw new InvalidArgumentException(sprintf('Plugin of type %s is invalid; must implement
Zend\Permissions\Acl\Assertion\AssertionInterface',
(is_object($plugin) ? get_class($plugin) : gettype($plugin))));
}

return true;
}
}
8 changes: 8 additions & 0 deletions src/Assertion/Exception/InvalidAssertionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
namespace Zend\Permissions\Acl\Assertion\Exception;

use Zend\Permissions\Acl\Exception\ExceptionInterface;

class InvalidAssertionException extends \InvalidArgumentException implements ExceptionInterface
{
}
Loading

0 comments on commit a30a4f1

Please sign in to comment.