Router.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. <?php
  2. /**
  3. * Copyright © 2015-2017 Ihor Vansach (ihor@magefan.com). All rights reserved.
  4. * See LICENSE.txt for license details (http://opensource.org/licenses/osl-3.0.php).
  5. *
  6. * Glory to Ukraine! Glory to the heroes!
  7. */
  8. namespace Magefan\Blog\Controller;
  9. use \Magefan\Blog\Model\Url;
  10. /**
  11. * Blog Controller Router
  12. */
  13. class Router implements \Magento\Framework\App\RouterInterface
  14. {
  15. /**
  16. * @var \Magento\Framework\App\ActionFactory
  17. */
  18. protected $actionFactory;
  19. /**
  20. * Event manager
  21. *
  22. * @var \Magento\Framework\Event\ManagerInterface
  23. */
  24. protected $_eventManager;
  25. /**
  26. * Store manager
  27. *
  28. * @var \Magento\Store\Model\StoreManagerInterface
  29. */
  30. protected $_storeManager;
  31. /**
  32. * Page factory
  33. *
  34. * @var \Magefan\Blog\Model\PostFactory
  35. */
  36. protected $_postFactory;
  37. /**
  38. * Category factory
  39. *
  40. * @var \Magefan\Blog\Model\CategoryFactory
  41. */
  42. protected $_categoryFactory;
  43. /**
  44. * Author factory
  45. *
  46. * @var \Magefan\Blog\Model\AuthorFactory
  47. */
  48. protected $_authorFactory;
  49. /**
  50. * Tag factory
  51. *
  52. * @var \Magefan\Blog\Model\TagFactory
  53. */
  54. protected $_tagFactory;
  55. /**
  56. * Config primary
  57. *
  58. * @var \Magento\Framework\App\State
  59. */
  60. protected $_appState;
  61. /**
  62. * Url
  63. *
  64. * @var \Magefan\Blog\Model\Url
  65. */
  66. protected $_url;
  67. /**
  68. * Response
  69. *
  70. * @var \Magento\Framework\App\ResponseInterface
  71. */
  72. protected $_response;
  73. /**
  74. * @var array
  75. */
  76. protected $_postId;
  77. /**
  78. * @var array
  79. */
  80. protected $_categoryId;
  81. /**
  82. * @var int
  83. */
  84. protected $_authorId;
  85. /**
  86. * @var int
  87. */
  88. protected $_tagId;
  89. /**
  90. * @param \Magento\Framework\App\ActionFactory $actionFactory
  91. * @param \Magento\Framework\Event\ManagerInterface $eventManager
  92. * @param \Magento\Framework\UrlInterface $url
  93. * @param \Magefan\Blog\Model\PostFactory $postFactory
  94. * @param \Magefan\Blog\Model\CategoryFactory $categoryFactory
  95. * @param \Magefan\Blog\Model\AuthorFactory $authorFactory
  96. * @param \Magefan\Blog\Model\TagFactory $tagFactory
  97. * @param \Magefan\Blog\Model\Url $url
  98. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  99. * @param \Magento\Framework\App\ResponseInterface $response
  100. */
  101. public function __construct(
  102. \Magento\Framework\App\ActionFactory $actionFactory,
  103. \Magento\Framework\Event\ManagerInterface $eventManager,
  104. Url $url,
  105. \Magefan\Blog\Model\PostFactory $postFactory,
  106. \Magefan\Blog\Model\CategoryFactory $categoryFactory,
  107. \Magefan\Blog\Model\AuthorFactory $authorFactory,
  108. \Magefan\Blog\Model\TagFactory $tagFactory,
  109. \Magento\Store\Model\StoreManagerInterface $storeManager,
  110. \Magento\Framework\App\ResponseInterface $response
  111. ) {
  112. $this->actionFactory = $actionFactory;
  113. $this->_eventManager = $eventManager;
  114. $this->_url = $url;
  115. $this->_postFactory = $postFactory;
  116. $this->_categoryFactory = $categoryFactory;
  117. $this->_authorFactory = $authorFactory;
  118. $this->_tagFactory = $tagFactory;
  119. $this->_storeManager = $storeManager;
  120. $this->_response = $response;
  121. }
  122. /**
  123. * Validate and Match Blog Pages and modify request
  124. *
  125. * @param \Magento\Framework\App\RequestInterface $request
  126. * @return bool
  127. */
  128. public function match(\Magento\Framework\App\RequestInterface $request)
  129. {
  130. $_identifier = trim($request->getPathInfo(), '/');
  131. $pathInfo = explode('/', $_identifier);
  132. $blogRoute = $this->_url->getRoute();
  133. if ($pathInfo[0] != $blogRoute) {
  134. return;
  135. }
  136. unset($pathInfo[0]);
  137. if (!count($pathInfo)) {
  138. $request
  139. ->setModuleName('blog')
  140. ->setControllerName('index')
  141. ->setActionName('index');
  142. } elseif ($pathInfo[1] == $this->_url->getRoute(Url::CONTROLLER_RSS)) {
  143. $request
  144. ->setModuleName('blog')
  145. ->setControllerName(Url::CONTROLLER_RSS)
  146. ->setActionName(isset($pathInfo[2]) ? $pathInfo[2] : 'index');
  147. } elseif ($pathInfo[1] == $this->_url->getRoute(Url::CONTROLLER_SEARCH)
  148. && !empty($pathInfo[2])
  149. ) {
  150. $request
  151. ->setModuleName('blog')
  152. ->setControllerName(Url::CONTROLLER_SEARCH)
  153. ->setActionName('index')
  154. ->setParam('q', $pathInfo[2]);
  155. } elseif ($pathInfo[1] == $this->_url->getRoute(Url::CONTROLLER_AUTHOR)
  156. && !empty($pathInfo[2])
  157. && ($authorId = $this->_getAuthorId($pathInfo[2]))
  158. ) {
  159. $request
  160. ->setModuleName('blog')
  161. ->setControllerName(Url::CONTROLLER_AUTHOR)
  162. ->setActionName('view')
  163. ->setParam('id', $authorId);
  164. } elseif ($pathInfo[1] == $this->_url->getRoute(Url::CONTROLLER_TAG)
  165. && !empty($pathInfo[2])
  166. && $tagId = $this->_getTagId($pathInfo[2])
  167. ) {
  168. $request
  169. ->setModuleName('blog')
  170. ->setControllerName(Url::CONTROLLER_TAG)
  171. ->setActionName('view')
  172. ->setParam('id', $tagId);
  173. } else {
  174. $controllerName = null;
  175. if (Url::PERMALINK_TYPE_DEFAULT == $this->_url->getPermalinkType()) {
  176. $controllerName = $this->_url->getControllerName($pathInfo[1]);
  177. unset($pathInfo[1]);
  178. }
  179. $pathInfo = array_values($pathInfo);
  180. $pathInfoCount = count($pathInfo);
  181. if ($pathInfoCount == 1) {
  182. if ( (!$controllerName || $controllerName == Url::CONTROLLER_ARCHIVE)
  183. && $this->_isArchiveIdentifier($pathInfo[0])
  184. ) {
  185. $request
  186. ->setModuleName('blog')
  187. ->setControllerName(Url::CONTROLLER_ARCHIVE)
  188. ->setActionName('view')
  189. ->setParam('date', $pathInfo[0]);
  190. } elseif ( (!$controllerName || $controllerName == Url::CONTROLLER_POST)
  191. && $postId = $this->_getPostId($pathInfo[0])
  192. ) {
  193. $request
  194. ->setModuleName('blog')
  195. ->setControllerName(Url::CONTROLLER_POST)
  196. ->setActionName('view')
  197. ->setParam('id', $postId);
  198. } elseif ( (!$controllerName || $controllerName == Url::CONTROLLER_CATEGORY)
  199. && $categoryId = $this->_getCategoryId($pathInfo[0])
  200. ) {
  201. $request
  202. ->setModuleName('blog')
  203. ->setControllerName(Url::CONTROLLER_CATEGORY)
  204. ->setActionName('view')
  205. ->setParam('id', $categoryId);
  206. }
  207. } elseif ($pathInfoCount > 1) {
  208. $postId = 0;
  209. $categoryId = 0;
  210. $first = true;
  211. $pathExist = true;
  212. for ($i = $pathInfoCount - 1; $i >= 0; $i--) {
  213. if ( (!$controllerName || $controllerName == Url::CONTROLLER_POST)
  214. && $first
  215. && ($postId = $this->_getPostId($pathInfo[$i]))
  216. ) {
  217. //we have postId
  218. } elseif ( (!$controllerName || !$first || $controllerName == Url::CONTROLLER_CATEGORY)
  219. && ($cid = $this->_getCategoryId($pathInfo[$i], $first))
  220. ) {
  221. if (!$categoryId) {
  222. $categoryId = $cid;
  223. }
  224. } else {
  225. $pathExist = false;
  226. break;
  227. }
  228. if ($first) {
  229. $first = false;
  230. }
  231. }
  232. if ($pathExist) {
  233. if ($postId) {
  234. $request
  235. ->setModuleName('blog')
  236. ->setControllerName(Url::CONTROLLER_POST)
  237. ->setActionName('view')
  238. ->setParam('id', $postId);
  239. if ($categoryId) {
  240. $request->setParam('category_id', $categoryId);
  241. }
  242. } elseif ($categoryId) {
  243. $request
  244. ->setModuleName('blog')
  245. ->setControllerName(Url::CONTROLLER_CATEGORY)
  246. ->setActionName('view')
  247. ->setParam('id', $categoryId);
  248. }
  249. } elseif ( (!$controllerName || $controllerName == Url::CONTROLLER_POST)
  250. && $postId = $this->_getPostId(implode('/', $pathInfo))
  251. ) {
  252. $request
  253. ->setModuleName('blog')
  254. ->setControllerName(Url::CONTROLLER_POST)
  255. ->setActionName('view')
  256. ->setParam('id', $postId);
  257. }
  258. }
  259. }
  260. $condition = new \Magento\Framework\DataObject(
  261. [
  262. 'identifier' => $_identifier,
  263. 'request' => $request,
  264. 'continue' => true
  265. ]
  266. );
  267. $this->_eventManager->dispatch(
  268. 'magefan_blog_controller_router_match_before',
  269. ['router' => $this, 'condition' => $condition]
  270. );
  271. if ($condition->getRedirectUrl()) {
  272. $this->_response->setRedirect($condition->getRedirectUrl());
  273. $request->setDispatched(true);
  274. return $this->actionFactory->create(
  275. 'Magento\Framework\App\Action\Redirect',
  276. ['request' => $request]
  277. );
  278. }
  279. if (!$condition->getContinue()) {
  280. return null;
  281. }
  282. if (!$request->getModuleName()) {
  283. return null;
  284. }
  285. $request->setAlias(\Magento\Framework\Url::REWRITE_REQUEST_PATH_ALIAS, $_identifier);
  286. return $this->actionFactory->create(
  287. 'Magento\Framework\App\Action\Forward',
  288. ['request' => $request]
  289. );
  290. }
  291. /**
  292. * Retrieve post id by identifier
  293. * @param string $identifier
  294. * @return int
  295. */
  296. protected function _getPostId($identifier, $checkSufix = true)
  297. {
  298. $key = $identifier . ($checkSufix ? '-checksufix' : '');
  299. if (!isset($this->_postId[$key])) {
  300. $sufix = $this->_url->getUrlSufix(Url::CONTROLLER_POST);
  301. $trimmedIdentifier = $this->_url->trimSufix($identifier, $sufix);
  302. if ($checkSufix && $sufix && $trimmedIdentifier == $identifier) { //if url without sufix
  303. $this->_postId[$key] = 0;
  304. } else {
  305. $post = $this->_postFactory->create();
  306. $this->_postId[$key] = $post->checkIdentifier(
  307. $trimmedIdentifier,
  308. $this->_storeManager->getStore()->getId()
  309. );
  310. }
  311. }
  312. return $this->_postId[$key];
  313. }
  314. /**
  315. * Retrieve category id by identifier
  316. * @param string $identifier
  317. * @return int
  318. */
  319. protected function _getCategoryId($identifier, $checkSufix = true)
  320. {
  321. $key = $identifier . ($checkSufix ? '-checksufix' : '');
  322. if (!isset($this->_categoryId[$key])) {
  323. $sufix = $this->_url->getUrlSufix(Url::CONTROLLER_CATEGORY);
  324. $trimmedIdentifier = $this->_url->trimSufix($identifier, $sufix);
  325. if ($checkSufix && $sufix && $trimmedIdentifier == $identifier) { //if url without sufix
  326. $this->_categoryId[$key] = 0;
  327. } else {
  328. $category = $this->_categoryFactory->create();
  329. $this->_categoryId[$key] = $category->checkIdentifier(
  330. $trimmedIdentifier,
  331. $this->_storeManager->getStore()->getId()
  332. );
  333. }
  334. }
  335. return $this->_categoryId[$key];
  336. }
  337. /**
  338. * Retrieve category id by identifier
  339. * @param string $identifier
  340. * @return int
  341. */
  342. protected function _getAuthorId($identifier)
  343. {
  344. if (is_null($this->_authorId)) {
  345. $author = $this->_authorFactory->create();
  346. $this->_authorId = $author->checkIdentifier(
  347. $identifier
  348. );
  349. }
  350. return $this->_authorId;
  351. }
  352. /**
  353. * Retrieve tag id by identifier
  354. * @param string $identifier
  355. * @return int
  356. */
  357. protected function _getTagId($identifier)
  358. {
  359. if (is_null($this->_tagId)) {
  360. $tag = $this->_tagFactory->create();
  361. $this->_tagId = $tag->checkIdentifier(
  362. $identifier
  363. );
  364. }
  365. return $this->_tagId;
  366. }
  367. /**
  368. * Detect arcive identifier
  369. * @param string $identifier
  370. * @return boolean
  371. */
  372. protected function _isArchiveIdentifier($identifier)
  373. {
  374. $info = explode('-', $identifier);
  375. return count($info) == 2
  376. && strlen($info[0]) == 4
  377. && strlen($info[1]) == 2
  378. && is_numeric($info[0])
  379. && is_numeric($info[1]);
  380. }
  381. }