├── composer.json ├── modman ├── readme.markdown └── src └── app ├── code └── community │ └── AvS │ └── StoreViewCopy │ ├── Block │ └── Adminhtml │ │ └── CopyForm.php │ ├── Helper │ └── Data.php │ ├── Model │ └── Observer.php │ ├── controllers │ └── StoreviewcopyController.php │ └── etc │ └── config.xml ├── design └── adminhtml │ └── default │ └── default │ └── template │ └── storeviewcopy │ └── form.phtml ├── etc └── modules │ └── AvS_StoreViewCopy.xml └── locale └── de_DE └── AvS_StoreViewCopy.csv /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "avstudnitz/storeviewcopy", 3 | "type": "magento-module", 4 | "description": "Copies product attribute data from one store view to another via massaction", 5 | "homepage": "https://github.com/avstudnitz/StoreViewCopy" 6 | } 7 | -------------------------------------------------------------------------------- /modman: -------------------------------------------------------------------------------- 1 | src/app/code/community/AvS/StoreViewCopy app/code/community/AvS/StoreViewCopy 2 | src/app/design/adminhtml/default/default/template/storeviewcopy app/design/adminhtml/default/default/template/storeviewcopy 3 | src/app/etc/modules/AvS_StoreViewCopy.xml app/etc/modules/AvS_StoreViewCopy.xml 4 | src/app/locale/de_DE/AvS_StoreViewCopy.csv app/locale/de_DE/AvS_StoreViewCopy.csv 5 | -------------------------------------------------------------------------------- /readme.markdown: -------------------------------------------------------------------------------- 1 | AvS_StoreViewCopy 2 | ===================== 3 | Copies product attribute data from one store view to another via massaction 4 | 5 | Facts 6 | ----- 7 | - version: 0.1.0 8 | - extension key: AvS_StoreViewCopy 9 | - [extension on GitHub](https://github.com/avstudnitz/StoreViewCopy) 10 | - [direct download link](https://github.com/avstudnitz/StoreViewCopy/archive/master.tar.gz) 11 | - Composer key: avstudnitz/storeviewcopy 12 | 13 | Description 14 | ----------- 15 | Select the products you want to have copied in the products grid. Then, choose "Copy StoreView Attributes" from the massaction 16 | menu. On the next screen, you can choose source and target store view. 17 | 18 | Requirements 19 | ------------ 20 | - PHP >= 5.2.0 21 | - Mage_Core 22 | - Mage_Adminhtml 23 | 24 | Compatibility 25 | ------------- 26 | - Magento >= 1.4 27 | 28 | Installation Instructions 29 | ------------------------- 30 | 1. Copy all the files into your document root or use composer. 31 | 32 | Uninstallation 33 | -------------- 34 | 1. Remove all extension files from your Magento installation 35 | 36 | Support 37 | ------- 38 | If you have any issues with this extension, open an issue on [GitHub](https://github.com/avstudnitz/StoreViewCopy/issues). 39 | 40 | Contribution 41 | ------------ 42 | Any contribution is highly appreciated. The best way to contribute code is to open a [pull request on GitHub](https://help.github.com/articles/using-pull-requests). 43 | 44 | Developer 45 | --------- 46 | Andreas von Studnitz 47 | 48 | [http://www.avs-webentwicklung.de](http://www.avs-webentwicklung.de) 49 | 50 | [@avstudnitz](https://twitter.com/avstudnitz) 51 | 52 | Licence 53 | ------- 54 | [OSL - Open Software Licence 3.0](http://opensource.org/licenses/osl-3.0.php) 55 | 56 | Copyright 57 | --------- 58 | (c) 2012-2015 Andreas von Studnitz 59 | -------------------------------------------------------------------------------- /src/app/code/community/AvS/StoreViewCopy/Block/Adminhtml/CopyForm.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | class AvS_StoreViewCopy_Block_Adminhtml_CopyForm extends Mage_Adminhtml_Block_Widget 10 | { 11 | public function __construct() 12 | { 13 | parent::__construct(); 14 | 15 | $this->setTemplate('storeviewcopy/form.phtml'); 16 | $this->setTitle('Copy StoreView Attributes'); 17 | } 18 | 19 | protected function _prepareLayout() 20 | { 21 | $this->setChild('save_button', 22 | $this->getLayout()->createBlock('adminhtml/widget_button') 23 | ->setData(array( 24 | 'label' => Mage::helper('adminhtml')->__('Copy'), 25 | 'onclick' => 'storeviewcopyForm.submit()', 26 | 'class' => 'save', 27 | )) 28 | ); 29 | return parent::_prepareLayout(); 30 | } 31 | 32 | public function getSaveButtonHtml() 33 | { 34 | return $this->getChildHtml('save_button'); 35 | } 36 | 37 | public function getSaveUrl() 38 | { 39 | return $this->getUrl('*/*/save', array('_current'=>true)); 40 | } 41 | 42 | public function getStores() { 43 | 44 | return Mage::getModel('core/store')->getCollection()->setOrder('website_id', 'ASC')->setOrder('name', 'ASC'); 45 | } 46 | 47 | public function getProductIds() { 48 | 49 | return Mage::app()->getRequest()->getParam('product'); 50 | } 51 | 52 | public function getProducts() { 53 | $products = Mage::getModel('catalog/product')->getCollection(); 54 | $products->addAttributeToSelect('name'); 55 | $products->addAttributeToFilter('entity_id', array('in' => $this->getProductIds())); 56 | 57 | return $products; 58 | } 59 | 60 | public function getFullStoreName($store) { 61 | 62 | $name = array(); 63 | $name[] = $store->getWebsite()->getName(); 64 | $name[] = $store->getGroup()->getName(); 65 | $name[] = $store->getName(); 66 | 67 | return implode(' » ', $name); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/app/code/community/AvS/StoreViewCopy/Helper/Data.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class AvS_StoreViewCopy_Helper_Data extends Mage_Core_Helper_Abstract 11 | { 12 | } -------------------------------------------------------------------------------- /src/app/code/community/AvS/StoreViewCopy/Model/Observer.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | class AvS_StoreViewCopy_Model_Observer 10 | { 11 | 12 | /** 13 | * add Massaction Option to Productgrid 14 | * 15 | * @param $observer Varien_Event 16 | */ 17 | public function addMassactionToProductGrid($observer) 18 | { 19 | $block = $observer->getBlock(); 20 | if($block->getNameInLayout() === 'product.grid' && $block instanceof Mage_Adminhtml_Block_Widget_Grid){ 21 | 22 | $block->getMassactionBlock()->addItem('copy_storeview', array( 23 | 'label'=> Mage::helper('storeviewcopy')->__('Copy StoreView Attributes'), 24 | 'url' => $block->getUrl('*/storeviewcopy/form'), 25 | )); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/app/code/community/AvS/StoreViewCopy/controllers/StoreviewcopyController.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class AvS_StoreViewCopy_StoreviewcopyController extends Mage_Adminhtml_Controller_Action { 11 | 12 | /** 13 | * Basic action: reset form 14 | */ 15 | public function formAction() { 16 | 17 | if (!is_array($this->getRequest()->getParam('product')) || sizeof($this->getRequest()->getParam('product')) == 0) { 18 | 19 | $this->_getSession()->addError($this->__('Please select products.')); 20 | $this->_redirectReferer(); 21 | return; 22 | } 23 | 24 | $this->loadLayout() 25 | ->_setActiveMenu('catalog/product') 26 | ->_addBreadcrumb(Mage::helper('storeviewcopy')->__('Copy StoreView Attributes'), Mage::helper('storeviewcopy')->__('Copy StoreView Attributes')) 27 | ->_addContent($this->getLayout()->createBlock('storeviewcopy/adminhtml_copyForm')) 28 | ->renderLayout(); 29 | } 30 | 31 | /** 32 | * Basic action: reset save action 33 | */ 34 | public function saveAction() { 35 | 36 | if ($this->getRequest()->isPost()) { 37 | 38 | $targetStores = array(); 39 | foreach(Mage::getModel('core/store')->getCollection() as $store) { 40 | 41 | if ($this->getRequest()->getParam('target_store_' . $store->getId()) == 1) { 42 | $targetStores[] = $store->getId(); 43 | } 44 | } 45 | 46 | if (!$this->getRequest()->getParam('source_store') || empty($targetStores)) { 47 | 48 | $this->_getSession()->addError($this->__('Please select source and target store view.')); 49 | } elseif (in_array($this->getRequest()->getParam('source_store'), $targetStores)) { 50 | 51 | $this->_getSession()->addError($this->__('Source and Target StoreView must be different.')); 52 | } elseif (!$this->getRequest()->getParam('products')) { 53 | 54 | $this->_getSession()->addError($this->__('Please select products.')); 55 | } else { 56 | 57 | foreach(explode(',', $this->getRequest()->getParam('products')) as $productId) { 58 | 59 | foreach($targetStores as $targetStoreId) { 60 | 61 | try { 62 | 63 | $numberCopiedAttributes = $this->_copyAttributes($productId, $this->getRequest()->getParam('source_store'), $targetStoreId); 64 | $this->_getSession()->addSuccess($this->__('%s attributes of product %s have been copied.', $numberCopiedAttributes, $productId)); 65 | 66 | } catch(Exception $e) { 67 | 68 | $this->_getSession()->addError($this->__('An error occurred with product %s: %s', $productId, $e->getMessage())); 69 | } 70 | } 71 | } 72 | 73 | } 74 | } 75 | 76 | $this->_redirect('adminhtml/catalog_product'); 77 | } 78 | 79 | protected function _copyAttributes($productId, $sourceStoreId, $targetStoreId) { 80 | 81 | $updatedAttributes = 0; 82 | 83 | $sourceProduct = Mage::getModel('catalog/product')->setStoreId($sourceStoreId)->load($productId); 84 | $targetProduct = Mage::getModel('catalog/product')->setStoreId($targetStoreId)->load($productId); 85 | $attributeSet = Mage::getModel('eav/entity_attribute_set')->load($sourceProduct->getAttributeSetId()); 86 | foreach($this->_getAttributesFromSet($attributeSet) as $attribute) { 87 | 88 | if ($this->_updateAttribute($sourceProduct, $targetProduct, $attribute->getAttributeCode())) { 89 | 90 | $updatedAttributes++; 91 | } 92 | } 93 | 94 | return $updatedAttributes; 95 | } 96 | 97 | protected function _getAttributesFromSet($attributeSet) { 98 | 99 | $attributes = Mage::getResourceModel('catalog/product_attribute_collection') 100 | ->addFieldToFilter('is_global', array('in' => array(0, 2))) 101 | ->setAttributeSetFilter($attributeSet->getId()) 102 | ->load(); 103 | 104 | return $attributes; 105 | } 106 | 107 | protected function _updateAttribute($sourceProduct, $targetProduct, $attributeCode) { 108 | 109 | if ($sourceProduct->getData($attributeCode) != $targetProduct->getData($attributeCode)) { 110 | 111 | //echo $attributeCode . ': ' . $sourceProduct->getData($attributeCode) . ' : ' . $targetProduct->getData($attributeCode) . '
'; 112 | $targetProduct->setData($attributeCode, $sourceProduct->getData($attributeCode)); 113 | $targetProduct->getResource()->saveAttribute($targetProduct, $attributeCode); 114 | return true; 115 | } 116 | 117 | return false; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/app/code/community/AvS/StoreViewCopy/etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 0.1.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | AvS_StoreViewCopy_Model 13 | 14 | 15 | 16 | 17 | AvS_StoreViewCopy_Block 18 | 19 | 20 | 21 | 22 | AvS_StoreViewCopy_Helper 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | AvS_StoreViewCopy 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | AvS_StoreViewCopy.csv 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | singleton 54 | storeviewcopy/observer 55 | addMassactionToProductGrid 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/app/design/adminhtml/default/default/template/storeviewcopy/form.phtml: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 |

__($this->getTitle()) ?>

getSaveButtonHtml() ?>
7 |
8 |
9 |
10 |

11 | __('Selected Products') ?> 12 |

13 |
14 |
15 | getProducts() as $product): ?> 16 |

getName() ?> (getSku() ?>)

17 | 18 |
19 |
20 | 21 | getBlockHtml('formkey') ?> 22 |
23 |
24 |
25 |

26 | __('Source Store View') ?> 27 |

28 |
29 |
30 |
31 | getStores() as $store): ?> 32 |

33 | 34 | 35 |

36 | 37 |
38 |
39 |
40 |
41 |
42 |

43 | __('Target Store View') ?> 44 |

45 |
46 |
47 |
48 | getStores() as $store): ?> 49 |

50 | 51 | 52 |

53 | 54 |
55 |
56 |
57 |
58 |
59 |
60 | 63 | -------------------------------------------------------------------------------- /src/app/etc/modules/AvS_StoreViewCopy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | community 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/app/locale/de_DE/AvS_StoreViewCopy.csv: -------------------------------------------------------------------------------- 1 | "Copy StoreView Attributes","StoreView-Attribute kopieren" 2 | "Please select products.","Bitte Produkte auswählen." 3 | "Copy","Kopieren" 4 | "Source Store View","Quell-StoreView" 5 | "Target Store View","Ziel-StoreView" 6 | "Please select source and target store view.","Bitte wählen Sie Quell- und Ziel-StoreView." 7 | "%s attributes of product %s have been copied.","%s Attribute von Produkt %s wurden kopiert." 8 | "Source and Target StoreView must be different.","Quell- und Ziel-StoreView müssen unterschiedlich sein." 9 | "Selected Products","Ausgewählte Produkte" --------------------------------------------------------------------------------