PageRenderTime 27ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php

https://gitlab.com/crazybutterfly815/magento2
PHP | 349 lines | 219 code | 33 blank | 97 comment | 39 complexity | 661112573dd436557670c61cf968111f MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Catalog\Controller\Adminhtml\Category;
  7. use Magento\Store\Model\StoreManagerInterface;
  8. /**
  9. * Class Save
  10. *
  11. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  12. */
  13. class Save extends \Magento\Catalog\Controller\Adminhtml\Category
  14. {
  15. /**
  16. * @var \Magento\Framework\Controller\Result\RawFactory
  17. */
  18. protected $resultRawFactory;
  19. /**
  20. * @var \Magento\Framework\Controller\Result\JsonFactory
  21. */
  22. protected $resultJsonFactory;
  23. /**
  24. * @var \Magento\Framework\View\LayoutFactory
  25. */
  26. protected $layoutFactory;
  27. /**
  28. * The list of inputs that need to convert from string to boolean
  29. * @var array
  30. */
  31. protected $stringToBoolInputs = [
  32. 'custom_use_parent_settings',
  33. 'custom_apply_to_products',
  34. 'is_active',
  35. 'include_in_menu',
  36. 'is_anchor',
  37. 'use_default' => ['url_key'],
  38. 'use_config' => ['available_sort_by', 'filter_price_range', 'default_sort_by']
  39. ];
  40. /**
  41. * @var StoreManagerInterface
  42. */
  43. private $storeManager;
  44. /**
  45. * Constructor
  46. *
  47. * @param \Magento\Backend\App\Action\Context $context
  48. * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
  49. * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
  50. * @param \Magento\Framework\View\LayoutFactory $layoutFactory
  51. * @param StoreManagerInterface $storeManager
  52. */
  53. public function __construct(
  54. \Magento\Backend\App\Action\Context $context,
  55. \Magento\Framework\Controller\Result\RawFactory $resultRawFactory,
  56. \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
  57. \Magento\Framework\View\LayoutFactory $layoutFactory,
  58. StoreManagerInterface $storeManager
  59. ) {
  60. parent::__construct($context);
  61. $this->resultRawFactory = $resultRawFactory;
  62. $this->resultJsonFactory = $resultJsonFactory;
  63. $this->layoutFactory = $layoutFactory;
  64. $this->storeManager = $storeManager;
  65. }
  66. /**
  67. * Filter category data
  68. *
  69. * @param array $rawData
  70. * @return array
  71. */
  72. protected function _filterCategoryPostData(array $rawData)
  73. {
  74. $data = $rawData;
  75. // @todo It is a workaround to prevent saving this data in category model and it has to be refactored in future
  76. if (isset($data['image']) && is_array($data['image'])) {
  77. if (!empty($data['image']['delete'])) {
  78. $data['image'] = null;
  79. } else {
  80. if (isset($data['image'][0]['name']) && isset($data['image'][0]['tmp_name'])) {
  81. $data['image'] = $data['image'][0]['name'];
  82. } else {
  83. unset($data['image']);
  84. }
  85. }
  86. }
  87. return $data;
  88. }
  89. /**
  90. * Category save
  91. *
  92. * @return \Magento\Framework\Controller\ResultInterface
  93. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  94. * @SuppressWarnings(PHPMD.NPathComplexity)
  95. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  96. */
  97. public function execute()
  98. {
  99. /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
  100. $resultRedirect = $this->resultRedirectFactory->create();
  101. $category = $this->_initCategory();
  102. if (!$category) {
  103. return $resultRedirect->setPath('catalog/*/', ['_current' => true, 'id' => null]);
  104. }
  105. $data['general'] = $this->getRequest()->getPostValue();
  106. $categoryPostData = $data['general'];
  107. $isNewCategory = !isset($categoryPostData['entity_id']);
  108. $categoryPostData = $this->stringToBoolConverting($categoryPostData);
  109. $categoryPostData = $this->imagePreprocessing($categoryPostData);
  110. $categoryPostData = $this->dateTimePreprocessing($category, $categoryPostData);
  111. $storeId = isset($categoryPostData['store_id']) ? $categoryPostData['store_id'] : null;
  112. $store = $this->storeManager->getStore($storeId);
  113. $this->storeManager->setCurrentStore($store->getCode());
  114. $parentId = isset($categoryPostData['parent']) ? $categoryPostData['parent'] : null;
  115. if ($categoryPostData) {
  116. $category->addData($this->_filterCategoryPostData($categoryPostData));
  117. if ($isNewCategory) {
  118. $parentCategory = $this->getParentCategory($parentId, $storeId);
  119. $category->setPath($parentCategory->getPath());
  120. $category->setParentId($parentCategory->getId());
  121. }
  122. /**
  123. * Process "Use Config Settings" checkboxes
  124. */
  125. $useConfig = [];
  126. if (isset($categoryPostData['use_config']) && !empty($categoryPostData['use_config'])) {
  127. foreach ($categoryPostData['use_config'] as $attributeCode => $attributeValue) {
  128. if ($attributeValue) {
  129. $useConfig[] = $attributeCode;
  130. $category->setData($attributeCode, null);
  131. }
  132. }
  133. }
  134. $category->setAttributeSetId($category->getDefaultAttributeSetId());
  135. if (isset($categoryPostData['category_products'])
  136. && is_string($categoryPostData['category_products'])
  137. && !$category->getProductsReadonly()
  138. ) {
  139. $products = json_decode($categoryPostData['category_products'], true);
  140. $category->setPostedProducts($products);
  141. }
  142. $this->_eventManager->dispatch(
  143. 'catalog_category_prepare_save',
  144. ['category' => $category, 'request' => $this->getRequest()]
  145. );
  146. /**
  147. * Check "Use Default Value" checkboxes values
  148. */
  149. if (isset($categoryPostData['use_default']) && !empty($categoryPostData['use_default'])) {
  150. foreach ($categoryPostData['use_default'] as $attributeCode => $attributeValue) {
  151. if ($attributeValue) {
  152. $category->setData($attributeCode, null);
  153. }
  154. }
  155. }
  156. /**
  157. * Proceed with $_POST['use_config']
  158. * set into category model for processing through validation
  159. */
  160. $category->setData('use_post_data_config', $useConfig);
  161. try {
  162. $categoryResource = $category->getResource();
  163. if ($category->hasCustomDesignTo()) {
  164. $categoryResource->getAttribute('custom_design_from')->setMaxValue($category->getCustomDesignTo());
  165. }
  166. $validate = $category->validate();
  167. if ($validate !== true) {
  168. foreach ($validate as $code => $error) {
  169. if ($error === true) {
  170. $attribute = $categoryResource->getAttribute($code)->getFrontend()->getLabel();
  171. throw new \Magento\Framework\Exception\LocalizedException(
  172. __('Attribute "%1" is required.', $attribute)
  173. );
  174. } else {
  175. throw new \Exception($error);
  176. }
  177. }
  178. }
  179. $category->unsetData('use_post_data_config');
  180. $category->save();
  181. $this->messageManager->addSuccess(__('You saved the category.'));
  182. } catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
  183. $this->messageManager->addError($e->getMessage());
  184. $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
  185. $this->_getSession()->setCategoryData($categoryPostData);
  186. } catch (\Magento\Framework\Exception\LocalizedException $e) {
  187. $this->messageManager->addError($e->getMessage());
  188. $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
  189. $this->_getSession()->setCategoryData($categoryPostData);
  190. } catch (\Exception $e) {
  191. $this->messageManager->addError(__('Something went wrong while saving the category.'));
  192. $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
  193. $this->_getSession()->setCategoryData($categoryPostData);
  194. }
  195. }
  196. $hasError = (bool)$this->messageManager->getMessages()->getCountByType(
  197. \Magento\Framework\Message\MessageInterface::TYPE_ERROR
  198. );
  199. if ($this->getRequest()->getPost('return_session_messages_only')) {
  200. $category->load($category->getId());
  201. // to obtain truncated category name
  202. /** @var $block \Magento\Framework\View\Element\Messages */
  203. $block = $this->layoutFactory->create()->getMessagesBlock();
  204. $block->setMessages($this->messageManager->getMessages(true));
  205. /** @var \Magento\Framework\Controller\Result\Json $resultJson */
  206. $resultJson = $this->resultJsonFactory->create();
  207. return $resultJson->setData(
  208. [
  209. 'messages' => $block->getGroupedHtml(),
  210. 'error' => $hasError,
  211. 'category' => $category->toArray(),
  212. ]
  213. );
  214. }
  215. $redirectParams = $this->getRedirectParams($isNewCategory, $hasError, $category->getId(), $parentId, $storeId);
  216. return $resultRedirect->setPath(
  217. $redirectParams['path'],
  218. $redirectParams['params']
  219. );
  220. }
  221. /**
  222. * Image data preprocessing
  223. *
  224. * @param array $data
  225. *
  226. * @return array
  227. */
  228. public function imagePreprocessing($data)
  229. {
  230. if (empty($data['image'])) {
  231. unset($data['image']);
  232. $data['image']['delete'] = true;
  233. }
  234. return $data;
  235. }
  236. /**
  237. * Converting inputs from string to boolean
  238. *
  239. * @param array $data
  240. * @param array $stringToBoolInputs
  241. *
  242. * @return array
  243. */
  244. public function stringToBoolConverting($data, $stringToBoolInputs = null)
  245. {
  246. if (null === $stringToBoolInputs) {
  247. $stringToBoolInputs = $this->stringToBoolInputs;
  248. }
  249. foreach ($stringToBoolInputs as $key => $value) {
  250. if (is_array($value)) {
  251. if (isset($data[$key])) {
  252. $data[$key] = $this->stringToBoolConverting($data[$key], $value);
  253. }
  254. } else {
  255. if (isset($data[$value])) {
  256. if ($data[$value] === 'true') {
  257. $data[$value] = true;
  258. }
  259. if ($data[$value] === 'false') {
  260. $data[$value] = false;
  261. }
  262. }
  263. }
  264. }
  265. return $data;
  266. }
  267. /**
  268. * Get parent category
  269. *
  270. * @param int $parentId
  271. * @param int $storeId
  272. *
  273. * @return \Magento\Catalog\Model\Category
  274. */
  275. protected function getParentCategory($parentId, $storeId)
  276. {
  277. if (!$parentId) {
  278. if ($storeId) {
  279. $parentId = $this->_objectManager->get(
  280. \Magento\Store\Model\StoreManagerInterface::class
  281. )->getStore(
  282. $storeId
  283. )->getRootCategoryId();
  284. } else {
  285. $parentId = \Magento\Catalog\Model\Category::TREE_ROOT_ID;
  286. }
  287. }
  288. return $this->_objectManager->create(\Magento\Catalog\Model\Category::class)->load($parentId);
  289. }
  290. /**
  291. * Get category redirect path
  292. *
  293. * @param bool $isNewCategory
  294. * @param bool $hasError
  295. * @param int $categoryId
  296. * @param int $parentId
  297. * @param int $storeId
  298. *
  299. * @return array
  300. */
  301. protected function getRedirectParams($isNewCategory, $hasError, $categoryId, $parentId, $storeId)
  302. {
  303. $params = ['_current' => true];
  304. if ($storeId) {
  305. $params['store'] = $storeId;
  306. }
  307. if ($isNewCategory && $hasError) {
  308. $path = 'catalog/*/add';
  309. $params['parent'] = $parentId;
  310. } else {
  311. $path = 'catalog/*/edit';
  312. $params['id'] = $categoryId;
  313. }
  314. return ['path' => $path, 'params' => $params];
  315. }
  316. }