Config.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Persistent\Model\Persistent;
  7. use Magento\Framework\Module\Dir;
  8. /**
  9. * Persistent Config Model
  10. */
  11. class Config
  12. {
  13. /**
  14. * Path to config file
  15. *
  16. * @var string
  17. */
  18. protected $_configFilePath;
  19. /**
  20. * @var \Magento\Framework\Config\DomFactory
  21. */
  22. protected $_domFactory;
  23. /**
  24. * @var \Magento\Framework\Module\Dir\Reader
  25. */
  26. protected $_moduleReader;
  27. /**
  28. * @var \DOMXPath
  29. */
  30. protected $_configDomXPath = null;
  31. /**
  32. * Layout model
  33. *
  34. * @var \Magento\Framework\View\LayoutInterface
  35. */
  36. protected $_layout;
  37. /**
  38. * App state model
  39. *
  40. * @var \Magento\Framework\App\State
  41. */
  42. protected $_appState;
  43. /**
  44. * Model factory
  45. *
  46. * @var \Magento\Persistent\Model\Factory
  47. */
  48. protected $_persistentFactory;
  49. /**
  50. * @var \Magento\Framework\Filesystem\Directory\ReadFactory
  51. */
  52. protected $readFactory;
  53. /**
  54. * @param \Magento\Framework\Config\DomFactory $domFactory
  55. * @param \Magento\Framework\Module\Dir\Reader $moduleReader
  56. * @param \Magento\Framework\View\LayoutInterface $layout
  57. * @param \Magento\Framework\App\State $appState
  58. * @param \Magento\Persistent\Model\Factory $persistentFactory
  59. * @param \Magento\Framework\Filesystem\Directory\ReadFactory $readFactory
  60. */
  61. public function __construct(
  62. \Magento\Framework\Config\DomFactory $domFactory,
  63. \Magento\Framework\Module\Dir\Reader $moduleReader,
  64. \Magento\Framework\View\LayoutInterface $layout,
  65. \Magento\Framework\App\State $appState,
  66. \Magento\Persistent\Model\Factory $persistentFactory,
  67. \Magento\Framework\Filesystem\Directory\ReadFactory $readFactory
  68. ) {
  69. $this->_domFactory = $domFactory;
  70. $this->_moduleReader = $moduleReader;
  71. $this->_layout = $layout;
  72. $this->_appState = $appState;
  73. $this->_persistentFactory = $persistentFactory;
  74. $this->readFactory = $readFactory;
  75. }
  76. /**
  77. * Set path to config file that should be loaded
  78. *
  79. * @param string $path
  80. * @return $this
  81. * @codeCoverageIgnore
  82. */
  83. public function setConfigFilePath($path)
  84. {
  85. $this->_configFilePath = $path;
  86. return $this;
  87. }
  88. /**
  89. * Get persistent XML config xpath
  90. *
  91. * @return \DOMXPath
  92. * @throws \Magento\Framework\Exception\LocalizedException
  93. */
  94. protected function _getConfigDomXPath()
  95. {
  96. if ($this->_configDomXPath === null) {
  97. $dir = explode("/", $this->_configFilePath);
  98. array_pop($dir);
  99. $dir = implode("/", $dir);
  100. $directoryRead = $this->readFactory->create($dir);
  101. $filePath = $directoryRead->getRelativePath($this->_configFilePath);
  102. $isFile = $directoryRead->isFile($filePath);
  103. $isReadable = $directoryRead->isReadable($filePath);
  104. if (!$isFile || !$isReadable) {
  105. throw new \Magento\Framework\Exception\LocalizedException(
  106. __('We cannot load the configuration from file %1.', $this->_configFilePath)
  107. );
  108. }
  109. $xml = $directoryRead->readFile($filePath);
  110. /** @var \Magento\Framework\Config\Dom $configDom */
  111. $configDom = $this->_domFactory->createDom(
  112. [
  113. 'xml' => $xml,
  114. 'idAttributes' => ['config/instances/blocks/reference' => 'id'],
  115. 'schemaFile' => $this->_moduleReader->getModuleDir(Dir::MODULE_ETC_DIR, 'Magento_Persistent')
  116. . '/persistent.xsd',
  117. ]
  118. );
  119. $this->_configDomXPath = new \DOMXPath($configDom->getDom());
  120. }
  121. return $this->_configDomXPath;
  122. }
  123. /**
  124. * Get block's persistent config info.
  125. *
  126. * @param string $block
  127. * @return array
  128. * @codeCoverageIgnore
  129. */
  130. public function getBlockConfigInfo($block)
  131. {
  132. $xPath = '//instances/blocks/*[block_type="' . $block . '"]';
  133. $blocks = $this->_getConfigDomXPath()->query($xPath);
  134. return $this->_convertBlocksToArray($blocks);
  135. }
  136. /**
  137. * Retrieve instances that should be emulated by persistent data
  138. *
  139. * @return array
  140. * @codeCoverageIgnore
  141. */
  142. public function collectInstancesToEmulate()
  143. {
  144. $xPath = '/config/instances/blocks/reference';
  145. $blocks = $this->_getConfigDomXPath()->query($xPath);
  146. $blocksArray = $this->_convertBlocksToArray($blocks);
  147. return ['blocks' => $blocksArray];
  148. }
  149. /**
  150. * Convert Blocks
  151. *
  152. * @param /DomNodeList $blocks
  153. * @return array
  154. */
  155. protected function _convertBlocksToArray($blocks)
  156. {
  157. $blocksArray = [];
  158. foreach ($blocks as $reference) {
  159. $referenceAttributes = $reference->attributes;
  160. $id = $referenceAttributes->getNamedItem('id')->nodeValue;
  161. $blocksArray[$id] = [];
  162. /** @var $referenceSubNode /DOMNode */
  163. foreach ($reference->childNodes as $referenceSubNode) {
  164. switch ($referenceSubNode->nodeName) {
  165. case 'name_in_layout':
  166. case 'class':
  167. case 'method':
  168. case 'block_type':
  169. $blocksArray[$id][$referenceSubNode->nodeName] = $referenceSubNode->nodeValue;
  170. break;
  171. default:
  172. }
  173. }
  174. }
  175. return $blocksArray;
  176. }
  177. /**
  178. * Run all methods declared in persistent configuration
  179. *
  180. * @return $this
  181. */
  182. public function fire()
  183. {
  184. foreach ($this->collectInstancesToEmulate() as $type => $elements) {
  185. if (!is_array($elements)) {
  186. continue;
  187. }
  188. foreach ($elements as $info) {
  189. switch ($type) {
  190. case 'blocks':
  191. $this->fireOne($info, $this->_layout->getBlock($info['name_in_layout']));
  192. break;
  193. }
  194. }
  195. }
  196. return $this;
  197. }
  198. /**
  199. * Run one method by given method info
  200. *
  201. * @param array $info
  202. * @param bool $instance
  203. * @return $this
  204. * @throws \Magento\Framework\Exception\LocalizedException
  205. */
  206. public function fireOne($info, $instance = false)
  207. {
  208. if (!$instance || isset(
  209. $info['block_type']
  210. ) && !$instance instanceof $info['block_type'] || !isset(
  211. $info['class']
  212. ) || !isset(
  213. $info['method']
  214. )
  215. ) {
  216. return $this;
  217. }
  218. $object = $this->_persistentFactory->create($info['class']);
  219. $method = $info['method'];
  220. if (method_exists($object, $method)) {
  221. $object->{$method}($instance);
  222. } elseif ($this->_appState->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) {
  223. throw new \Magento\Framework\Exception\LocalizedException(
  224. __('Method "%1" is not defined in "%2"', $method, get_class($object))
  225. );
  226. }
  227. return $this;
  228. }
  229. }