diff -r 000000000000 -r 7f95f8617b0b vendor/symfony/src/Symfony/Component/Security/Acl/Permission/MaskBuilder.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/symfony/src/Symfony/Component/Security/Acl/Permission/MaskBuilder.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,202 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Acl\Permission; + +/** + * This class allows you to build cumulative permissions easily, or convert + * masks to a human-readable format. + * + * + * $builder = new MaskBuilder(); + * $builder + * ->add('view') + * ->add('create') + * ->add('edit') + * ; + * var_dump($builder->get()); // int(7) + * var_dump($builder->getPattern()); // string(32) ".............................ECV" + * + * + * We have defined some commonly used base permissions which you can use: + * - VIEW: the SID is allowed to view the domain object / field + * - CREATE: the SID is allowed to create new instances of the domain object / fields + * - EDIT: the SID is allowed to edit existing instances of the domain object / field + * - DELETE: the SID is allowed to delete domain objects + * - UNDELETE: the SID is allowed to recover domain objects from trash + * - OPERATOR: the SID is allowed to perform any action on the domain object + * except for granting others permissions + * - MASTER: the SID is allowed to perform any action on the domain object, + * and is allowed to grant other SIDs any permission except for + * MASTER and OWNER permissions + * - OWNER: the SID is owning the domain object in question and can perform any + * action on the domain object as well as grant any permission + * + * @author Johannes M. Schmitt + */ +class MaskBuilder +{ + const MASK_VIEW = 1; // 1 << 0 + const MASK_CREATE = 2; // 1 << 1 + const MASK_EDIT = 4; // 1 << 2 + const MASK_DELETE = 8; // 1 << 3 + const MASK_UNDELETE = 16; // 1 << 4 + const MASK_OPERATOR = 32; // 1 << 5 + const MASK_MASTER = 64; // 1 << 6 + const MASK_OWNER = 128; // 1 << 7 + const MASK_IDDQD = 1073741823; // 1 << 0 | 1 << 1 | ... | 1 << 30 + + const CODE_VIEW = 'V'; + const CODE_CREATE = 'C'; + const CODE_EDIT = 'E'; + const CODE_DELETE = 'D'; + const CODE_UNDELETE = 'U'; + const CODE_OPERATOR = 'O'; + const CODE_MASTER = 'M'; + const CODE_OWNER = 'N'; + + const ALL_OFF = '................................'; + const OFF = '.'; + const ON = '*'; + + private $mask; + + /** + * Constructor + * + * @param integer $mask optional; defaults to 0 + * @return void + */ + public function __construct($mask = 0) + { + if (!is_int($mask)) { + throw new \InvalidArgumentException('$mask must be an integer.'); + } + + $this->mask = $mask; + } + + /** + * Adds a mask to the permission + * + * @param mixed $mask + * @return PermissionBuilder + */ + public function add($mask) + { + if (is_string($mask) && defined($name = 'static::MASK_'.strtoupper($mask))) { + $mask = constant($name); + } else if (!is_int($mask)) { + throw new \InvalidArgumentException('$mask must be an integer.'); + } + + $this->mask |= $mask; + + return $this; + } + + /** + * Returns the mask of this permission + * + * @return integer + */ + public function get() + { + return $this->mask; + } + + /** + * Returns a human-readable representation of the permission + * + * @return string + */ + public function getPattern() + { + $pattern = self::ALL_OFF; + $length = strlen($pattern); + $bitmask = str_pad(decbin($this->mask), $length, '0', STR_PAD_LEFT); + + for ($i=$length-1; $i>=0; $i--) { + if ('1' === $bitmask[$i]) { + try { + $pattern[$i] = self::getCode(1 << ($length - $i - 1)); + } catch (\Exception $notPredefined) { + $pattern[$i] = self::ON; + } + } + } + + return $pattern; + } + + /** + * Removes a mask from the permission + * + * @param mixed $mask + * @return PermissionBuilder + */ + public function remove($mask) + { + if (is_string($mask) && defined($name = 'static::MASK_'.strtoupper($mask))) { + $mask = constant($name); + } else if (!is_int($mask)) { + throw new \InvalidArgumentException('$mask must be an integer.'); + } + + $this->mask &= ~$mask; + + return $this; + } + + /** + * Resets the PermissionBuilder + * + * @return PermissionBuilder + */ + public function reset() + { + $this->mask = 0; + + return $this; + } + + /** + * Returns the code for the passed mask + * + * @param integer $mask + * @throws \InvalidArgumentException + * @throws \RuntimeException + * @return string + */ + static public function getCode($mask) + { + if (!is_int($mask)) { + throw new \InvalidArgumentException('$mask must be an integer.'); + } + + $reflection = new \ReflectionClass(get_called_class()); + foreach ($reflection->getConstants() as $name => $cMask) { + if (0 !== strpos($name, 'MASK_')) { + continue; + } + + if ($mask === $cMask) { + if (!defined($cName = 'static::CODE_'.substr($name, 5))) { + throw new \RuntimeException('There was no code defined for this mask.'); + } + + return constant($cName); + } + } + + throw new \InvalidArgumentException(sprintf('The mask "%d" is not supported.', $mask)); + } +}