Can't able to set the product attribute programmatically in magento through observer - magento

I want to update the products description attribute after the product save.so for this i am using the observer called catalog_product_save_after and depending on some condition i create the description for the product and i will save the description of the products by following code
product->setDescription();
product->save();
the problem is when i am calling the product->save(); the site is loading and loading later i found that product->save(); this function is again calling the catalog_product_save_after. that's why it is going into the infinite loop.
Please help me to set the description for the product.

Option 1:
You can use catalog_product_save_before and just use $product->setDescription('something') (without the save).
Option 2
Make your observer run only once.
function doSomething($observer) {
//some code here
$id = $product->getId();
if (!Mage::registry('observer_already_executed_'.$id)) {
//do your magic here
Mage::register('observer_already_executed_'.$id, 1);
}
}

Related

Magento: Navigation static page directly to specific product

I would like to add a static link at the navigation bar that can link directly to a specific product.
As I only have one product listing under category "pillow", I wish to set it to go into the product directly, skipping the catalog view.
I am aware of two methods, being URL rewrite management and static block, however I experience problem with both.
For "URL rewrite", it worked but once I update something at the category (e.g. moving the position), the system generate a new "URL rewrite" and delete the my custom one.
For "static block", I do not know what code to put in it. My guess was to add below code, but it doesn't work.
{{block type="catalog/product_view" product_id="896" template="catalog/category/view.phtml"}}
How do I get it done? Thanks in advance.
I have taken a different approach to the problem which may be helpful. It seems like your end goal is to skip the category view if a category only contains one product. So rather than fussing with hard coding templates or trying to clobber the category with URL rewrite, you can accomplish this using an event observer.
The approach will listen for the <catalog_controller_category_init_after> event to fire and check whether the category only has one product. If so it will send the request directly to the product. You will need to add a new extension or modify an existing one.
etc/config.xml
Create a new node under config/frontend/events:
<catalog_controller_category_init_after>
<observers>
<redirectSingleProduct>
<class>My_MyExtension_Model_Observer</class>
<method>redirectSingleProduct</method>
</redirectSingleProduct>
</observers>
</catalog_controller_category_init_after>
Model/Observer.php
Create the corresponding method to handle the event:
class My_MyExtension_Model_Observer
{
/**
* Check whether a category view only contains one product, if so send the request directly to it.
* #param Varien_Event_Observer $observer
* #return $this
*/
public function redirectSingleProduct(Varien_Event_Observer $observer)
{
$category = $observer->getCategory();
if ($category->getProductCount() == 1) {
$product = $category->getProductCollection()->addUrlRewrite()->getFirstItem();
$url = $product->getProductUrl();
$observer->getControllerAction()->getResponse()->setRedirect($url);
}
return $this;
}
}

Magento - catalog_product_save_after: Check if product has been saved

I am currently trying to save a product with attributes that I have built, and it's working fine. I have also set up my code to call the catalog_product_save_after function on my observer, as shown below:
class Package_MyModule_Model_Observer
{
public function catalog_product_save_after($observer)
{
$product = $observer->getProduct();
//Do stuff here
}
}
In this line of code here, is there a way to detect whether the product has already been saved (i.e. no error messages were shown)? Because I need to update some values in the database when the product is saved successfully.
Mostly this gets called after product is saved successfully, but to be sure you can hook into
catalog_product_save_commit_after

magento target rule not applying to a specific product

A simple product is in specific category other products have that rule applied.This is happening on magento enterprise 1.13.0.1 version.
A rule is applicable to that category but when I look in catalogrule_product table then there is no entry for that product. This means no rule applies to that product.
http://www.solvingmagento.com/quick-tip-magento-catalog-price-rules-dont-work/ is the link I refered.
I want to know if for some reason a product has no target rules applied then:
1. Is there no cron job that will handle this and populate catalogrule_product table.
If yes then which cron job does this.
Also when we saved product its expected that catalog_product_save_after event should get fired resulting in Mage_CatalogRule module’s observer method applyAllRulesOnProduct getting executed but still no luck.
When I click via admin apply rule then it works.
I want to know is has magento not provided any cron job/indexer to handle this.
Thanks in Advance.
If you are creating products outside of the magento backend (using php, or soap) you may have to use the following code after you have called the $product->save() method...
public function applyActiveRulesToProduct($productId)
{
try {
$product = Mage::getModel('catalog/product') -> load($productId);
$rules = Mage::getModel('catalogrule/rule')->getCollection()->addFieldToFilter('is_active', 1);
foreach ($rules as $rule) {
$rule->applyAllRulesToProduct($product);
}
return "Applied rules to " . $productId;
} catch (Exception $e) {
return $e->getMessage();
}
}
It is code that i wrote for my own soap api extension. I could not get the rules to apply using applyToProduct(product, websiteIds) but using applyAllRulesToProduct with filters on the rules array seems to do the trick.
FYI, this code is buried inside of the CatalogRule.Rule.php core code as well, but it cannot be called directly using the rule model or product model. Who knows why they did that.

Add checkbox to Magento checkout?

I've been searching, trying, and failing alot here. What I want is to add a checkbox, on the Shipping page of Onepage checkout, the standard magento checkout.
I want to create a checkbox so that customers can check it if they want their products to be placed on their address without a signature.
I've been messing around with some old "Accept Terms" checkboxes, but with no luck.
I'm hoping that somebody might have had to make the same kind of customization.
What you can do is save the preference in the checkout/session via an observer. First, add the checkbox to the shipping section and give it the property of name=shipping[no_signature]. Then, create a new module and hook into the event controller_action_postdispatch_checkout_onepage_saveShipping and then use this code:
public function controller_action_postdispatch_checkout_onepage_saveShipping($observer)
{
$params = (Mage::app()->getRequest()->getParams()) ? Mage::app()->getRequest()->getParams() : array();
if (isset($params['shipping']['no_signature']) && $params['shipping']['no_signature']) {
Mage::getSingleton('checkout/session')->setNoSignature(true);
} else {
Mage::getSingleton('checkout/session')->setNoSignature(false);
}
return $this;
}
Then, when the order is about to be placed, hook into the event sales_order_place_before you can add a comment to the order like this:
public function sales_order_place_before($observer)
{
$order = $observer->getOrder();
if (Mage::getSingleton('checkout/session')->getNoSignature()) {
$order->setCustomerNote('No signature required.');
} else {
$order->setCustomerNote(null);
}
return $this;
}
When you go to Sales > Orders, you should see a comment on the order regarding if the customer requires a signature or not. This is under the assumption that no other module or custom code is injecting anything into the customer_note field on the order object.

Help with Magento and related products

I have a customer product page that literally lives beside the catalog/product/view.phtml page. It's basically identical to that page with a few small exceptions. It's basically a 'product of the day' type page so I can't combine it with the regular product page since I have to fetch the data from the DB and perform a load to get the product information
$_product = Mage::getModel('catalog/product')->load($row['productid']);
To make a long story short, everything works (including all children html blocks) with the singular exception of the related products.
After the load I save the product into the registry with
Mage::register('product', $_product);
and then attempt to load the related products with:
echo $this->getLayout()->createBlock('catalog/product_view')->setTemplate('catalog/product/list/related.phtml')->toHtml();`
All of which give back the error:
Fatal error: Call to a member function getSize() on a non-object in catalog/product/list/related.phtml on line 29`,
and line 29 is
<?php if($this->getItems()->getSize()): ?>`.
Any help getting the relateds to load would be appreicated.
I didn't quite follow what you're trying to do, but I know why you're getting your errors. You're creating a block whose class-alias/class is
catalog/product_view
Mage_Catalog_Block_Product_View
but you're setting this block's template as
catalog/product/list/related.phtml
The stock catalog/product/list/related.phtml template was built to be used with a catalog/product_list_related Block only, and not a catalog/product_view Block.
If you take a look at the class definition for a catalog/product_list_related Block (which is a Mage_Catalog_Block_Product_List_Related), you can see that there's a getItems() method.
public function getItems()
{
return $this->_itemCollection;
}
which returns a collection. The collection is set in the _prepareData method
protected function _prepareData()
{
$product = Mage::registry('product');
/* #var $product Mage_Catalog_Model_Product */
$this->_itemCollection = $product->getRelatedProductCollection()
...
This collection is never set with a catalog/product_view Block, which is why you're getting your errors.
In your code above, if you switch to creating a catalog/product_list_related block, your errors should go away.
public function relatedproductsAction(){
$this->loadLayout();
$relatedBlock = "";
$rec_prod_id = Mage::getSingleton('checkout/session')->getLastAddedProductId(true);
$_product = Mage::getModel('catalog/product')->load($rec_prod_id);
Mage::register('product', $_product);
$relatedBlock = $this->getLayout()->createBlock('catalog/product_list_related')->setTemplate('catalog/product/related.phtml')->toHtml();
echo $relatedBlock;
exit;
}
Getting html of related block through ajax call, right after when product is added to cart. might be relatively helpful.

Resources