Magento setting Product Attribute's "Use Default Value" using updateAttributes - magento

I have a multi-store setup and I am setting a Product's Attribute for a particular store to use the "Use Default Value" option - (ie to use the value in the Store View), as follows:
$_product = Mage::getModel('catalog/product');
$_product->load($productId);
$_product->setStoreId($storeId)->setName(false)->save();
This sets the Name attribute of storeId for $productId to use "Use Default Value"
Given that I have a lot of attributes to set I am trying to use:
Mage::getSingleton('catalog/product_action')->updateAttributes(array($productId), array('name' => false), $storeId);
But this is not setting the "Use Default Value" checkbox to true.
How can I use ->updateAttributes to set a store value to use the "Use Default Value" option?
Screenshot:

The "Use Default Value" flag isn't stored in the database anywhere.
Magento core uses that flag to do this when saving products:
/**
* Check "Use Default Value" checkboxes values
*/
if ($useDefaults = $this->getRequest()->getPost('use_default')) {
foreach ($useDefaults as $attributeCode) {
$product->setData($attributeCode, false);
}
}
Before doing some other things.
I would look at Mage_Adminhtml_Catalog_ProductController (app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php) and learn how Magento core does it.
Specifically saveAction() and _initProductSave()
I hope this points you in the right direction.

Simply use 0 as the store ID (admin store) which is the same thing as default values in the Magento Admin.
Mage::getSingleton('catalog/product_action')
->updateAttributes(
array($productId),
array('name' => false),
0);
If you already set the store view scopes you will have to go in and recheck the use default values or it will override the attribute at the relevant scope.
There may be a way to programmatically set these. I'm uncertain.

Related

How to change magento config programatically for different stores?

I have a list of custom options in magento config and I need to change them programmatically when an user clicks on "Save Config". In generally it's not a big problem to get it done using observer but I need to have one option like "Pack of options" and if user choose one of package appropriate options must be changed programatically. It's not a big deal too:
Mage::getConfig()->saveConfig('path/to/config/', 1, 'default', 0);
Mage::getConfig()->saveConfig('path/to/config2/', 1, 'default', 0);
But the problem is that I can't get it working for different stores, it's working for default scope only. Example:
Mage::getConfig()->saveConfig('path/to/config2/', 1, 'german', 0);
isn't working.
How can I update options programatically for certain stores only? So the user could check witch store he wants to apply options too?
Thanks for any help.
Try this:
$storeCode = 'german';
$store = Mage::getModel('core/store')->load($storeCode);
$path = 'path/to/config';
$config = Mage::getModel('core/config_data');
$config->setValue('Your value here');
$config->setPath($path);
$config->setScope('stores');
$config->setScopeId($store->getId());
$config->save();
Look at the definition of the function :
public function saveConfig($path, $value, $scope = 'default', $scopeId = 0)
The scope can actually take only 3 values : 'default', 'stores' or 'websites'.
Let's suppose your german store has 3 as Id, here is the code that would work :
$config = Mage::getModel('core/config');
$config->saveConfig('path/to/config/', 'value_to_set', 'stores', 3);
For a website-scoped config :
$config->saveConfig('path/to/config/', 'value_to_set', 'websites', $websiteId);

Magento - Get attribute value per website

I've created (manually via Admin Panel) an attribute called att_by_website which is scoped as 'Website' and I'm want to get its several values.
How can I do this? I'm able to set different values via Admin Panel, but at this time I'm only able to get the default value.
When I execute $this->getProduct()->getData('att_by_website') it returns only the default value (where $this->getProduct() returns an instance of Mage_Catalog_Model_Product).
Thanks!
It may not be the best approach, but solved the problem:
$value = Mage::getResourceModel('catalog/product')->getAttributeRawValue($productID, 'att_by_website', $storeId);
Try this:
foreach (Mage::app()->getWebsites() as $website) {
$websiteId = $website->getWebsiteId();
$storeId = $website->getDefaultGroup()->getDefaultStoreId();
Mage::app()->setCurrentStore($storeId);
echo $this->getProduct()->getData('att_by_website');
}

Magento "Forgot Password" email sent in wrong language

I have a Magento site with multiple languages. I have setup the language packs and everything seems to translate properly on the website. Also the transactional e-mails are sent in the correct language EXCEPT for the "Forgot Password" e-mail which is always sent in German. Here's what I did:
Installed language packs and made sure all templates and folder structures are correct. Example: /app/locale/nl_NL/template/email/
Under System » Transactional Emails: I applied the template, chose the locale and saved.
Then I went to System » Configuration » Sales Emails, I switched to each language from the "Current Configuration Scope" dropdown, and I chose the templates I created in Transactional Emails for each language (each store view).
After looking around online for a solution, it seems others had this problem too and someone mentioned that Magento is picking the "Forgot Password" template from the first locale folder found in /app/locale/. In my case I had: de_DE, en_US, fr_FR, nl_NL. So It picks the template from the German de_DE pack.
NOTE: Also, in the backend under "Configuration" there's a tab on the left called "LOCALE PACKS" which only has "Locale de_DE" under it, even though I have other language packs which don't show up here. Not sure if this is relevant.
Site: http://site1.cp1.glimworm.com/magento/
Magento Community version: 1.7.0.2
Locale packs:
Mage_Locale_en_US
Locale_Mage_community_de_DE
Locale_Mage_community_fr_FR
Mage_Locale_nl_NL
Any idea how I can get the correct email template from the corresponding language to be sent as opposed to always German? Any help will be greatly appreciated! I can provide more info as well.
I have same problem in magento v1.5. After a long research i found this solution and its working for me.
Mage/Customer/Model/Customer.php
in this file i have make some changes as following.
find this line of code
if (!$storeId)
{
$storeId = $this->_getWebsiteStoreId($this->getSendemailStoreId());
}
and replace with
$storeId = ($storeId == '0')?$this->getSendemailStoreId():$storeId;
if ($this->getWebsiteId() != '0' && $storeId == '0')
{
$storeIds = Mage::app()->getWebsite($this->getWebsiteId())->getStoreIds();
reset($storeIds);
$storeId = current($storeIds);
}
I had the same problem, and it looks like user2282917's solution works with a little modify:
You should edit the sendPasswordResetConfirmationEmail function in the Customer.php not the sendNewAccountEmail. Try to replace the code there, and it will working.
Overwrite the forgotPasswordPostAction controller on the AccountController.php.
You need to set the correct store id so that the locale will be used.
/**
* Forgot customer password action
*/
public function forgotPasswordPostAction()
{
$email = (string) $this->getRequest()->getPost('email');
if ($email) {
if (!Zend_Validate::is($email, 'EmailAddress')) {
$this->_getSession()->setForgottenEmail($email);
$this->_getSession()->addError($this->__('Invalid email address.'));
$this->_redirect('*/*/forgotpassword');
return;
}
/** #var $customer Mage_Customer_Model_Customer */
$customer = $this->_getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
->loadByEmail($email);
if ($customer->getId()) {
try {
$newResetPasswordLinkToken = $this->_getHelper('customer')->generateResetPasswordLinkToken();
$customer->changeResetPasswordLinkToken($newResetPasswordLinkToken);
// Add store ID so that correct locale will be set
$customer->setStoreId(Mage::app()->getStore()->getId());
$customer->sendPasswordResetConfirmationEmail();
} catch (Exception $exception) {
$this->_getSession()->addError($exception->getMessage());
$this->_redirect('*/*/forgotpassword');
return;
}
}
$this->_getSession()
->addSuccess( $this->_getHelper('customer')
->__('If there is an account associated with %s you will receive an email with a link to reset your password.',
$this->_getHelper('customer')->escapeHtml($email)));
$this->_redirect('*/*/');
return;
} else {
$this->_getSession()->addError($this->__('Please enter your email.'));
$this->_redirect('*/*/forgotpassword');
return;
}
}
In the below file
Mage/Customer/Model/Customer.php
In sendPasswordResetConfirmationEmail function() change the
$storeId = $this->getStoreId();
to
$storeId = Mage::app()->getStore()->getStoreId();
Thanks
In our case... We found that when a Customer Account was created by Admin the "email send from" option was not saved and only used for the first account creation email. Any subsequent email sent are sent from the default store view of the website the customer was allocated.
The real problem is how, when the customer store id is identified when none is set.
The method sendPasswordResetConfirmationEmail (Magento 1.9.1) when the store id is 0 (admin or not set), defaults to _getWebsiteStoreId which will return the first store id associated to that website.
The problem is that Magento assumes the first store id associated with the website id is the default store... We found this is not the case when a Sort Order is set against the store record.
Simply put make sure your default store assocaited with a web site is also specified with a sort order of 0.
Hope this link will be usefull to you
In link they have used New Password but Instead of New Password Use Forgot Password template In step 4
Thanks..
The password reset email is send in Mage_Customer_Model_Customer::_sendEmailTemplate(). Here the emailtemplate is loaded. If it was loaded in admin in "Systemn > Transactional Emails" and configured to be used, your template will be used.
Else the default template is loaded from file in Mage_Core_Model_Email_Template::sendTransactional. This is done using $this->loadDefault($templateId, $localeCode); The template ist loaded using
$templateText = Mage::app()->getTranslator()->getTemplateFile(
$data['file'], 'email', $locale
);
Here locale folders are checked in following order:
Specified locale
Locale of default store
en_US locale
The first matched locale is chosen. As Mage::app() doesn't know about the store which was passed with the emailtemplate, the default defaultstore is loaded, which is german in your case. It has nothing to do with the order of the locale folders.
So in your case I suggest to check if your emailtemplate is selected in admin configuration in "System > Config > Customerconfiguration > Password Options" or use Mage::getStoreConfig(Mage_Customer_Model_Customer::XML_PATH_REMIND_EMAIL_TEMPLATE, $storeId) if it is set for your store.
The reason for why you are receiving the email templates in another language than the one expected is dependent of the language in which you first created your account. Try to check this to be in your own language when you first created the account.
Check this under Customers> Account Information to see how your account was created.
/Kalif

Magento - Set product attribute to use default values

This has been asked many times before but with no working answer.
I have multiple stores and some attributes have been overridden. I want to change these attributes to 'use default value' with a script.
Here is an image showing store views and 'use default value' checkboxes
http://dl.dropbox.com/u/3209649/storeviews-and-defaultvalues.png (not allowed to post images yet)
In app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php setData() is used with false for the second argument when 'Use Default Value' has been selected for any attributes.
/**
* Check "Use Default Value" checkboxes values
*/
if ($useDefaults = $this->getRequest()->getPost('use_default')) {
foreach ($useDefaults as $attributeCode) {
$product->setData($attributeCode, false);
}
}
The following code attempts to set the 'name' attribute to 'use default values' for product 1 in store 3 using the same method.
require_once '../app/Mage.php';
Mage::app(3);
$product = Mage::getModel('catalog/product')->load(1);
$product->setData('name', false); # as used in ProductController.php
$product->save();
Using
$product->setData('name', 'anything');
correctly sets the 'name' attribute to 'anything' but false does not set it to 'use default value'
'Use Default Value' is not stored anywhere in the database so within the controller for the admin interface there must be another procedure that deletes the attribute row?
Related Links here -> http://pastebin.com/raw.php?i=j7fwu9H6
(not allowed to post links yet either)
This doesn't work because you need the current store being the admin store for this kind of operation.
To make a specific store view use the default value for a given attribute:
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$product = Mage::getModel('catalog/product')
->load($product_id) // in your case: 1
->setStoreId($store_id) // in your case: 3
->setData($attr, false) // in your case: 'name'
->save();

Programmatically change product attribute at store view level

I'm sorry if this question is trivial but I've been struggling to find what I am doing wrong here. I am trying to change the value of an attribute on a store view level but the default is also changed whereas it shouldn't be. Of course, this attribute is set up to be "store-view-scoped". To keep it simple, I've tried with the product name. No success.
Below are unsuccessful tests I've tried...
Do you see what I am doing wrong here?
Many thanks.
My tries :
$product = Mage::getModel('catalog/product')->load(PRODUCT_ID);
$product->setStoreId(STORE_ID)->setName('new_name')->save();
$product = Mage::getModel('catalog/product')->load(PRODUCT_ID);
$product->setStoreId(STORE_ID)->setStore(STORE_CODE)->setName('new_name')->save();
$product = Mage::getModel('catalog/product')->load(PRODUCT_ID);
$product->setStoreId(STORE_CODE)->setName('new_name')->save();
$product = Mage::getModel('catalog/product')->setStoreId(STORE_ID)->load(PRODUCT_ID);
$product->setName('new_name')->save();
$product = Mage::getModel('catalog/product')->setStoreId(STORE_ID)->load(PRODUCT_ID);
$product->setStoreId(STORE_ID)->setName('new_name')->save();
I even tried by adding the line below before the product model load...
Mage::app()->setCurrentStore(STORE_ID);
So here is the complete snippet to change attribute value for a specific product attribute on a specific store view. Example with the product name :
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$product = Mage::getModel('catalog/product')->load(PRODUCT_ID);
$product->setStoreId(STORE_ID)->setName('my_new_product_name')->save();
And as an additional answer, one could be interested in changing the attribute value to the default one. In this case, the argument 'false' must be passed to the setAttribute :
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$product = Mage::getModel('catalog/product')->load(PRODUCT_ID);
$product->setStoreId(STORE_ID)->setName(false)->save();
You need to set the current store to admin at the top of your code block:
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
note when loading product with data for some store view, also default values get loaded. saving such product will save default values as store values (thus unset "Use Default Value" for fields)
i ended up with following function to clean-up product data from default values
public static function _removeDefaults($item) {
static $attributeCodes = null;
if($attributeCodes == null) {
$attributes = Mage::getSingleton('eav/config')
->getEntityType(Mage_Catalog_Model_Product::ENTITY)->getAttributeCollection();
$attributeCodes = array();
foreach($attributes as $attribute) {
$ac = $attribute->getAttributeCode();
if(in_array($ac, array('sku','has_options','required_options','created_at','updated_at','category_ids'))) {
continue;
}
$attributeCodes[] = $ac;
}
}
foreach($attributeCodes as $ac) {
if(false == $item->getExistsStoreValueFlag($ac)) {
$item->unsetData($ac);
}
}
}
remember to send only product loaded for some store view

Resources