123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Backend\Model;
- use Magento\Framework\Serialize\Serializer\Json;
- use Magento\Framework\Url\HostChecker;
- use Magento\Framework\App\ObjectManager;
- /**
- * Class \Magento\Backend\Model\UrlInterface
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- * @api
- * @since 100.0.2
- */
- class Url extends \Magento\Framework\Url implements \Magento\Backend\Model\UrlInterface
- {
- /**
- * Whether to use a security key in the backend
- *
- * @bug Currently, this constant is slightly misleading: it says "form key", but in fact it is used by URLs, too
- */
- const XML_PATH_USE_SECURE_KEY = 'admin/security/use_form_key';
- /**
- * Authentication session
- *
- * @var \Magento\Backend\Model\Auth\Session
- */
- protected $_session;
- /**
- * @var \Magento\Backend\Model\Menu
- */
- protected $_menu;
- /**
- * Startup page url from config
- *
- * @var string
- */
- protected $_startupMenuItemId;
- /**
- * @var \Magento\Backend\Helper\Data
- */
- protected $_backendHelper;
- /**
- * Menu config
- *
- * @var \Magento\Backend\Model\Menu\Config
- */
- protected $_menuConfig;
- /**
- * @var \Magento\Framework\App\CacheInterface
- */
- protected $_cache;
- /**
- * @var \Magento\Framework\Encryption\EncryptorInterface
- */
- protected $_encryptor;
- /**
- * @var \Magento\Store\Model\StoreFactory
- */
- protected $_storeFactory;
- /**
- * @var \Magento\Framework\Data\Form\FormKey
- */
- protected $formKey;
- /**
- * @var \Magento\Store\Model\Store
- */
- protected $_scope;
- /**
- * Constructor
- *
- * @param \Magento\Framework\App\Route\ConfigInterface $routeConfig
- * @param \Magento\Framework\App\RequestInterface $request
- * @param \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo
- * @param \Magento\Framework\Url\ScopeResolverInterface $scopeResolver
- * @param \Magento\Framework\Session\Generic $session
- * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
- * @param \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory
- * @param \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver
- * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
- * @param \Magento\Framework\Url\RouteParamsPreprocessorInterface $routeParamsPreprocessor
- * @param string $scopeType
- * @param \Magento\Backend\Helper\Data $backendHelper
- * @param Menu\Config $menuConfig
- * @param \Magento\Framework\App\CacheInterface $cache
- * @param Auth\Session $authSession
- * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
- * @param \Magento\Store\Model\StoreFactory $storeFactory
- * @param \Magento\Framework\Data\Form\FormKey $formKey
- * @param array $data
- * @param HostChecker|null $hostChecker
- * @param Json $serializer
- * @SuppressWarnings(PHPMD.ExcessiveParameterList)
- */
- public function __construct(
- \Magento\Framework\App\Route\ConfigInterface $routeConfig,
- \Magento\Framework\App\RequestInterface $request,
- \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo,
- \Magento\Framework\Url\ScopeResolverInterface $scopeResolver,
- \Magento\Framework\Session\Generic $session,
- \Magento\Framework\Session\SidResolverInterface $sidResolver,
- \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory,
- \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver,
- \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
- \Magento\Framework\Url\RouteParamsPreprocessorInterface $routeParamsPreprocessor,
- $scopeType,
- \Magento\Backend\Helper\Data $backendHelper,
- \Magento\Backend\Model\Menu\Config $menuConfig,
- \Magento\Framework\App\CacheInterface $cache,
- \Magento\Backend\Model\Auth\Session $authSession,
- \Magento\Framework\Encryption\EncryptorInterface $encryptor,
- \Magento\Store\Model\StoreFactory $storeFactory,
- \Magento\Framework\Data\Form\FormKey $formKey,
- array $data = [],
- HostChecker $hostChecker = null,
- Json $serializer = null
- ) {
- $this->_encryptor = $encryptor;
- $hostChecker = $hostChecker ?: ObjectManager::getInstance()->get(HostChecker::class);
- parent::__construct(
- $routeConfig,
- $request,
- $urlSecurityInfo,
- $scopeResolver,
- $session,
- $sidResolver,
- $routeParamsResolverFactory,
- $queryParamsResolver,
- $scopeConfig,
- $routeParamsPreprocessor,
- $scopeType,
- $data,
- $hostChecker,
- $serializer
- );
- $this->_backendHelper = $backendHelper;
- $this->_menuConfig = $menuConfig;
- $this->_cache = $cache;
- $this->_session = $authSession;
- $this->formKey = $formKey;
- $this->_storeFactory = $storeFactory;
- }
- /**
- * Retrieve is secure mode for ULR logic
- *
- * @return bool
- */
- protected function _isSecure()
- {
- if ($this->hasData('secure_is_forced')) {
- return $this->getData('secure');
- }
- return $this->_scopeConfig->isSetFlag('web/secure/use_in_adminhtml');
- }
- /**
- * Force strip secret key param if _nosecret param specified
- *
- * @param array $data
- * @param bool $unsetOldParams
- * @return $this
- */
- protected function _setRouteParams(array $data, $unsetOldParams = true)
- {
- if (isset($data['_nosecret'])) {
- $this->setNoSecret(true);
- unset($data['_nosecret']);
- } else {
- $this->setNoSecret(false);
- }
- unset($data['_scope_to_url']);
- return parent::_setRouteParams($data, $unsetOldParams);
- }
- /**
- * Custom logic to retrieve Urls
- *
- * @param string $routePath
- * @param array $routeParams
- * @return string
- */
- public function getUrl($routePath = null, $routeParams = null)
- {
- if (filter_var($routePath, FILTER_VALIDATE_URL)) {
- return $routePath;
- }
- $cacheSecretKey = false;
- if (isset($routeParams['_cache_secret_key'])) {
- unset($routeParams['_cache_secret_key']);
- $cacheSecretKey = true;
- }
- $result = parent::getUrl($routePath, $routeParams);
- if (!$this->useSecretKey()) {
- return $result;
- }
- $this->getRouteParamsResolver()->unsetData('route_params');
- $this->_setRoutePath($routePath);
- $extraParams = $this->getRouteParamsResolver()->getRouteParams();
- $routeName = $this->_getRouteName('*');
- $controllerName = $this->_getControllerName(self::DEFAULT_CONTROLLER_NAME);
- $actionName = $this->_getActionName(self::DEFAULT_ACTION_NAME);
- if (!isset($routeParams[self::SECRET_KEY_PARAM_NAME])) {
- if (!is_array($routeParams)) {
- $routeParams = [];
- }
- $secretKey = $cacheSecretKey
- ? "\${$routeName}/{$controllerName}/{$actionName}\$"
- : $this->getSecretKey($routeName, $controllerName, $actionName);
- $routeParams[self::SECRET_KEY_PARAM_NAME] = $secretKey;
- }
- if (!empty($extraParams)) {
- $routeParams = array_merge($extraParams, $routeParams);
- }
- return parent::getUrl("{$routeName}/{$controllerName}/{$actionName}", $routeParams);
- }
- /**
- * Generate secret key for controller and action based on form key
- *
- * @param string $routeName
- * @param string $controller Controller name
- * @param string $action Action name
- * @return string
- */
- public function getSecretKey($routeName = null, $controller = null, $action = null)
- {
- $salt = $this->formKey->getFormKey();
- $request = $this->_getRequest();
- if (!$routeName) {
- if ($request->getBeforeForwardInfo('route_name') !== null) {
- $routeName = $request->getBeforeForwardInfo('route_name');
- } else {
- $routeName = $request->getRouteName();
- }
- }
- if (!$controller) {
- if ($request->getBeforeForwardInfo('controller_name') !== null) {
- $controller = $request->getBeforeForwardInfo('controller_name');
- } else {
- $controller = $request->getControllerName();
- }
- }
- if (!$action) {
- if ($request->getBeforeForwardInfo('action_name') !== null) {
- $action = $request->getBeforeForwardInfo('action_name');
- } else {
- $action = $request->getActionName();
- }
- }
- $secret = $routeName . $controller . $action . $salt;
- return $this->_encryptor->getHash($secret);
- }
- /**
- * Return secret key settings flag
- *
- * @return bool
- */
- public function useSecretKey()
- {
- return $this->_scopeConfig->isSetFlag(self::XML_PATH_USE_SECURE_KEY) && !$this->getNoSecret();
- }
- /**
- * Enable secret key using
- *
- * @return $this
- */
- public function turnOnSecretKey()
- {
- $this->setNoSecret(false);
- return $this;
- }
- /**
- * Disable secret key using
- *
- * @return $this
- */
- public function turnOffSecretKey()
- {
- $this->setNoSecret(true);
- return $this;
- }
- /**
- * Refresh admin menu cache etc.
- *
- * @return void
- */
- public function renewSecretUrls()
- {
- $this->_cache->clean([\Magento\Backend\Block\Menu::CACHE_TAGS]);
- }
- /**
- * Find admin start page url
- *
- * @return string
- */
- public function getStartupPageUrl()
- {
- $menuItem = $this->_getMenu()->get(
- $this->_scopeConfig->getValue(self::XML_PATH_STARTUP_MENU_ITEM, $this->_scopeType)
- );
- if ($menuItem !== null) {
- if ($menuItem->isAllowed() && $menuItem->getAction()) {
- return $menuItem->getAction();
- }
- }
- return $this->findFirstAvailableMenu();
- }
- /**
- * Find first menu item that user is able to access
- *
- * @return string
- */
- public function findFirstAvailableMenu()
- {
- /* @var $menu \Magento\Backend\Model\Menu\Item */
- $menu = $this->_getMenu();
- $item = $menu->getFirstAvailable();
- $action = $item ? $item->getAction() : null;
- if (!$item) {
- $user = $this->_getSession()->getUser();
- if ($user) {
- $user->setHasAvailableResources(false);
- }
- $action = '*/*/denied';
- }
- return $action;
- }
- /**
- * Get Menu model
- *
- * @return \Magento\Backend\Model\Menu
- */
- protected function _getMenu()
- {
- if ($this->_menu === null) {
- $this->_menu = $this->_menuConfig->getMenu();
- }
- return $this->_menu;
- }
- /**
- * Set custom auth session
- *
- * @param \Magento\Backend\Model\Auth\Session $session
- * @return $this
- */
- public function setSession(\Magento\Backend\Model\Auth\Session $session)
- {
- $this->_session = $session;
- return $this;
- }
- /**
- * Retrieve auth session
- *
- * @return \Magento\Backend\Model\Auth\Session
- */
- protected function _getSession()
- {
- return $this->_session;
- }
- /**
- * Return backend area front name, defined in configuration
- *
- * @return string
- */
- public function getAreaFrontName()
- {
- if (!$this->_getData('area_front_name')) {
- $this->setData('area_front_name', $this->_backendHelper->getAreaFrontName());
- }
- return $this->_getData('area_front_name');
- }
- /**
- * Retrieve action path.
- * Add backend area front name as a prefix to action path
- *
- * @return string
- */
- protected function _getActionPath()
- {
- $path = parent::_getActionPath();
- if ($path) {
- if ($this->getAreaFrontName()) {
- $path = $this->getAreaFrontName() . '/' . $path;
- }
- }
- return $path;
- }
- /**
- * Get scope for the url instance
- *
- * @return \Magento\Store\Model\Store
- */
- protected function _getScope()
- {
- if (!$this->_scope) {
- $this->_scope = $this->_storeFactory->create(
- [
- 'url' => $this,
- 'data' => ['code' => 'admin', 'force_disable_rewrites' => false, 'disable_store_in_url' => true],
- ]
- );
- }
- return $this->_scope;
- }
- /**
- * Get cache id for config path
- *
- * @param string $path
- * @return string
- */
- protected function _getConfigCacheId($path)
- {
- return 'admin/' . $path;
- }
- /**
- * Get config data by path
- * Use only global config values for backend
- *
- * @param string $path
- * @return null|string
- */
- protected function _getConfig($path)
- {
- return $this->_scopeConfig->getValue($path);
- }
- }
|