Config.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Simplexml;
  7. /**
  8. * Base class for simplexml based configurations
  9. *
  10. * @api
  11. * @since 100.0.2
  12. */
  13. class Config
  14. {
  15. /**
  16. * Configuration xml
  17. *
  18. * @var Element
  19. */
  20. protected $_xml = null;
  21. /**
  22. * Class name of simplexml elements for this configuration
  23. *
  24. * @var string
  25. */
  26. protected $_elementClass = \Magento\Framework\Simplexml\Element::class;
  27. /**
  28. * Xpath describing nodes in configuration that need to be extended
  29. *
  30. * @example <allResources extends="/config/modules//resource"/>
  31. */
  32. protected $_xpathExtends = "//*[@extends]";
  33. /**
  34. * Constructor
  35. *
  36. * Initializes XML for this configuration
  37. *
  38. * @see \Magento\Framework\Simplexml\Config::setXml
  39. * @param Element|string $sourceData
  40. */
  41. public function __construct($sourceData = null)
  42. {
  43. if ($sourceData === null) {
  44. return;
  45. }
  46. if ($sourceData instanceof Element) {
  47. $this->setXml($sourceData);
  48. } elseif (is_string($sourceData) && !empty($sourceData)) {
  49. if (strlen($sourceData) < 1000 && is_readable($sourceData)) {
  50. $this->loadFile($sourceData);
  51. } else {
  52. $this->loadString($sourceData);
  53. }
  54. }
  55. }
  56. /**
  57. * Sets xml for this configuration
  58. *
  59. * @param Element $node
  60. * @return $this
  61. */
  62. public function setXml(Element $node)
  63. {
  64. $this->_xml = $node;
  65. return $this;
  66. }
  67. /**
  68. * Returns node found by the $path
  69. *
  70. * @see \Magento\Framework\Simplexml\Element::descend
  71. * @param string $path
  72. * @return Element|bool
  73. */
  74. public function getNode($path = null)
  75. {
  76. if (!$this->getXml() instanceof Element) {
  77. return false;
  78. } elseif ($path === null) {
  79. return $this->getXml();
  80. } else {
  81. return $this->getXml()->descend($path);
  82. }
  83. }
  84. /**
  85. * Returns nodes found by xpath expression
  86. *
  87. * @param string $xpath
  88. * @return Element[]|bool
  89. */
  90. public function getXpath($xpath)
  91. {
  92. $xml = $this->getXml();
  93. if (empty($xml)) {
  94. return false;
  95. }
  96. if (!($result = @$xml->xpath($xpath))) {
  97. return false;
  98. }
  99. return $result;
  100. }
  101. /**
  102. * Return Xml of node as string
  103. *
  104. * @return string
  105. */
  106. public function getXmlString()
  107. {
  108. return $this->getNode()->asNiceXml('', false);
  109. }
  110. /**
  111. * Imports XML file
  112. *
  113. * @param string $filePath
  114. * @return boolean
  115. */
  116. public function loadFile($filePath)
  117. {
  118. if (!is_readable($filePath)) {
  119. //throw new \Exception('Can not read xml file '.$filePath);
  120. return false;
  121. }
  122. $fileData = file_get_contents($filePath);
  123. $fileData = $this->processFileData($fileData);
  124. return $this->loadString($fileData);
  125. }
  126. /**
  127. * Imports XML string
  128. *
  129. * @param string $string
  130. * @return boolean
  131. */
  132. public function loadString($string)
  133. {
  134. if (!empty($string)) {
  135. $xml = simplexml_load_string($string, $this->_elementClass);
  136. if ($xml) {
  137. $this->setXml($xml);
  138. return true;
  139. }
  140. }
  141. return false;
  142. }
  143. /**
  144. * Imports DOM node
  145. *
  146. * @param \DOMNode $dom
  147. * @return bool
  148. */
  149. public function loadDom(\DOMNode $dom)
  150. {
  151. $xml = simplexml_import_dom($dom, $this->_elementClass);
  152. if ($xml) {
  153. $this->setXml($xml);
  154. return true;
  155. }
  156. return false;
  157. }
  158. /**
  159. * Create node by $path and set its value.
  160. *
  161. * @param string $path separated by slashes
  162. * @param string $value
  163. * @param boolean $overwrite
  164. * @return $this
  165. */
  166. public function setNode($path, $value, $overwrite = true)
  167. {
  168. $this->getXml()->setNode($path, $value, $overwrite);
  169. return $this;
  170. }
  171. /**
  172. * Process configuration xml
  173. *
  174. * @return $this
  175. */
  176. public function applyExtends()
  177. {
  178. $targets = $this->getXpath($this->_xpathExtends);
  179. if (!$targets) {
  180. return $this;
  181. }
  182. foreach ($targets as $target) {
  183. $sources = $this->getXpath((string)$target['extends']);
  184. if ($sources) {
  185. foreach ($sources as $source) {
  186. $target->extend($source);
  187. }
  188. }
  189. }
  190. return $this;
  191. }
  192. /**
  193. * Stub method for processing file data right after loading the file text
  194. *
  195. * @param string $text
  196. * @return string
  197. */
  198. public function processFileData($text)
  199. {
  200. return $text;
  201. }
  202. /**
  203. * Enter description here...
  204. *
  205. * @param Config $config
  206. * @param boolean $overwrite
  207. * @return $this
  208. */
  209. public function extend(Config $config, $overwrite = true)
  210. {
  211. $this->getNode()->extend($config->getNode(), $overwrite);
  212. return $this;
  213. }
  214. /**
  215. * Cleanup circular references
  216. *
  217. * Destructor should be called explicitly in order to work around the PHP bug
  218. * https://bugs.php.net/bug.php?id=62468
  219. *
  220. * @return void
  221. */
  222. public function __destruct()
  223. {
  224. $this->_xml = null;
  225. }
  226. /**
  227. * Getter for xml element
  228. *
  229. * @return Element
  230. */
  231. protected function getXml()
  232. {
  233. return $this->_xml;
  234. }
  235. }