PageRenderTime 31ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/mailpoet/vendor-prefixed/doctrine/orm/lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php

https://gitlab.com/remyvianne/krowkaramel
PHP | 369 lines | 368 code | 0 blank | 1 comment | 50 complexity | 4fd85f38fc16b06ce4f161a16792ddd6 MD5 | raw file
  1. <?php
  2. declare (strict_types=1);
  3. namespace MailPoetVendor\Doctrine\ORM\Cache\Persister\Entity;
  4. if (!defined('ABSPATH')) exit;
  5. use MailPoetVendor\Doctrine\Common\Collections\Criteria;
  6. use MailPoetVendor\Doctrine\Common\Util\ClassUtils;
  7. use MailPoetVendor\Doctrine\ORM\Cache;
  8. use MailPoetVendor\Doctrine\ORM\Cache\CollectionCacheKey;
  9. use MailPoetVendor\Doctrine\ORM\Cache\EntityCacheKey;
  10. use MailPoetVendor\Doctrine\ORM\Cache\EntityHydrator;
  11. use MailPoetVendor\Doctrine\ORM\Cache\Logging\CacheLogger;
  12. use MailPoetVendor\Doctrine\ORM\Cache\Persister\CachedPersister;
  13. use MailPoetVendor\Doctrine\ORM\Cache\QueryCacheKey;
  14. use MailPoetVendor\Doctrine\ORM\Cache\Region;
  15. use MailPoetVendor\Doctrine\ORM\Cache\TimestampCacheKey;
  16. use MailPoetVendor\Doctrine\ORM\Cache\TimestampRegion;
  17. use MailPoetVendor\Doctrine\ORM\EntityManagerInterface;
  18. use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadata;
  19. use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadataFactory;
  20. use MailPoetVendor\Doctrine\ORM\PersistentCollection;
  21. use MailPoetVendor\Doctrine\ORM\Persisters\Entity\EntityPersister;
  22. use MailPoetVendor\Doctrine\ORM\UnitOfWork;
  23. use function assert;
  24. use function serialize;
  25. use function sha1;
  26. abstract class AbstractEntityPersister implements CachedEntityPersister
  27. {
  28. protected $uow;
  29. protected $metadataFactory;
  30. protected $persister;
  31. protected $class;
  32. protected $queuedCache = [];
  33. protected $region;
  34. protected $timestampRegion;
  35. protected $timestampKey;
  36. protected $hydrator;
  37. protected $cache;
  38. protected $cacheLogger;
  39. protected $regionName;
  40. protected $joinedAssociations;
  41. public function __construct(EntityPersister $persister, Region $region, EntityManagerInterface $em, ClassMetadata $class)
  42. {
  43. $configuration = $em->getConfiguration();
  44. $cacheConfig = $configuration->getSecondLevelCacheConfiguration();
  45. $cacheFactory = $cacheConfig->getCacheFactory();
  46. $this->class = $class;
  47. $this->region = $region;
  48. $this->persister = $persister;
  49. $this->cache = $em->getCache();
  50. $this->regionName = $region->getName();
  51. $this->uow = $em->getUnitOfWork();
  52. $this->metadataFactory = $em->getMetadataFactory();
  53. $this->cacheLogger = $cacheConfig->getCacheLogger();
  54. $this->timestampRegion = $cacheFactory->getTimestampRegion();
  55. $this->hydrator = $cacheFactory->buildEntityHydrator($em, $class);
  56. $this->timestampKey = new TimestampCacheKey($this->class->rootEntityName);
  57. }
  58. public function addInsert($entity)
  59. {
  60. $this->persister->addInsert($entity);
  61. }
  62. public function getInserts()
  63. {
  64. return $this->persister->getInserts();
  65. }
  66. public function getSelectSQL($criteria, $assoc = null, $lockMode = null, $limit = null, $offset = null, ?array $orderBy = null)
  67. {
  68. return $this->persister->getSelectSQL($criteria, $assoc, $lockMode, $limit, $offset, $orderBy);
  69. }
  70. public function getCountSQL($criteria = [])
  71. {
  72. return $this->persister->getCountSQL($criteria);
  73. }
  74. public function getInsertSQL()
  75. {
  76. return $this->persister->getInsertSQL();
  77. }
  78. public function getResultSetMapping()
  79. {
  80. return $this->persister->getResultSetMapping();
  81. }
  82. public function getSelectConditionStatementSQL($field, $value, $assoc = null, $comparison = null)
  83. {
  84. return $this->persister->getSelectConditionStatementSQL($field, $value, $assoc, $comparison);
  85. }
  86. public function exists($entity, ?Criteria $extraConditions = null)
  87. {
  88. if ($extraConditions === null) {
  89. $key = new EntityCacheKey($this->class->rootEntityName, $this->class->getIdentifierValues($entity));
  90. if ($this->region->contains($key)) {
  91. return \true;
  92. }
  93. }
  94. return $this->persister->exists($entity, $extraConditions);
  95. }
  96. public function getCacheRegion()
  97. {
  98. return $this->region;
  99. }
  100. public function getEntityHydrator()
  101. {
  102. return $this->hydrator;
  103. }
  104. public function storeEntityCache($entity, EntityCacheKey $key)
  105. {
  106. $class = $this->class;
  107. $className = ClassUtils::getClass($entity);
  108. if ($className !== $this->class->name) {
  109. $class = $this->metadataFactory->getMetadataFor($className);
  110. }
  111. $entry = $this->hydrator->buildCacheEntry($class, $key, $entity);
  112. $cached = $this->region->put($key, $entry);
  113. if ($this->cacheLogger && $cached) {
  114. $this->cacheLogger->entityCachePut($this->regionName, $key);
  115. }
  116. return $cached;
  117. }
  118. private function storeJoinedAssociations($entity) : void
  119. {
  120. if ($this->joinedAssociations === null) {
  121. $associations = [];
  122. foreach ($this->class->associationMappings as $name => $assoc) {
  123. if (isset($assoc['cache']) && $assoc['type'] & ClassMetadata::TO_ONE && ($assoc['fetch'] === ClassMetadata::FETCH_EAGER || !$assoc['isOwningSide'])) {
  124. $associations[] = $name;
  125. }
  126. }
  127. $this->joinedAssociations = $associations;
  128. }
  129. foreach ($this->joinedAssociations as $name) {
  130. $assoc = $this->class->associationMappings[$name];
  131. $assocEntity = $this->class->getFieldValue($entity, $name);
  132. if ($assocEntity === null) {
  133. continue;
  134. }
  135. $assocId = $this->uow->getEntityIdentifier($assocEntity);
  136. $assocMetadata = $this->metadataFactory->getMetadataFor($assoc['targetEntity']);
  137. $assocKey = new EntityCacheKey($assocMetadata->rootEntityName, $assocId);
  138. $assocPersister = $this->uow->getEntityPersister($assoc['targetEntity']);
  139. $assocPersister->storeEntityCache($assocEntity, $assocKey);
  140. }
  141. }
  142. protected function getHash($query, $criteria, ?array $orderBy = null, $limit = null, $offset = null)
  143. {
  144. [$params] = $criteria instanceof Criteria ? $this->persister->expandCriteriaParameters($criteria) : $this->persister->expandParameters($criteria);
  145. return sha1($query . serialize($params) . serialize($orderBy) . $limit . $offset);
  146. }
  147. public function expandParameters($criteria)
  148. {
  149. return $this->persister->expandParameters($criteria);
  150. }
  151. public function expandCriteriaParameters(Criteria $criteria)
  152. {
  153. return $this->persister->expandCriteriaParameters($criteria);
  154. }
  155. public function getClassMetadata()
  156. {
  157. return $this->persister->getClassMetadata();
  158. }
  159. public function getManyToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null)
  160. {
  161. return $this->persister->getManyToManyCollection($assoc, $sourceEntity, $offset, $limit);
  162. }
  163. public function getOneToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null)
  164. {
  165. return $this->persister->getOneToManyCollection($assoc, $sourceEntity, $offset, $limit);
  166. }
  167. public function getOwningTable($fieldName)
  168. {
  169. return $this->persister->getOwningTable($fieldName);
  170. }
  171. public function executeInserts()
  172. {
  173. $this->queuedCache['insert'] = $this->persister->getInserts();
  174. return $this->persister->executeInserts();
  175. }
  176. public function load(array $criteria, $entity = null, $assoc = null, array $hints = [], $lockMode = null, $limit = null, ?array $orderBy = null)
  177. {
  178. if ($entity !== null || $assoc !== null || $hints !== [] || $lockMode !== null) {
  179. return $this->persister->load($criteria, $entity, $assoc, $hints, $lockMode, $limit, $orderBy);
  180. }
  181. //handle only EntityRepository#findOneBy
  182. $query = $this->persister->getSelectSQL($criteria, null, null, $limit, null, $orderBy);
  183. $hash = $this->getHash($query, $criteria, null, null, null);
  184. $rsm = $this->getResultSetMapping();
  185. $queryKey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
  186. $queryCache = $this->cache->getQueryCache($this->regionName);
  187. $result = $queryCache->get($queryKey, $rsm);
  188. if ($result !== null) {
  189. if ($this->cacheLogger) {
  190. $this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
  191. }
  192. return $result[0];
  193. }
  194. $result = $this->persister->load($criteria, $entity, $assoc, $hints, $lockMode, $limit, $orderBy);
  195. if ($result === null) {
  196. return null;
  197. }
  198. $cached = $queryCache->put($queryKey, $rsm, [$result]);
  199. if ($this->cacheLogger) {
  200. $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
  201. if ($cached) {
  202. $this->cacheLogger->queryCachePut($this->regionName, $queryKey);
  203. }
  204. }
  205. return $result;
  206. }
  207. public function loadAll(array $criteria = [], ?array $orderBy = null, $limit = null, $offset = null)
  208. {
  209. $query = $this->persister->getSelectSQL($criteria, null, null, $limit, $offset, $orderBy);
  210. $hash = $this->getHash($query, $criteria, null, null, null);
  211. $rsm = $this->getResultSetMapping();
  212. $queryKey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
  213. $queryCache = $this->cache->getQueryCache($this->regionName);
  214. $result = $queryCache->get($queryKey, $rsm);
  215. if ($result !== null) {
  216. if ($this->cacheLogger) {
  217. $this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
  218. }
  219. return $result;
  220. }
  221. $result = $this->persister->loadAll($criteria, $orderBy, $limit, $offset);
  222. $cached = $queryCache->put($queryKey, $rsm, $result);
  223. if ($this->cacheLogger) {
  224. if ($result) {
  225. $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
  226. }
  227. if ($cached) {
  228. $this->cacheLogger->queryCachePut($this->regionName, $queryKey);
  229. }
  230. }
  231. return $result;
  232. }
  233. public function loadById(array $identifier, $entity = null)
  234. {
  235. $cacheKey = new EntityCacheKey($this->class->rootEntityName, $identifier);
  236. $cacheEntry = $this->region->get($cacheKey);
  237. $class = $this->class;
  238. if ($cacheEntry !== null) {
  239. if ($cacheEntry->class !== $this->class->name) {
  240. $class = $this->metadataFactory->getMetadataFor($cacheEntry->class);
  241. }
  242. $cachedEntity = $this->hydrator->loadCacheEntry($class, $cacheKey, $cacheEntry, $entity);
  243. if ($cachedEntity !== null) {
  244. if ($this->cacheLogger) {
  245. $this->cacheLogger->entityCacheHit($this->regionName, $cacheKey);
  246. }
  247. return $cachedEntity;
  248. }
  249. }
  250. $entity = $this->persister->loadById($identifier, $entity);
  251. if ($entity === null) {
  252. return null;
  253. }
  254. $class = $this->class;
  255. $className = ClassUtils::getClass($entity);
  256. if ($className !== $this->class->name) {
  257. $class = $this->metadataFactory->getMetadataFor($className);
  258. }
  259. $cacheEntry = $this->hydrator->buildCacheEntry($class, $cacheKey, $entity);
  260. $cached = $this->region->put($cacheKey, $cacheEntry);
  261. if ($cached && ($this->joinedAssociations === null || $this->joinedAssociations)) {
  262. $this->storeJoinedAssociations($entity);
  263. }
  264. if ($this->cacheLogger) {
  265. if ($cached) {
  266. $this->cacheLogger->entityCachePut($this->regionName, $cacheKey);
  267. }
  268. $this->cacheLogger->entityCacheMiss($this->regionName, $cacheKey);
  269. }
  270. return $entity;
  271. }
  272. public function count($criteria = [])
  273. {
  274. return $this->persister->count($criteria);
  275. }
  276. public function loadCriteria(Criteria $criteria)
  277. {
  278. $orderBy = $criteria->getOrderings();
  279. $limit = $criteria->getMaxResults();
  280. $offset = $criteria->getFirstResult();
  281. $query = $this->persister->getSelectSQL($criteria);
  282. $hash = $this->getHash($query, $criteria, $orderBy, $limit, $offset);
  283. $rsm = $this->getResultSetMapping();
  284. $queryKey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
  285. $queryCache = $this->cache->getQueryCache($this->regionName);
  286. $cacheResult = $queryCache->get($queryKey, $rsm);
  287. if ($cacheResult !== null) {
  288. if ($this->cacheLogger) {
  289. $this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
  290. }
  291. return $cacheResult;
  292. }
  293. $result = $this->persister->loadCriteria($criteria);
  294. $cached = $queryCache->put($queryKey, $rsm, $result);
  295. if ($this->cacheLogger) {
  296. if ($result) {
  297. $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
  298. }
  299. if ($cached) {
  300. $this->cacheLogger->queryCachePut($this->regionName, $queryKey);
  301. }
  302. }
  303. return $result;
  304. }
  305. public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $collection)
  306. {
  307. $persister = $this->uow->getCollectionPersister($assoc);
  308. $hasCache = $persister instanceof CachedPersister;
  309. if (!$hasCache) {
  310. return $this->persister->loadManyToManyCollection($assoc, $sourceEntity, $collection);
  311. }
  312. $ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
  313. $key = $this->buildCollectionCacheKey($assoc, $ownerId);
  314. $list = $persister->loadCollectionCache($collection, $key);
  315. if ($list !== null) {
  316. if ($this->cacheLogger) {
  317. $this->cacheLogger->collectionCacheHit($persister->getCacheRegion()->getName(), $key);
  318. }
  319. return $list;
  320. }
  321. $list = $this->persister->loadManyToManyCollection($assoc, $sourceEntity, $collection);
  322. $persister->storeCollectionCache($key, $list);
  323. if ($this->cacheLogger) {
  324. $this->cacheLogger->collectionCacheMiss($persister->getCacheRegion()->getName(), $key);
  325. }
  326. return $list;
  327. }
  328. public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $collection)
  329. {
  330. $persister = $this->uow->getCollectionPersister($assoc);
  331. $hasCache = $persister instanceof CachedPersister;
  332. if (!$hasCache) {
  333. return $this->persister->loadOneToManyCollection($assoc, $sourceEntity, $collection);
  334. }
  335. $ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
  336. $key = $this->buildCollectionCacheKey($assoc, $ownerId);
  337. $list = $persister->loadCollectionCache($collection, $key);
  338. if ($list !== null) {
  339. if ($this->cacheLogger) {
  340. $this->cacheLogger->collectionCacheHit($persister->getCacheRegion()->getName(), $key);
  341. }
  342. return $list;
  343. }
  344. $list = $this->persister->loadOneToManyCollection($assoc, $sourceEntity, $collection);
  345. $persister->storeCollectionCache($key, $list);
  346. if ($this->cacheLogger) {
  347. $this->cacheLogger->collectionCacheMiss($persister->getCacheRegion()->getName(), $key);
  348. }
  349. return $list;
  350. }
  351. public function loadOneToOneEntity(array $assoc, $sourceEntity, array $identifier = [])
  352. {
  353. return $this->persister->loadOneToOneEntity($assoc, $sourceEntity, $identifier);
  354. }
  355. public function lock(array $criteria, $lockMode)
  356. {
  357. $this->persister->lock($criteria, $lockMode);
  358. }
  359. public function refresh(array $id, $entity, $lockMode = null)
  360. {
  361. $this->persister->refresh($id, $entity, $lockMode);
  362. }
  363. protected function buildCollectionCacheKey(array $association, $ownerId)
  364. {
  365. $metadata = $this->metadataFactory->getMetadataFor($association['sourceEntity']);
  366. assert($metadata instanceof ClassMetadata);
  367. return new CollectionCacheKey($metadata->rootEntityName, $association['fieldName'], $ownerId);
  368. }
  369. }