PageRenderTime 27ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/magento/module-catalog/Model/Product/Attribute/Backend/Media.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 356 lines | 268 code | 42 blank | 46 comment | 31 complexity | 31c0161b5bafc4ae221bd477d5463bed 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\Model\Product\Attribute\Backend;
  7. use Magento\Catalog\Model\Product;
  8. use Magento\MediaStorage\Model\File\Uploader as FileUploader;
  9. use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
  10. use Magento\Framework\Exception\LocalizedException;
  11. /**
  12. * Class Media backend model
  13. */
  14. class Media extends Product\Attribute\Backend\AbstractMedia
  15. {
  16. /**
  17. * @param Product $object
  18. * @return Product
  19. */
  20. public function afterLoad($object)
  21. {
  22. $attribute = $this->getAttribute();
  23. $attrCode = $attribute->getAttributeCode();
  24. $value = [];
  25. $value['images'] = [];
  26. $value['values'] = [];
  27. $localAttributes = ['label', 'position', 'disabled'];
  28. $mediaEntries = $this->getResource()->loadProductGalleryByAttributeId($object, $attribute->getId());
  29. foreach ($mediaEntries as $mediaEntry) {
  30. foreach ($localAttributes as $localAttribute) {
  31. if ($mediaEntry[$localAttribute] === null) {
  32. $mediaEntry[$localAttribute] = $this->findDefaultValue($localAttribute, $mediaEntry);
  33. }
  34. }
  35. $value['images'][] = $mediaEntry;
  36. }
  37. $object->setData($attrCode, $value);
  38. return $object;
  39. }
  40. /**
  41. * @param Product $object
  42. * @return Product
  43. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  44. * @SuppressWarnings(PHPMD.NPathComplexity)
  45. */
  46. public function beforeSave($object)
  47. {
  48. $attrCode = $this->getAttribute()->getAttributeCode();
  49. $value = $object->getData($attrCode);
  50. if (!is_array($value) || !isset($value['images'])) {
  51. return $object;
  52. }
  53. if (!is_array($value['images']) && strlen($value['images']) > 0) {
  54. $value['images'] = $this->jsonHelper->jsonDecode($value['images']);
  55. }
  56. if (!is_array($value['images'])) {
  57. $value['images'] = [];
  58. }
  59. $clearImages = [];
  60. $newImages = [];
  61. $existImages = [];
  62. if ($object->getIsDuplicate() != true) {
  63. foreach ($value['images'] as &$image) {
  64. if (!empty($image['removed'])) {
  65. $clearImages[] = $image['file'];
  66. } elseif (empty($image['value_id'])) {
  67. $newFile = $this->moveImageFromTmp($image['file']);
  68. $image['new_file'] = $newFile;
  69. $newImages[$image['file']] = $image;
  70. $image['file'] = $newFile;
  71. } else {
  72. $existImages[$image['file']] = $image;
  73. }
  74. }
  75. } else {
  76. // For duplicating we need copy original images.
  77. $duplicate = [];
  78. foreach ($value['images'] as &$image) {
  79. if (empty($image['value_id']) || !empty($image['removed'])) {
  80. continue;
  81. }
  82. $duplicate[$image['value_id']] = $this->copyImage($image['file']);
  83. $image['new_file'] = $duplicate[$image['value_id']];
  84. $newImages[$image['file']] = $image;
  85. }
  86. $value['duplicate'] = $duplicate;
  87. }
  88. foreach ($object->getMediaAttributes() as $mediaAttribute) {
  89. $mediaAttrCode = $mediaAttribute->getAttributeCode();
  90. $attrData = $object->getData($mediaAttrCode);
  91. if (in_array($attrData, $clearImages)) {
  92. $object->setData($mediaAttrCode, 'no_selection');
  93. }
  94. if (in_array($attrData, array_keys($newImages))) {
  95. $object->setData($mediaAttrCode, $newImages[$attrData]['new_file']);
  96. $object->setData($mediaAttrCode . '_label', $newImages[$attrData]['label']);
  97. }
  98. if (in_array($attrData, array_keys($existImages))) {
  99. $object->setData($mediaAttrCode . '_label', $existImages[$attrData]['label']);
  100. }
  101. }
  102. $object->setData($attrCode, $value);
  103. return $object;
  104. }
  105. /**
  106. * @param Product $object
  107. * @return Product
  108. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  109. * @SuppressWarnings(PHPMD.NPathComplexity)
  110. */
  111. public function afterSave($object)
  112. {
  113. if ($object->getIsDuplicate() == true) {
  114. $this->duplicate($object, $this->getAttribute());
  115. return $object;
  116. }
  117. $attrCode = $this->getAttribute()->getAttributeCode();
  118. $value = $object->getData($attrCode);
  119. if (!is_array($value) || !isset($value['images']) || $object->isLockedAttribute($attrCode)) {
  120. return $object;
  121. }
  122. $storeId = $object->getStoreId();
  123. $storeIds = $object->getStoreIds();
  124. $storeIds[] = \Magento\Store\Model\Store::DEFAULT_STORE_ID;
  125. // remove current storeId
  126. $storeIds = array_flip($storeIds);
  127. unset($storeIds[$storeId]);
  128. $storeIds = array_keys($storeIds);
  129. $images = $this->productFactory->create()->getAssignedImages($object, $storeIds);
  130. $picturesInOtherStores = [];
  131. foreach ($images as $image) {
  132. $picturesInOtherStores[$image['filepath']] = true;
  133. }
  134. $recordsToDelete = [];
  135. $filesToDelete = [];
  136. foreach ($value['images'] as &$image) {
  137. if (!empty($image['removed'])) {
  138. if (!empty($image['value_id']) && !isset($picturesInOtherStores[$image['file']])) {
  139. $recordsToDelete[] = $image['value_id'];
  140. $filesToDelete[] = ltrim($image['file'], '/');
  141. }
  142. continue;
  143. }
  144. if (empty($image['value_id'])) {
  145. $data = [];
  146. $data['attribute_id'] = $this->getAttribute()->getId();
  147. $data['value'] = $image['file'];
  148. if (!empty($image['media_type'])) {
  149. $data['media_type'] = $image['media_type'];
  150. }
  151. $image['value_id'] = $this->getResource()->insertGallery($data);
  152. $this->getResource()->bindValueToEntity($image['value_id'], $object->getId());
  153. }
  154. $this->getResource()->deleteGalleryValueInStore(
  155. $image['value_id'],
  156. $object->getId(),
  157. $object->getStoreId()
  158. );
  159. // Add per store labels, position, disabled
  160. $data = [];
  161. $data['value_id'] = $image['value_id'];
  162. $data['entity_id'] = $object->getId();
  163. $data['label'] = isset($image['label']) ? $image['label'] : '';
  164. $data['position'] = isset($image['position']) ? (int)$image['position'] : 0;
  165. $data['disabled'] = isset($image['disabled']) ? (int)$image['disabled'] : 0;
  166. $data['store_id'] = (int)$object->getStoreId();
  167. $data['entity_id'] = (int)$object->getId();
  168. $this->getResource()->insertGalleryValueInStore($data);
  169. }
  170. $this->getResource()->deleteGallery($recordsToDelete);
  171. $this->removeDeletedImages($filesToDelete);
  172. $object->setData($attrCode, $value);
  173. return $object;
  174. }
  175. /**
  176. * @param \Magento\Catalog\Model\Product $product
  177. * @param AbstractAttribute $attribute
  178. * @return $this
  179. */
  180. protected function duplicate($product, $attribute)
  181. {
  182. $mediaGalleryData = $product->getData($attribute->getAttributeCode());
  183. if (!isset($mediaGalleryData['images']) || !is_array($mediaGalleryData['images'])) {
  184. return $this;
  185. }
  186. $this->getResource()->duplicate(
  187. $attribute->getId(),
  188. isset($mediaGalleryData['duplicate']) ? $mediaGalleryData['duplicate'] : [],
  189. $product->getOriginalId(),
  190. $product->getId()
  191. );
  192. return $this;
  193. }
  194. /**
  195. * @param array $files
  196. * @return null
  197. */
  198. protected function removeDeletedImages(array $files)
  199. {
  200. $catalogPath = $this->mediaConfig->getBaseMediaPath();
  201. foreach ($files as $filePath) {
  202. $this->mediaDirectory->delete($catalogPath . '/' . $filePath);
  203. }
  204. }
  205. /**
  206. * Move image from temporary directory to normal
  207. *
  208. * @param string $file
  209. * @return string
  210. */
  211. protected function moveImageFromTmp($file)
  212. {
  213. $file = $this->getFilenameFromTmp($file);
  214. $destinationFile = $this->getUniqueFileName($file);
  215. if ($this->fileStorageDb->checkDbUsage()) {
  216. $this->fileStorageDb->renameFile(
  217. $this->mediaConfig->getTmpMediaShortUrl($file),
  218. $this->mediaConfig->getMediaShortUrl($destinationFile)
  219. );
  220. $this->mediaDirectory->delete($this->mediaConfig->getTmpMediaPath($file));
  221. $this->mediaDirectory->delete($this->mediaConfig->getMediaPath($destinationFile));
  222. } else {
  223. $this->mediaDirectory->renameFile(
  224. $this->mediaConfig->getTmpMediaPath($file),
  225. $this->mediaConfig->getMediaPath($destinationFile)
  226. );
  227. }
  228. return str_replace('\\', '/', $destinationFile);
  229. }
  230. /**
  231. * Check whether file to move exists. Getting unique name
  232. *
  233. * @param string $file
  234. * @param bool $forTmp
  235. * @return string
  236. */
  237. protected function getUniqueFileName($file, $forTmp = false)
  238. {
  239. if ($this->fileStorageDb->checkDbUsage()) {
  240. $destFile = $this->fileStorageDb->getUniqueFilename(
  241. $this->mediaConfig->getBaseMediaUrlAddition(),
  242. $file
  243. );
  244. } else {
  245. $destinationFile = $forTmp
  246. ? $this->mediaDirectory->getAbsolutePath($this->mediaConfig->getTmpMediaPath($file))
  247. : $this->mediaDirectory->getAbsolutePath($this->mediaConfig->getMediaPath($file));
  248. $destFile = dirname($file) . '/' . FileUploader::getNewFileName($destinationFile);
  249. }
  250. return $destFile;
  251. }
  252. /**
  253. * @param string $file
  254. * @return string
  255. */
  256. protected function getFilenameFromTmp($file)
  257. {
  258. return strrpos($file, '.tmp') == strlen($file) - 4 ? substr($file, 0, strlen($file) - 4) : $file;
  259. }
  260. /**
  261. * Copy image and return new filename.
  262. *
  263. * @param string $file
  264. * @return string
  265. * @throws \Magento\Framework\Exception\LocalizedException
  266. */
  267. protected function copyImage($file)
  268. {
  269. try {
  270. $destinationFile = $this->getUniqueFileName($file);
  271. if (!$this->mediaDirectory->isFile($this->mediaConfig->getMediaPath($file))) {
  272. throw new \Exception();
  273. }
  274. if ($this->fileStorageDb->checkDbUsage()) {
  275. $this->fileStorageDb->copyFile(
  276. $this->mediaDirectory->getAbsolutePath($this->mediaConfig->getMediaShortUrl($file)),
  277. $this->mediaConfig->getMediaShortUrl($destinationFile)
  278. );
  279. $this->mediaDirectory->delete($this->mediaConfig->getMediaPath($destinationFile));
  280. } else {
  281. $this->mediaDirectory->copyFile(
  282. $this->mediaConfig->getMediaPath($file),
  283. $this->mediaConfig->getMediaPath($destinationFile)
  284. );
  285. }
  286. return str_replace('\\', '/', $destinationFile);
  287. } catch (\Exception $e) {
  288. $file = $this->mediaConfig->getMediaPath($file);
  289. throw new LocalizedException(
  290. __('We couldn\'t copy file %1. Please delete media with non-existing images and try again.', $file)
  291. );
  292. }
  293. }
  294. /**
  295. * @param string $key
  296. * @param string[] &$image
  297. * @return string
  298. */
  299. protected function findDefaultValue($key, &$image)
  300. {
  301. if (isset($image[$key . '_default'])) {
  302. return $image[$key . '_default'];
  303. }
  304. return '';
  305. }
  306. }