PageRenderTime 26ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/Magento/Backend/Model/Url.php

https://gitlab.com/crazybutterfly815/magento2
PHP | 445 lines | 237 code | 32 blank | 176 comment | 32 complexity | 83468e6cd7dfe9d9c93a53850e3e5858 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Backend\Model;
  7. /**
  8. * Class \Magento\Backend\Model\UrlInterface
  9. *
  10. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  11. */
  12. class Url extends \Magento\Framework\Url implements \Magento\Backend\Model\UrlInterface
  13. {
  14. /**
  15. * Whether to use a security key in the backend
  16. *
  17. * @bug Currently, this constant is slightly misleading: it says "form key", but in fact it is used by URLs, too
  18. */
  19. const XML_PATH_USE_SECURE_KEY = 'admin/security/use_form_key';
  20. /**
  21. * Authentication session
  22. *
  23. * @var \Magento\Backend\Model\Auth\Session
  24. */
  25. protected $_session;
  26. /**
  27. * @var \Magento\Backend\Model\Menu
  28. */
  29. protected $_menu;
  30. /**
  31. * Startup page url from config
  32. *
  33. * @var string
  34. */
  35. protected $_startupMenuItemId;
  36. /**
  37. * @var \Magento\Backend\Helper\Data
  38. */
  39. protected $_backendHelper;
  40. /**
  41. * Menu config
  42. *
  43. * @var \Magento\Backend\Model\Menu\Config
  44. */
  45. protected $_menuConfig;
  46. /**
  47. * @var \Magento\Framework\App\CacheInterface
  48. */
  49. protected $_cache;
  50. /**
  51. * @var \Magento\Framework\Encryption\EncryptorInterface
  52. */
  53. protected $_encryptor;
  54. /**
  55. * @var \Magento\Store\Model\StoreFactory
  56. */
  57. protected $_storeFactory;
  58. /**
  59. * @var \Magento\Framework\Data\Form\FormKey
  60. */
  61. protected $formKey;
  62. /**
  63. * @var \Magento\Store\Model\Store
  64. */
  65. protected $_scope;
  66. /**
  67. * @param \Magento\Framework\App\Route\ConfigInterface $routeConfig
  68. * @param \Magento\Framework\App\RequestInterface $request
  69. * @param \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo
  70. * @param \Magento\Framework\Url\ScopeResolverInterface $scopeResolver
  71. * @param \Magento\Framework\Session\Generic $session
  72. * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
  73. * @param \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory
  74. * @param \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver
  75. * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  76. * @param \Magento\Framework\Url\RouteParamsPreprocessorInterface $routeParamsPreprocessor
  77. * @param string $scopeType
  78. * @param \Magento\Backend\Helper\Data $backendHelper
  79. * @param Menu\Config $menuConfig
  80. * @param \Magento\Framework\App\CacheInterface $cache
  81. * @param Auth\Session $authSession
  82. * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
  83. * @param \Magento\Store\Model\StoreFactory $storeFactory
  84. * @param \Magento\Framework\Data\Form\FormKey $formKey
  85. * @param array $data
  86. *
  87. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  88. */
  89. public function __construct(
  90. \Magento\Framework\App\Route\ConfigInterface $routeConfig,
  91. \Magento\Framework\App\RequestInterface $request,
  92. \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo,
  93. \Magento\Framework\Url\ScopeResolverInterface $scopeResolver,
  94. \Magento\Framework\Session\Generic $session,
  95. \Magento\Framework\Session\SidResolverInterface $sidResolver,
  96. \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory,
  97. \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver,
  98. \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
  99. \Magento\Framework\Url\RouteParamsPreprocessorInterface $routeParamsPreprocessor,
  100. $scopeType,
  101. \Magento\Backend\Helper\Data $backendHelper,
  102. \Magento\Backend\Model\Menu\Config $menuConfig,
  103. \Magento\Framework\App\CacheInterface $cache,
  104. \Magento\Backend\Model\Auth\Session $authSession,
  105. \Magento\Framework\Encryption\EncryptorInterface $encryptor,
  106. \Magento\Store\Model\StoreFactory $storeFactory,
  107. \Magento\Framework\Data\Form\FormKey $formKey,
  108. array $data = []
  109. ) {
  110. $this->_encryptor = $encryptor;
  111. parent::__construct(
  112. $routeConfig,
  113. $request,
  114. $urlSecurityInfo,
  115. $scopeResolver,
  116. $session,
  117. $sidResolver,
  118. $routeParamsResolverFactory,
  119. $queryParamsResolver,
  120. $scopeConfig,
  121. $routeParamsPreprocessor,
  122. $scopeType,
  123. $data
  124. );
  125. $this->_backendHelper = $backendHelper;
  126. $this->_menuConfig = $menuConfig;
  127. $this->_cache = $cache;
  128. $this->_session = $authSession;
  129. $this->formKey = $formKey;
  130. $this->_storeFactory = $storeFactory;
  131. }
  132. /**
  133. * Retrieve is secure mode for ULR logic
  134. *
  135. * @return bool
  136. */
  137. protected function _isSecure()
  138. {
  139. if ($this->hasData('secure_is_forced')) {
  140. return $this->getData('secure');
  141. }
  142. return $this->_scopeConfig->isSetFlag('web/secure/use_in_adminhtml');
  143. }
  144. /**
  145. * Force strip secret key param if _nosecret param specified
  146. *
  147. * @param array $data
  148. * @param bool $unsetOldParams
  149. * @return $this
  150. */
  151. protected function _setRouteParams(array $data, $unsetOldParams = true)
  152. {
  153. if (isset($data['_nosecret'])) {
  154. $this->setNoSecret(true);
  155. unset($data['_nosecret']);
  156. } else {
  157. $this->setNoSecret(false);
  158. }
  159. unset($data['_scope_to_url']);
  160. return parent::_setRouteParams($data, $unsetOldParams);
  161. }
  162. /**
  163. * Custom logic to retrieve Urls
  164. *
  165. * @param string $routePath
  166. * @param array $routeParams
  167. * @return string
  168. */
  169. public function getUrl($routePath = null, $routeParams = null)
  170. {
  171. if (filter_var($routePath, FILTER_VALIDATE_URL)) {
  172. return $routePath;
  173. }
  174. $cacheSecretKey = false;
  175. if (is_array($routeParams) && isset($routeParams['_cache_secret_key'])) {
  176. unset($routeParams['_cache_secret_key']);
  177. $cacheSecretKey = true;
  178. }
  179. $result = parent::getUrl($routePath, $routeParams);
  180. if (!$this->useSecretKey()) {
  181. return $result;
  182. }
  183. $this->_setRoutePath($routePath);
  184. $routeName = $this->_getRouteName('*');
  185. $controllerName = $this->_getControllerName(self::DEFAULT_CONTROLLER_NAME);
  186. $actionName = $this->_getActionName(self::DEFAULT_ACTION_NAME);
  187. if ($cacheSecretKey) {
  188. $secret = [self::SECRET_KEY_PARAM_NAME => "\${$routeName}/{$controllerName}/{$actionName}\$"];
  189. } else {
  190. $secret = [
  191. self::SECRET_KEY_PARAM_NAME => $this->getSecretKey($routeName, $controllerName, $actionName),
  192. ];
  193. }
  194. if (is_array($routeParams)) {
  195. $routeParams = array_merge($secret, $routeParams);
  196. } else {
  197. $routeParams = $secret;
  198. }
  199. if (is_array($this->_getRouteParams())) {
  200. $routeParams = array_merge($this->_getRouteParams(), $routeParams);
  201. }
  202. return parent::getUrl("{$routeName}/{$controllerName}/{$actionName}", $routeParams);
  203. }
  204. /**
  205. * Generate secret key for controller and action based on form key
  206. *
  207. * @param string $routeName
  208. * @param string $controller Controller name
  209. * @param string $action Action name
  210. * @return string
  211. */
  212. public function getSecretKey($routeName = null, $controller = null, $action = null)
  213. {
  214. $salt = $this->formKey->getFormKey();
  215. $request = $this->_getRequest();
  216. if (!$routeName) {
  217. if ($request->getBeforeForwardInfo('route_name') !== null) {
  218. $routeName = $request->getBeforeForwardInfo('route_name');
  219. } else {
  220. $routeName = $request->getRouteName();
  221. }
  222. }
  223. if (!$controller) {
  224. if ($request->getBeforeForwardInfo('controller_name') !== null) {
  225. $controller = $request->getBeforeForwardInfo('controller_name');
  226. } else {
  227. $controller = $request->getControllerName();
  228. }
  229. }
  230. if (!$action) {
  231. if ($request->getBeforeForwardInfo('action_name') !== null) {
  232. $action = $request->getBeforeForwardInfo('action_name');
  233. } else {
  234. $action = $request->getActionName();
  235. }
  236. }
  237. $secret = $routeName . $controller . $action . $salt;
  238. return $this->_encryptor->getHash($secret);
  239. }
  240. /**
  241. * Return secret key settings flag
  242. *
  243. * @return bool
  244. */
  245. public function useSecretKey()
  246. {
  247. return $this->_scopeConfig->isSetFlag(self::XML_PATH_USE_SECURE_KEY) && !$this->getNoSecret();
  248. }
  249. /**
  250. * Enable secret key using
  251. *
  252. * @return $this
  253. */
  254. public function turnOnSecretKey()
  255. {
  256. $this->setNoSecret(false);
  257. return $this;
  258. }
  259. /**
  260. * Disable secret key using
  261. *
  262. * @return $this
  263. */
  264. public function turnOffSecretKey()
  265. {
  266. $this->setNoSecret(true);
  267. return $this;
  268. }
  269. /**
  270. * Refresh admin menu cache etc.
  271. *
  272. * @return void
  273. */
  274. public function renewSecretUrls()
  275. {
  276. $this->_cache->clean([\Magento\Backend\Block\Menu::CACHE_TAGS]);
  277. }
  278. /**
  279. * Find admin start page url
  280. *
  281. * @return string
  282. */
  283. public function getStartupPageUrl()
  284. {
  285. $menuItem = $this->_getMenu()->get(
  286. $this->_scopeConfig->getValue(self::XML_PATH_STARTUP_MENU_ITEM, $this->_scopeType)
  287. );
  288. if ($menuItem !== null) {
  289. if ($menuItem->isAllowed() && $menuItem->getAction()) {
  290. return $menuItem->getAction();
  291. }
  292. }
  293. return $this->findFirstAvailableMenu();
  294. }
  295. /**
  296. * Find first menu item that user is able to access
  297. *
  298. * @return string
  299. */
  300. public function findFirstAvailableMenu()
  301. {
  302. /* @var $menu \Magento\Backend\Model\Menu\Item */
  303. $menu = $this->_getMenu();
  304. $item = $menu->getFirstAvailable();
  305. $action = $item ? $item->getAction() : null;
  306. if (!$item) {
  307. $user = $this->_getSession()->getUser();
  308. if ($user) {
  309. $user->setHasAvailableResources(false);
  310. }
  311. $action = '*/*/denied';
  312. }
  313. return $action;
  314. }
  315. /**
  316. * Get Menu model
  317. *
  318. * @return \Magento\Backend\Model\Menu
  319. */
  320. protected function _getMenu()
  321. {
  322. if ($this->_menu === null) {
  323. $this->_menu = $this->_menuConfig->getMenu();
  324. }
  325. return $this->_menu;
  326. }
  327. /**
  328. * Set custom auth session
  329. *
  330. * @param \Magento\Backend\Model\Auth\Session $session
  331. * @return $this
  332. */
  333. public function setSession(\Magento\Backend\Model\Auth\Session $session)
  334. {
  335. $this->_session = $session;
  336. return $this;
  337. }
  338. /**
  339. * Retrieve auth session
  340. *
  341. * @return \Magento\Backend\Model\Auth\Session
  342. */
  343. protected function _getSession()
  344. {
  345. return $this->_session;
  346. }
  347. /**
  348. * Return backend area front name, defined in configuration
  349. *
  350. * @return string
  351. */
  352. public function getAreaFrontName()
  353. {
  354. if (!$this->_getData('area_front_name')) {
  355. $this->setData('area_front_name', $this->_backendHelper->getAreaFrontName());
  356. }
  357. return $this->_getData('area_front_name');
  358. }
  359. /**
  360. * Retrieve action path.
  361. * Add backend area front name as a prefix to action path
  362. *
  363. * @return string
  364. */
  365. protected function _getActionPath()
  366. {
  367. $path = parent::_getActionPath();
  368. if ($path) {
  369. if ($this->getAreaFrontName()) {
  370. $path = $this->getAreaFrontName() . '/' . $path;
  371. }
  372. }
  373. return $path;
  374. }
  375. /**
  376. * Get scope for the url instance
  377. *
  378. * @return \Magento\Store\Model\Store
  379. */
  380. protected function _getScope()
  381. {
  382. if (!$this->_scope) {
  383. $this->_scope = $this->_storeFactory->create(
  384. [
  385. 'url' => $this,
  386. 'data' => ['code' => 'admin', 'force_disable_rewrites' => false, 'disable_store_in_url' => true],
  387. ]
  388. );
  389. }
  390. return $this->_scope;
  391. }
  392. /**
  393. * Get cache id for config path
  394. *
  395. * @param string $path
  396. * @return string
  397. */
  398. protected function _getConfigCacheId($path)
  399. {
  400. return 'admin/' . $path;
  401. }
  402. /**
  403. * Get config data by path
  404. * Use only global config values for backend
  405. *
  406. * @param string $path
  407. * @return null|string
  408. */
  409. protected function _getConfig($path)
  410. {
  411. return $this->_scopeConfig->getValue($path);
  412. }
  413. }