PageRenderTime 26ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/DoctrineAclCache.php

https://github.com/nattaphat/hgis
PHP | 223 lines | 130 code | 35 blank | 58 comment | 11 complexity | 2f552f22f35c47d5d523c187d25039eb MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Security\Acl\Domain;
  11. use Doctrine\Common\Cache\Cache;
  12. use Symfony\Component\Security\Acl\Model\AclCacheInterface;
  13. use Symfony\Component\Security\Acl\Model\AclInterface;
  14. use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
  15. use Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface;
  16. /**
  17. * This class is a wrapper around the actual cache implementation.
  18. *
  19. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  20. */
  21. class DoctrineAclCache implements AclCacheInterface
  22. {
  23. const PREFIX = 'sf2_acl_';
  24. private $cache;
  25. private $prefix;
  26. private $permissionGrantingStrategy;
  27. /**
  28. * Constructor
  29. *
  30. * @param Cache $cache
  31. * @param PermissionGrantingStrategyInterface $permissionGrantingStrategy
  32. * @param string $prefix
  33. *
  34. * @throws \InvalidArgumentException
  35. */
  36. public function __construct(Cache $cache, PermissionGrantingStrategyInterface $permissionGrantingStrategy, $prefix = self::PREFIX)
  37. {
  38. if (0 === strlen($prefix)) {
  39. throw new \InvalidArgumentException('$prefix cannot be empty.');
  40. }
  41. $this->cache = $cache;
  42. $this->permissionGrantingStrategy = $permissionGrantingStrategy;
  43. $this->prefix = $prefix;
  44. }
  45. /**
  46. * {@inheritDoc}
  47. */
  48. public function clearCache()
  49. {
  50. $this->cache->deleteByPrefix($this->prefix);
  51. }
  52. /**
  53. * {@inheritDoc}
  54. */
  55. public function evictFromCacheById($aclId)
  56. {
  57. $lookupKey = $this->getAliasKeyForIdentity($aclId);
  58. if (!$this->cache->contains($lookupKey)) {
  59. return;
  60. }
  61. $key = $this->cache->fetch($lookupKey);
  62. if ($this->cache->contains($key)) {
  63. $this->cache->delete($key);
  64. }
  65. $this->cache->delete($lookupKey);
  66. }
  67. /**
  68. * {@inheritDoc}
  69. */
  70. public function evictFromCacheByIdentity(ObjectIdentityInterface $oid)
  71. {
  72. $key = $this->getDataKeyByIdentity($oid);
  73. if (!$this->cache->contains($key)) {
  74. return;
  75. }
  76. $this->cache->delete($key);
  77. }
  78. /**
  79. * {@inheritDoc}
  80. */
  81. public function getFromCacheById($aclId)
  82. {
  83. $lookupKey = $this->getAliasKeyForIdentity($aclId);
  84. if (!$this->cache->contains($lookupKey)) {
  85. return null;
  86. }
  87. $key = $this->cache->fetch($lookupKey);
  88. if (!$this->cache->contains($key)) {
  89. $this->cache->delete($lookupKey);
  90. return null;
  91. }
  92. return $this->unserializeAcl($this->cache->fetch($key));
  93. }
  94. /**
  95. * {@inheritDoc}
  96. */
  97. public function getFromCacheByIdentity(ObjectIdentityInterface $oid)
  98. {
  99. $key = $this->getDataKeyByIdentity($oid);
  100. if (!$this->cache->contains($key)) {
  101. return null;
  102. }
  103. return $this->unserializeAcl($this->cache->fetch($key));
  104. }
  105. /**
  106. * {@inheritDoc}
  107. */
  108. public function putInCache(AclInterface $acl)
  109. {
  110. if (null === $acl->getId()) {
  111. throw new \InvalidArgumentException('Transient ACLs cannot be cached.');
  112. }
  113. if (null !== $parentAcl = $acl->getParentAcl()) {
  114. $this->putInCache($parentAcl);
  115. }
  116. $key = $this->getDataKeyByIdentity($acl->getObjectIdentity());
  117. $this->cache->save($key, serialize($acl));
  118. $this->cache->save($this->getAliasKeyForIdentity($acl->getId()), $key);
  119. }
  120. /**
  121. * Unserializes the ACL.
  122. *
  123. * @param string $serialized
  124. * @return AclInterface
  125. */
  126. private function unserializeAcl($serialized)
  127. {
  128. $acl = unserialize($serialized);
  129. if (null !== $parentId = $acl->getParentAcl()) {
  130. $parentAcl = $this->getFromCacheById($parentId);
  131. if (null === $parentAcl) {
  132. return null;
  133. }
  134. $acl->setParentAcl($parentAcl);
  135. }
  136. $reflectionProperty = new \ReflectionProperty($acl, 'permissionGrantingStrategy');
  137. $reflectionProperty->setAccessible(true);
  138. $reflectionProperty->setValue($acl, $this->permissionGrantingStrategy);
  139. $reflectionProperty->setAccessible(false);
  140. $aceAclProperty = new \ReflectionProperty('Symfony\Component\Security\Acl\Domain\Entry', 'acl');
  141. $aceAclProperty->setAccessible(true);
  142. foreach ($acl->getObjectAces() as $ace) {
  143. $aceAclProperty->setValue($ace, $acl);
  144. }
  145. foreach ($acl->getClassAces() as $ace) {
  146. $aceAclProperty->setValue($ace, $acl);
  147. }
  148. $aceClassFieldProperty = new \ReflectionProperty($acl, 'classFieldAces');
  149. $aceClassFieldProperty->setAccessible(true);
  150. foreach ($aceClassFieldProperty->getValue($acl) as $aces) {
  151. foreach ($aces as $ace) {
  152. $aceAclProperty->setValue($ace, $acl);
  153. }
  154. }
  155. $aceClassFieldProperty->setAccessible(false);
  156. $aceObjectFieldProperty = new \ReflectionProperty($acl, 'objectFieldAces');
  157. $aceObjectFieldProperty->setAccessible(true);
  158. foreach ($aceObjectFieldProperty->getValue($acl) as $aces) {
  159. foreach ($aces as $ace) {
  160. $aceAclProperty->setValue($ace, $acl);
  161. }
  162. }
  163. $aceObjectFieldProperty->setAccessible(false);
  164. $aceAclProperty->setAccessible(false);
  165. return $acl;
  166. }
  167. /**
  168. * Returns the key for the object identity
  169. *
  170. * @param ObjectIdentityInterface $oid
  171. * @return string
  172. */
  173. private function getDataKeyByIdentity(ObjectIdentityInterface $oid)
  174. {
  175. return $this->prefix.md5($oid->getType()).sha1($oid->getType())
  176. .'_'.md5($oid->getIdentifier()).sha1($oid->getIdentifier());
  177. }
  178. /**
  179. * Returns the alias key for the object identity key
  180. *
  181. * @param string $aclId
  182. * @return string
  183. */
  184. private function getAliasKeyForIdentity($aclId)
  185. {
  186. return $this->prefix.$aclId;
  187. }
  188. }