/vendor/magento/framework/DataObject/Cache.php

https://gitlab.com/yousafsyed/easternglamor · PHP · 476 lines · 237 code · 44 blank · 195 comment · 26 complexity · 8eaabb326c10e1e906f2c3be89428819 MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\DataObject;
  7. /**
  8. * Object Cache
  9. *
  10. * Stores objects for reuse, cleanup and to avoid circular references
  11. *
  12. * @author Magento Core Team <core@magentocommerce.com>
  13. */
  14. class Cache
  15. {
  16. /**
  17. * Singleton instance
  18. *
  19. * @var \Magento\Framework\DataObject\Cache
  20. */
  21. protected static $_instance;
  22. /**
  23. * Running object index for anonymous objects
  24. *
  25. * @var integer
  26. */
  27. protected $_idx = 0;
  28. /**
  29. * Array of objects
  30. *
  31. * @var array of objects
  32. */
  33. protected $_objects = [];
  34. /**
  35. * SPL object hashes
  36. *
  37. * @var array
  38. */
  39. protected $_hashes = [];
  40. /**
  41. * SPL hashes by object
  42. *
  43. * @var array
  44. */
  45. protected $_objectHashes = [];
  46. /**
  47. * Objects by tags for cleanup
  48. *
  49. * @var array 2D
  50. */
  51. protected $_tags = [];
  52. /**
  53. * Tags by objects
  54. *
  55. * @var array 2D
  56. */
  57. protected $_objectTags = [];
  58. /**
  59. * References to objects
  60. *
  61. * @var array
  62. */
  63. protected $_references = [];
  64. /**
  65. * References by object
  66. *
  67. * @var array 2D
  68. */
  69. protected $_objectReferences = [];
  70. /**
  71. * Debug data such as backtrace per class
  72. *
  73. * @var array
  74. */
  75. protected $_debug = [];
  76. /**
  77. * Singleton factory
  78. *
  79. * @return \Magento\Framework\DataObject\Cache
  80. */
  81. public static function singleton()
  82. {
  83. if (!self::$_instance) {
  84. self::$_instance = new self();
  85. }
  86. return self::$_instance;
  87. }
  88. /**
  89. * Load an object from registry
  90. *
  91. * @param string|object $idx
  92. * @param object $default
  93. * @return object
  94. */
  95. public function load($idx, $default = null)
  96. {
  97. if (isset($this->_references[$idx])) {
  98. $idx = $this->_references[$idx];
  99. }
  100. if (isset($this->_objects[$idx])) {
  101. return $this->_objects[$idx];
  102. }
  103. return $default;
  104. }
  105. /**
  106. * Save an object entry
  107. *
  108. * @param object $object
  109. * @param string $idx
  110. * @param array|string $tags
  111. * @return string
  112. * @throws \Magento\Framework\Exception\LocalizedException
  113. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  114. * @SuppressWarnings(PHPMD.NPathComplexity)
  115. */
  116. public function save($object, $idx = null, $tags = null)
  117. {
  118. //\Magento\Framework\Profiler::start('OBJECT_SAVE');
  119. if (!is_object($object)) {
  120. return false;
  121. }
  122. $hash = spl_object_hash($object);
  123. if ($idx !== null && strpos($idx, '{')) {
  124. $idx = str_replace('{hash}', $hash, $idx);
  125. }
  126. if (isset($this->_hashes[$hash])) {
  127. //throw new \Exception('test');
  128. if ($idx !== null) {
  129. $this->_references[$idx] = $this->_hashes[$hash];
  130. }
  131. return $this->_hashes[$hash];
  132. }
  133. if ($idx === null) {
  134. $idx = '#' . ++$this->_idx;
  135. }
  136. if (isset($this->_objects[$idx])) {
  137. throw new \Magento\Framework\Exception\LocalizedException(
  138. new \Magento\Framework\Phrase(
  139. 'Object already exists in registry (%1). Old object class: %2, new object class: %3',
  140. [$idx, get_class($this->_objects[$idx]), get_class($object)]
  141. )
  142. );
  143. }
  144. $this->_objects[$idx] = $object;
  145. $this->_hashes[$hash] = $idx;
  146. $this->_objectHashes[$idx] = $hash;
  147. if (is_string($tags)) {
  148. $this->_tags[$tags][$idx] = true;
  149. $this->_objectTags[$idx][$tags] = true;
  150. } elseif (is_array($tags)) {
  151. foreach ($tags as $t) {
  152. $this->_tags[$t][$idx] = true;
  153. $this->_objectTags[$idx][$t] = true;
  154. }
  155. }
  156. //\Magento\Framework\Profiler::stop('OBJECT_SAVE');
  157. return $idx;
  158. }
  159. /**
  160. * Add a reference to an object
  161. *
  162. * @param string|array $refName
  163. * @param string $idx
  164. * @return bool|void
  165. * @throws \Magento\Framework\Exception\LocalizedException
  166. */
  167. public function reference($refName, $idx)
  168. {
  169. if (is_array($refName)) {
  170. foreach ($refName as $ref) {
  171. $this->reference($ref, $idx);
  172. }
  173. return;
  174. }
  175. if (isset($this->_references[$refName])) {
  176. throw new \Magento\Framework\Exception\LocalizedException(
  177. new \Magento\Framework\Phrase(
  178. 'The reference already exists: %1. New index: %2, old index: %3',
  179. [$refName, $idx, $this->_references[$refName]]
  180. )
  181. );
  182. }
  183. $this->_references[$refName] = $idx;
  184. $this->_objectReferences[$idx][$refName] = true;
  185. return true;
  186. }
  187. /**
  188. * Delete an object from registry
  189. *
  190. * @param string|object $idx
  191. * @return boolean
  192. */
  193. public function delete($idx)
  194. {
  195. //\Magento\Framework\Profiler::start("OBJECT_DELETE");
  196. if (is_object($idx)) {
  197. $idx = $this->find($idx);
  198. if (false === $idx) {
  199. //\Magento\Framework\Profiler::stop("OBJECT_DELETE");
  200. return false;
  201. }
  202. unset($this->_objects[$idx]);
  203. //\Magento\Framework\Profiler::stop("OBJECT_DELETE");
  204. return false;
  205. } elseif (!isset($this->_objects[$idx])) {
  206. //\Magento\Framework\Profiler::stop("OBJECT_DELETE");
  207. return false;
  208. }
  209. unset($this->_objects[$idx]);
  210. unset($this->_hashes[$this->_objectHashes[$idx]], $this->_objectHashes[$idx]);
  211. if (isset($this->_objectTags[$idx])) {
  212. foreach ($this->_objectTags[$idx] as $t => $dummy) {
  213. unset($this->_tags[$t][$idx]);
  214. }
  215. unset($this->_objectTags[$idx]);
  216. }
  217. if (isset($this->_objectReferences[$idx])) {
  218. foreach ($this->_references as $r => $dummy) {
  219. unset($this->_references[$r]);
  220. }
  221. unset($this->_objectReferences[$idx]);
  222. }
  223. //\Magento\Framework\Profiler::stop("OBJECT_DELETE");
  224. return true;
  225. }
  226. /**
  227. * Cleanup by class name for objects of subclasses too
  228. *
  229. * @param string $class
  230. * @return void
  231. */
  232. public function deleteByClass($class)
  233. {
  234. foreach ($this->_objects as $idx => $object) {
  235. if ($object instanceof $class) {
  236. $this->delete($idx);
  237. }
  238. }
  239. }
  240. /**
  241. * Cleanup objects by tags
  242. *
  243. * @param array|string $tags
  244. * @return true
  245. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  246. */
  247. public function deleteByTags($tags)
  248. {
  249. if (is_string($tags)) {
  250. $tags = [$tags];
  251. }
  252. foreach ($tags as $t) {
  253. foreach ($this->_tags[$t] as $idx => $dummy) {
  254. $this->delete($idx);
  255. }
  256. }
  257. return true;
  258. }
  259. /**
  260. * Check whether object id exists in registry
  261. *
  262. * @param string $idx
  263. * @return boolean
  264. */
  265. public function has($idx)
  266. {
  267. return isset($this->_objects[$idx]) || isset($this->_references[$idx]);
  268. }
  269. /**
  270. * Find an object id
  271. *
  272. * @param object $object
  273. * @return string|boolean
  274. */
  275. public function find($object)
  276. {
  277. foreach ($this->_objects as $idx => $obj) {
  278. if ($object === $obj) {
  279. return $idx;
  280. }
  281. }
  282. return false;
  283. }
  284. /**
  285. * Find objects by ids
  286. *
  287. * @param string[] $ids
  288. * @return array
  289. */
  290. public function findByIds($ids)
  291. {
  292. $objects = [];
  293. foreach ($this->_objects as $idx => $obj) {
  294. if (in_array($idx, $ids)) {
  295. $objects[$idx] = $obj;
  296. }
  297. }
  298. return $objects;
  299. }
  300. /**
  301. * Find object by hash
  302. *
  303. * @param string $hash
  304. * @return object
  305. */
  306. public function findByHash($hash)
  307. {
  308. return isset($this->_hashes[$hash]) ? $this->_objects[$this->_hashes[$hash]] : null;
  309. }
  310. /**
  311. * Find objects by tags
  312. *
  313. * @param array|string $tags
  314. * @return array
  315. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  316. */
  317. public function findByTags($tags)
  318. {
  319. if (is_string($tags)) {
  320. $tags = [$tags];
  321. }
  322. $objects = [];
  323. foreach ($tags as $t) {
  324. foreach ($this->_tags[$t] as $idx => $dummy) {
  325. if (isset($objects[$idx])) {
  326. continue;
  327. }
  328. $objects[$idx] = $this->load($idx);
  329. }
  330. }
  331. return $objects;
  332. }
  333. /**
  334. * Find by class name for objects of subclasses too
  335. *
  336. * @param string $class
  337. * @return array
  338. */
  339. public function findByClass($class)
  340. {
  341. $objects = [];
  342. foreach ($this->_objects as $idx => $object) {
  343. if ($object instanceof $class) {
  344. $objects[$idx] = $object;
  345. }
  346. }
  347. return $objects;
  348. }
  349. /**
  350. * Debug
  351. *
  352. * @param string $idx
  353. * @param object|null $object
  354. * @return void
  355. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  356. */
  357. public function debug($idx, $object = null)
  358. {
  359. $bt = debug_backtrace();
  360. $debug = [];
  361. foreach ($bt as $i => $step) {
  362. $debug[$i] = [
  363. 'file' => isset($step['file']) ? $step['file'] : null,
  364. 'line' => isset($step['line']) ? $step['line'] : null,
  365. 'function' => isset($step['function']) ? $step['function'] : null,
  366. ];
  367. }
  368. $this->_debug[$idx] = $debug;
  369. }
  370. /**
  371. * Return debug information by ids
  372. *
  373. * @param array|string $ids
  374. * @return array
  375. */
  376. public function debugByIds($ids)
  377. {
  378. if (is_string($ids)) {
  379. $ids = [$ids];
  380. }
  381. $debug = [];
  382. foreach ($ids as $idx) {
  383. $debug[$idx] = $this->_debug[$idx];
  384. }
  385. return $debug;
  386. }
  387. /**
  388. * Get all objects
  389. *
  390. * @return array
  391. */
  392. public function getAllObjects()
  393. {
  394. return $this->_objects;
  395. }
  396. /**
  397. * Get all tags
  398. *
  399. * @return array
  400. */
  401. public function getAllTags()
  402. {
  403. return $this->_tags;
  404. }
  405. /**
  406. * Get all tags by object
  407. *
  408. * @return array
  409. */
  410. public function getAllTagsByObject()
  411. {
  412. return $this->_objectTags;
  413. }
  414. /**
  415. * Get all references
  416. *
  417. * @return array
  418. */
  419. public function getAllReferences()
  420. {
  421. return $this->_references;
  422. }
  423. /**
  424. * Get all references by object
  425. *
  426. * @return array
  427. */
  428. public function getAllReferencesByObject()
  429. {
  430. return $this->_referencesByObject;
  431. }
  432. }