Baseurl.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Config\Model\Config\Backend;
  7. use Magento\Framework\Validator\Url as UrlValidator;
  8. use Magento\Framework\App\ObjectManager;
  9. /**
  10. * @api
  11. * @since 100.0.2
  12. */
  13. class Baseurl extends \Magento\Framework\App\Config\Value
  14. {
  15. /**
  16. * @var \Magento\Framework\View\Asset\MergeService
  17. */
  18. protected $_mergeService;
  19. /**
  20. * @var UrlValidator
  21. */
  22. private $urlValidator;
  23. /**
  24. * @param \Magento\Framework\Model\Context $context
  25. * @param \Magento\Framework\Registry $registry
  26. * @param \Magento\Framework\App\Config\ScopeConfigInterface $config
  27. * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
  28. * @param \Magento\Framework\View\Asset\MergeService $mergeService
  29. * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
  30. * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
  31. * @param array $data
  32. */
  33. public function __construct(
  34. \Magento\Framework\Model\Context $context,
  35. \Magento\Framework\Registry $registry,
  36. \Magento\Framework\App\Config\ScopeConfigInterface $config,
  37. \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
  38. \Magento\Framework\View\Asset\MergeService $mergeService,
  39. \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
  40. \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
  41. array $data = []
  42. ) {
  43. $this->_mergeService = $mergeService;
  44. parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
  45. }
  46. /**
  47. * Validate a base URL field value
  48. *
  49. * @return void
  50. * @throws \Magento\Framework\Exception\LocalizedException
  51. */
  52. public function beforeSave()
  53. {
  54. $value = $this->getValue();
  55. try {
  56. if (!$this->_validateUnsecure($value) && !$this->_validateSecure($value)) {
  57. $this->_validateFullyQualifiedUrl($value);
  58. }
  59. } catch (\Magento\Framework\Exception\LocalizedException $e) {
  60. $field = $this->getFieldConfig();
  61. $label = $field && is_array($field) ? $field['label'] : 'value';
  62. $msg = __('Invalid %1. %2', $label, $e->getMessage());
  63. $error = new \Magento\Framework\Exception\LocalizedException($msg, $e);
  64. throw $error;
  65. }
  66. }
  67. /**
  68. * Validation sub-routine for unsecure base URLs
  69. *
  70. * @param string $value
  71. * @return bool
  72. */
  73. private function _validateUnsecure($value)
  74. {
  75. $placeholders = ['{{unsecure_base_url}}'];
  76. switch ($this->getPath()) {
  77. case \Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL:
  78. $this->_assertValuesOrUrl(['{{base_url}}'], $value);
  79. break;
  80. case \Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_LINK_URL:
  81. $this->_assertStartsWithValuesOrUrl($placeholders, $value);
  82. break;
  83. case \Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_STATIC_URL:
  84. case \Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_MEDIA_URL:
  85. $this->_assertStartsWithValuesOrUrlOrEmpty($placeholders, $value);
  86. break;
  87. default:
  88. return false;
  89. }
  90. return true;
  91. }
  92. /**
  93. * Validation sub-routine for secure base URLs
  94. *
  95. * @param string $value
  96. * @return bool
  97. */
  98. private function _validateSecure($value)
  99. {
  100. $placeholders = ['{{unsecure_base_url}}', '{{secure_base_url}}'];
  101. switch ($this->getPath()) {
  102. case \Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL:
  103. $this->_assertValuesOrUrl(['{{base_url}}', '{{unsecure_base_url}}'], $value);
  104. break;
  105. case \Magento\Store\Model\Store::XML_PATH_SECURE_BASE_LINK_URL:
  106. $this->_assertStartsWithValuesOrUrl($placeholders, $value);
  107. break;
  108. case \Magento\Store\Model\Store::XML_PATH_SECURE_BASE_STATIC_URL:
  109. case \Magento\Store\Model\Store::XML_PATH_SECURE_BASE_MEDIA_URL:
  110. $this->_assertStartsWithValuesOrUrlOrEmpty($placeholders, $value);
  111. break;
  112. default:
  113. return false;
  114. }
  115. return true;
  116. }
  117. /**
  118. * Value equals to one of provided items or is a URL
  119. *
  120. * @param array $values
  121. * @param string $value
  122. * @return void
  123. * @throws \Magento\Framework\Exception\LocalizedException
  124. */
  125. private function _assertValuesOrUrl(array $values, $value)
  126. {
  127. if (!in_array($value, $values) && !$this->_isFullyQualifiedUrl($value)) {
  128. throw new \Magento\Framework\Exception\LocalizedException(
  129. __('Value must be a URL or one of placeholders: %1', implode(',', $values))
  130. );
  131. }
  132. }
  133. /**
  134. * Value starts with one of provided items or is a URL
  135. *
  136. * @param array $values
  137. * @param string $value
  138. * @return void
  139. * @throws \Magento\Framework\Exception\LocalizedException
  140. */
  141. private function _assertStartsWithValuesOrUrl(array $values, $value)
  142. {
  143. $quoted = array_map('preg_quote', $values, array_fill(0, count($values), '/'));
  144. if (!preg_match('/^(' . implode('|', $quoted) . ')(.+\/)?$/', $value) && !$this->_isFullyQualifiedUrl($value)
  145. ) {
  146. throw new \Magento\Framework\Exception\LocalizedException(
  147. __(
  148. 'Specify a URL or path that starts with placeholder(s): %1, and ends with "/".',
  149. implode(', ', $values)
  150. )
  151. );
  152. }
  153. }
  154. /**
  155. * Value starts with, empty or is a URL
  156. *
  157. * @param array $values
  158. * @param string $value
  159. * @return void
  160. * @throws \Magento\Framework\Exception\LocalizedException
  161. */
  162. private function _assertStartsWithValuesOrUrlOrEmpty(array $values, $value)
  163. {
  164. if (empty($value)) {
  165. return;
  166. }
  167. try {
  168. $this->_assertStartsWithValuesOrUrl($values, $value);
  169. } catch (\Magento\Framework\Exception\LocalizedException $e) {
  170. $msg = __('%1 An empty value is allowed as well.', $e->getMessage());
  171. $error = new \Magento\Framework\Exception\LocalizedException($msg, $e);
  172. throw $error;
  173. }
  174. }
  175. /**
  176. * Default validation of a URL
  177. *
  178. * @param string $value
  179. * @return void
  180. * @throws \Magento\Framework\Exception\LocalizedException
  181. */
  182. private function _validateFullyQualifiedUrl($value)
  183. {
  184. if (!$this->_isFullyQualifiedUrl($value)) {
  185. throw new \Magento\Framework\Exception\LocalizedException(__('Specify a fully qualified URL.'));
  186. }
  187. }
  188. /**
  189. * Whether the provided value can be considered as a fully qualified URL
  190. *
  191. * @param string $value
  192. * @return bool
  193. */
  194. private function _isFullyQualifiedUrl($value)
  195. {
  196. return preg_match('/\/$/', $value) && $this->getUrlValidator()->isValid($value, ['http', 'https']);
  197. }
  198. /**
  199. * Clean compiled JS/CSS when updating url configuration settings
  200. *
  201. * @return $this
  202. */
  203. public function afterSave()
  204. {
  205. if ($this->isValueChanged()) {
  206. switch ($this->getPath()) {
  207. case \Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL:
  208. case \Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_MEDIA_URL:
  209. case \Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL:
  210. case \Magento\Store\Model\Store::XML_PATH_SECURE_BASE_MEDIA_URL:
  211. $this->_mergeService->cleanMergedJsCss();
  212. break;
  213. }
  214. }
  215. return parent::afterSave();
  216. }
  217. /**
  218. * Get URL Validator
  219. *
  220. * @deprecated 101.0.0
  221. * @return UrlValidator
  222. */
  223. private function getUrlValidator()
  224. {
  225. if (!$this->urlValidator) {
  226. $this->urlValidator = ObjectManager::getInstance()->get(UrlValidator::class);
  227. }
  228. return $this->urlValidator;
  229. }
  230. }