1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29: 30: 31: 32: 33:
34: class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract
35: {
36: protected $_renamedImages = array();
37:
38: 39: 40: 41: 42:
43: public function afterLoad($object)
44: {
45: $attrCode = $this->getAttribute()->getAttributeCode();
46: $value = array();
47: $value['images'] = array();
48: $value['values'] = array();
49: $localAttributes = array('label', 'position', 'disabled');
50:
51: foreach ($this->_getResource()->loadGallery($object, $this) as $image) {
52: foreach ($localAttributes as $localAttribute) {
53: if (is_null($image[$localAttribute])) {
54: $image[$localAttribute] = $this->_getDefaultValue($localAttribute, $image);
55: }
56: }
57: $value['images'][] = $image;
58: }
59:
60: $object->setData($attrCode, $value);
61: }
62:
63: protected function _getDefaultValue($key, &$image)
64: {
65: if (isset($image[$key . '_default'])) {
66: return $image[$key . '_default'];
67: }
68:
69: return '';
70: }
71:
72: 73: 74: 75: 76: 77: 78:
79: public function validate($object)
80: {
81: if ($this->getAttribute()->getIsRequired()) {
82: $value = $object->getData($this->getAttribute()->getAttributeCode());
83: if ($this->getAttribute()->isValueEmpty($value)) {
84: if ( !(is_array($value) && count($value)>0) ) {
85: return false;
86: }
87: }
88: }
89: if ($this->getAttribute()->getIsUnique()) {
90: if (!$this->getAttribute()->getEntity()->checkAttributeUniqueValue($this->getAttribute(), $object)) {
91: $label = $this->getAttribute()->getFrontend()->getLabel();
92: Mage::throwException(Mage::helper('eav')->__('The value of attribute "%s" must be unique.', $label));
93: }
94: }
95:
96: return true;
97: }
98:
99: public function beforeSave($object)
100: {
101: $attrCode = $this->getAttribute()->getAttributeCode();
102: $value = $object->getData($attrCode);
103: if (!is_array($value) || !isset($value['images'])) {
104: return;
105: }
106:
107: if(!is_array($value['images']) && strlen($value['images']) > 0) {
108: $value['images'] = Mage::helper('core')->jsonDecode($value['images']);
109: }
110:
111: if (!is_array($value['images'])) {
112: $value['images'] = array();
113: }
114:
115:
116:
117: $clearImages = array();
118: $newImages = array();
119: $existImages = array();
120: if ($object->getIsDuplicate()!=true) {
121: foreach ($value['images'] as &$image) {
122: if(!empty($image['removed'])) {
123: $clearImages[] = $image['file'];
124: } else if (!isset($image['value_id'])) {
125: $newFile = $this->_moveImageFromTmp($image['file']);
126: $image['new_file'] = $newFile;
127: $newImages[$image['file']] = $image;
128: $this->_renamedImages[$image['file']] = $newFile;
129: $image['file'] = $newFile;
130: } else {
131: $existImages[$image['file']] = $image;
132: }
133: }
134: } else {
135:
136: $duplicate = array();
137: foreach ($value['images'] as &$image) {
138: if (!isset($image['value_id'])) {
139: continue;
140: }
141: $duplicate[$image['value_id']] = $this->_copyImage($image['file']);
142: $newImages[$image['file']] = $duplicate[$image['value_id']];
143: }
144:
145: $value['duplicate'] = $duplicate;
146: }
147:
148: foreach ($object->getMediaAttributes() as $mediaAttribute) {
149: $mediaAttrCode = $mediaAttribute->getAttributeCode();
150: $attrData = $object->getData($mediaAttrCode);
151:
152: if (in_array($attrData, $clearImages)) {
153: $object->setData($mediaAttrCode, 'no_selection');
154: }
155:
156: if (in_array($attrData, array_keys($newImages))) {
157: $object->setData($mediaAttrCode, $newImages[$attrData]['new_file']);
158: $object->setData($mediaAttrCode.'_label', $newImages[$attrData]['label']);
159: }
160:
161: if (in_array($attrData, array_keys($existImages))) {
162: $object->setData($mediaAttrCode.'_label', $existImages[$attrData]['label']);
163: }
164: }
165:
166: Mage::dispatchEvent('catalog_product_media_save_before', array('product' => $object, 'images' => $value));
167:
168: $object->setData($attrCode, $value);
169:
170: return $this;
171: }
172:
173: 174: 175: 176: 177: 178:
179: public function getRenamedImage($file)
180: {
181: if (isset($this->_renamedImages[$file])) {
182: return $this->_renamedImages[$file];
183: }
184:
185: return $file;
186: }
187:
188: public function afterSave($object)
189: {
190: if ($object->getIsDuplicate() == true) {
191: $this->duplicate($object);
192: return;
193: }
194:
195: $attrCode = $this->getAttribute()->getAttributeCode();
196: $value = $object->getData($attrCode);
197: if (!is_array($value) || !isset($value['images']) || $object->isLockedAttribute($attrCode)) {
198: return;
199: }
200:
201: $storeId = $object->getStoreId();
202:
203: $storeIds = $object->getStoreIds();
204: $storeIds[] = Mage_Core_Model_App::ADMIN_STORE_ID;
205:
206:
207: $storeIds = array_flip($storeIds);
208: unset($storeIds[$storeId]);
209: $storeIds = array_keys($storeIds);
210:
211: $images = Mage::getResourceModel('catalog/product')
212: ->getAssignedImages($object, $storeIds);
213:
214: $picturesInOtherStores = array();
215: foreach ($images as $image) {
216: $picturesInOtherStores[$image['filepath']] = true;
217: }
218:
219: $toDelete = array();
220: $filesToValueIds = array();
221: foreach ($value['images'] as &$image) {
222: if(!empty($image['removed'])) {
223: if(isset($image['value_id']) && !isset($picturesInOtherStores[$image['file']])) {
224: $toDelete[] = $image['value_id'];
225: }
226: continue;
227: }
228:
229: if(!isset($image['value_id'])) {
230: $data = array();
231: $data['entity_id'] = $object->getId();
232: $data['attribute_id'] = $this->getAttribute()->getId();
233: $data['value'] = $image['file'];
234: $image['value_id'] = $this->_getResource()->insertGallery($data);
235: }
236:
237: $this->_getResource()->deleteGalleryValueInStore($image['value_id'], $object->getStoreId());
238:
239:
240: $data = array();
241: $data['value_id'] = $image['value_id'];
242: $data['label'] = $image['label'];
243: $data['position'] = (int) $image['position'];
244: $data['disabled'] = (int) $image['disabled'];
245: $data['store_id'] = (int) $object->getStoreId();
246:
247: $this->_getResource()->insertGalleryValueInStore($data);
248: }
249:
250: $this->_getResource()->deleteGallery($toDelete);
251: }
252:
253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263:
264: public function addImage(Mage_Catalog_Model_Product $product, $file,
265: $mediaAttribute = null, $move = false, $exclude = true)
266: {
267: $file = realpath($file);
268:
269: if (!$file || !file_exists($file)) {
270: Mage::throwException(Mage::helper('catalog')->__('Image does not exist.'));
271: }
272:
273: Mage::dispatchEvent('catalog_product_media_add_image', array('product' => $product, 'image' => $file));
274:
275: $pathinfo = pathinfo($file);
276: $imgExtensions = array('jpg','jpeg','gif','png');
277: if (!isset($pathinfo['extension']) || !in_array(strtolower($pathinfo['extension']), $imgExtensions)) {
278: Mage::throwException(Mage::helper('catalog')->__('Invalid image file type.'));
279: }
280:
281: $fileName = Mage_Core_Model_File_Uploader::getCorrectFileName($pathinfo['basename']);
282: $dispretionPath = Mage_Core_Model_File_Uploader::getDispretionPath($fileName);
283: $fileName = $dispretionPath . DS . $fileName;
284:
285: $fileName = $this->_getNotDuplicatedFilename($fileName, $dispretionPath);
286:
287: $ioAdapter = new Varien_Io_File();
288: $ioAdapter->setAllowCreateFolders(true);
289: $distanationDirectory = dirname($this->_getConfig()->getTmpMediaPath($fileName));
290:
291: try {
292: $ioAdapter->open(array(
293: 'path'=>$distanationDirectory
294: ));
295:
296:
297: $storageHelper = Mage::helper('core/file_storage_database');
298: if ($move) {
299: $ioAdapter->mv($file, $this->_getConfig()->getTmpMediaPath($fileName));
300:
301:
302: $storageHelper->saveFile($this->_getConfig()->getTmpMediaShortUrl($fileName));
303: } else {
304: $ioAdapter->cp($file, $this->_getConfig()->getTmpMediaPath($fileName));
305:
306: $storageHelper->saveFile($this->_getConfig()->getTmpMediaShortUrl($fileName));
307: $ioAdapter->chmod($this->_getConfig()->getTmpMediaPath($fileName), 0777);
308: }
309: }
310: catch (Exception $e) {
311: Mage::throwException(Mage::helper('catalog')->__('Failed to move file: %s', $e->getMessage()));
312: }
313:
314: $fileName = str_replace(DS, '/', $fileName);
315:
316: $attrCode = $this->getAttribute()->getAttributeCode();
317: $mediaGalleryData = $product->getData($attrCode);
318: $position = 0;
319: if (!is_array($mediaGalleryData)) {
320: $mediaGalleryData = array(
321: 'images' => array()
322: );
323: }
324:
325: foreach ($mediaGalleryData['images'] as &$image) {
326: if (isset($image['position']) && $image['position'] > $position) {
327: $position = $image['position'];
328: }
329: }
330:
331: $position++;
332: $mediaGalleryData['images'][] = array(
333: 'file' => $fileName,
334: 'position' => $position,
335: 'label' => '',
336: 'disabled' => (int) $exclude
337: );
338:
339: $product->setData($attrCode, $mediaGalleryData);
340:
341: if (!is_null($mediaAttribute)) {
342: $this->setMediaAttribute($product, $mediaAttribute, $fileName);
343: }
344:
345: return $fileName;
346: }
347:
348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358:
359: public function addImagesWithDifferentMediaAttributes(Mage_Catalog_Model_Product $product,
360: $fileAndAttributesArray, $filePath = '', $move = false, $exclude = true) {
361:
362: $alreadyAddedFiles = array();
363: $alreadyAddedFilesNames = array();
364:
365: foreach ($fileAndAttributesArray as $key => $value) {
366: $keyInAddedFiles = array_search($value['file'], $alreadyAddedFiles, true);
367: if ($keyInAddedFiles === false) {
368: $savedFileName = $this->addImage($product, $filePath . $value['file'], null, $move, $exclude);
369: $alreadyAddedFiles[$key] = $value['file'];
370: $alreadyAddedFilesNames[$key] = $savedFileName;
371: } else {
372: $savedFileName = $alreadyAddedFilesNames[$keyInAddedFiles];
373: }
374:
375: if (!is_null($value['mediaAttribute'])) {
376: $this->setMediaAttribute($product, $value['mediaAttribute'], $savedFileName);
377: }
378:
379: }
380:
381: return array('alreadyAddedFiles' => $alreadyAddedFiles, 'alreadyAddedFilesNames' => $alreadyAddedFilesNames);
382: }
383:
384: 385: 386: 387: 388: 389: 390: 391:
392: public function updateImage(Mage_Catalog_Model_Product $product, $file, $data)
393: {
394: $fieldsMap = array(
395: 'label' => 'label',
396: 'position' => 'position',
397: 'disabled' => 'disabled',
398: 'exclude' => 'disabled'
399: );
400:
401: $attrCode = $this->getAttribute()->getAttributeCode();
402:
403: $mediaGalleryData = $product->getData($attrCode);
404:
405: if (!isset($mediaGalleryData['images']) || !is_array($mediaGalleryData['images'])) {
406: return $this;
407: }
408:
409: foreach ($mediaGalleryData['images'] as &$image) {
410: if ($image['file'] == $file) {
411: foreach ($fieldsMap as $mappedField=>$realField) {
412: if (isset($data[$mappedField])) {
413: $image[$realField] = $data[$mappedField];
414: }
415: }
416: }
417: }
418:
419: $product->setData($attrCode, $mediaGalleryData);
420: return $this;
421: }
422:
423: 424: 425: 426: 427: 428: 429:
430: public function removeImage(Mage_Catalog_Model_Product $product, $file)
431: {
432: $attrCode = $this->getAttribute()->getAttributeCode();
433:
434: $mediaGalleryData = $product->getData($attrCode);
435:
436: if (!isset($mediaGalleryData['images']) || !is_array($mediaGalleryData['images'])) {
437: return $this;
438: }
439:
440: foreach ($mediaGalleryData['images'] as &$image) {
441: if ($image['file'] == $file) {
442: $image['removed'] = 1;
443: }
444: }
445:
446: $product->setData($attrCode, $mediaGalleryData);
447:
448: return $this;
449: }
450:
451: 452: 453: 454: 455: 456: 457:
458: public function getImage(Mage_Catalog_Model_Product $product, $file)
459: {
460: $attrCode = $this->getAttribute()->getAttributeCode();
461: $mediaGalleryData = $product->getData($attrCode);
462: if (!isset($mediaGalleryData['images']) || !is_array($mediaGalleryData['images'])) {
463: return false;
464: }
465:
466: foreach ($mediaGalleryData['images'] as $image) {
467: if ($image['file'] == $file) {
468: return $image;
469: }
470: }
471:
472: return false;
473: }
474:
475: 476: 477: 478: 479: 480: 481:
482: public function clearMediaAttribute(Mage_Catalog_Model_Product $product, $mediaAttribute)
483: {
484: $mediaAttributeCodes = array_keys($product->getMediaAttributes());
485:
486: if (is_array($mediaAttribute)) {
487: foreach ($mediaAttribute as $atttribute) {
488: if (in_array($atttribute, $mediaAttributeCodes)) {
489: $product->setData($atttribute, null);
490: }
491: }
492: } elseif (in_array($mediaAttribute, $mediaAttributeCodes)) {
493: $product->setData($mediaAttribute, null);
494: }
495:
496: return $this;
497: }
498:
499: 500: 501: 502: 503: 504: 505: 506:
507: public function setMediaAttribute(Mage_Catalog_Model_Product $product, $mediaAttribute, $value)
508: {
509: $mediaAttributeCodes = array_keys($product->getMediaAttributes());
510:
511: if (is_array($mediaAttribute)) {
512: foreach ($mediaAttribute as $atttribute) {
513: if (in_array($atttribute, $mediaAttributeCodes)) {
514: $product->setData($atttribute, $value);
515: }
516: }
517: } elseif (in_array($mediaAttribute, $mediaAttributeCodes)) {
518: $product->setData($mediaAttribute, $value);
519: }
520:
521: return $this;
522: }
523:
524: 525: 526: 527: 528:
529: protected function _getResource()
530: {
531: return Mage::getResourceSingleton('catalog/product_attribute_backend_media');
532: }
533:
534: 535: 536: 537: 538:
539: protected function _getConfig()
540: {
541: return Mage::getSingleton('catalog/product_media_config');
542: }
543:
544: 545: 546: 547: 548: 549:
550: protected function _moveImageFromTmp($file)
551: {
552: $ioObject = new Varien_Io_File();
553: $destDirectory = dirname($this->_getConfig()->getMediaPath($file));
554: try {
555: $ioObject->open(array('path'=>$destDirectory));
556: } catch (Exception $e) {
557: $ioObject->mkdir($destDirectory, 0777, true);
558: $ioObject->open(array('path'=>$destDirectory));
559: }
560:
561: if (strrpos($file, '.tmp') == strlen($file)-4) {
562: $file = substr($file, 0, strlen($file)-4);
563: }
564: $destFile = $this->_getUniqueFileName($file, $ioObject->dirsep());
565:
566:
567: $storageHelper = Mage::helper('core/file_storage_database');
568:
569: if ($storageHelper->checkDbUsage()) {
570: $storageHelper->renameFile(
571: $this->_getConfig()->getTmpMediaShortUrl($file),
572: $this->_getConfig()->getMediaShortUrl($destFile));
573:
574: $ioObject->rm($this->_getConfig()->getTmpMediaPath($file));
575: $ioObject->rm($this->_getConfig()->getMediaPath($destFile));
576: } else {
577: $ioObject->mv(
578: $this->_getConfig()->getTmpMediaPath($file),
579: $this->_getConfig()->getMediaPath($destFile)
580: );
581: }
582:
583: return str_replace($ioObject->dirsep(), '/', $destFile);
584: }
585:
586: 587: 588: 589: 590: 591: 592:
593: protected function _getUniqueFileName($file, $dirsep) {
594: if (Mage::helper('core/file_storage_database')->checkDbUsage()) {
595: $destFile = Mage::helper('core/file_storage_database')
596: ->getUniqueFilename(
597: Mage::getSingleton('catalog/product_media_config')->getBaseMediaUrlAddition(),
598: $file
599: );
600: } else {
601: $destFile = dirname($file) . $dirsep
602: . Mage_Core_Model_File_Uploader::getNewFileName($this->_getConfig()->getMediaPath($file));
603: }
604:
605: return $destFile;
606: }
607:
608: 609: 610: 611: 612: 613:
614: protected function _copyImage($file)
615: {
616: try {
617: $ioObject = new Varien_Io_File();
618: $destDirectory = dirname($this->_getConfig()->getMediaPath($file));
619: $ioObject->open(array('path'=>$destDirectory));
620:
621: $destFile = $this->_getUniqueFileName($file, $ioObject->dirsep());
622:
623: if (!$ioObject->fileExists($this->_getConfig()->getMediaPath($file),true)) {
624: throw new Exception();
625: }
626:
627: if (Mage::helper('core/file_storage_database')->checkDbUsage()) {
628: Mage::helper('core/file_storage_database')
629: ->copyFile($this->_getConfig()->getMediaShortUrl($file),
630: $this->_getConfig()->getMediaShortUrl($destFile));
631:
632: $ioObject->rm($this->_getConfig()->getMediaPath($destFile));
633: } else {
634: $ioObject->cp(
635: $this->_getConfig()->getMediaPath($file),
636: $this->_getConfig()->getMediaPath($destFile)
637: );
638: }
639:
640: } catch (Exception $e) {
641: $file = $this->_getConfig()->getMediaPath($file);
642: Mage::throwException(
643: Mage::helper('catalog')->__('Failed to copy file %s. Please, delete media with non-existing images and try again.', $file)
644: );
645: }
646:
647: return str_replace($ioObject->dirsep(), '/', $destFile);
648: }
649:
650: public function duplicate($object)
651: {
652: $attrCode = $this->getAttribute()->getAttributeCode();
653: $mediaGalleryData = $object->getData($attrCode);
654:
655: if (!isset($mediaGalleryData['images']) || !is_array($mediaGalleryData['images'])) {
656: return $this;
657: }
658:
659: $this->_getResource()->duplicate(
660: $this,
661: (isset($mediaGalleryData['duplicate']) ? $mediaGalleryData['duplicate'] : array()),
662: $object->getOriginalId(),
663: $object->getId()
664: );
665:
666: return $this;
667: }
668:
669: 670: 671: 672: 673: 674: 675:
676: protected function _getNotDuplicatedFilename($fileName, $dispretionPath)
677: {
678: $fileMediaName = $dispretionPath . DS
679: . Mage_Core_Model_File_Uploader::getNewFileName($this->_getConfig()->getMediaPath($fileName));
680: $fileTmpMediaName = $dispretionPath . DS
681: . Mage_Core_Model_File_Uploader::getNewFileName($this->_getConfig()->getTmpMediaPath($fileName));
682:
683: if ($fileMediaName != $fileTmpMediaName) {
684: if ($fileMediaName != $fileName) {
685: return $this->_getNotDuplicatedFileName($fileMediaName, $dispretionPath);
686: } elseif ($fileTmpMediaName != $fileName) {
687: return $this->_getNotDuplicatedFilename($fileTmpMediaName, $dispretionPath);
688: }
689: }
690:
691: return $fileMediaName;
692: }
693: }
694: