/vendor/doctrine/doctrine-cache-bundle/Acl/Model/AclCache.php

https://gitlab.com/cuza/Clinic_Recods · PHP · 239 lines · 127 code · 49 blank · 63 comment · 9 complexity · 3908eccba950c8d023082615747d0daa MD5 · raw file

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