Magento - pass a variable from Controller to checkout temaplte - magento

I've read the other posts about this subject and tried loads of things but cant get a Variable from my controller file to the Checkout. I have very little experience with creating modules so followed a guide to create the following
app ▸ code ▸ local ▸ Creare ▸ AgeRestricted ▸ etc ▸ config.xml
<?xml version="1.0"?>
<config>
<modules>
<Creare_AgeRestricted>
<version>0.1.0</version>
</Creare_AgeRestricted>
</modules>
<global>
<events>
<payment_method_is_active>
<observers>
<age_restricted>
<type>singleton</type>
<class>AgeRestricted/observer</class>
<method>AgeRestricted</method>
</age_restricted>
</observers>
</payment_method_is_active>
</events>
<models>
<AgeRestricted>
<class>Creare_AgeRestricted_Model</class>
<resourceModel>agerestricted_mysql4</resourceModel>
</AgeRestricted>
</models>
<sales>
<quote>
<item>
<product_attributes>
<age_restricted/>
</product_attributes>
</item>
</quote>
</sales>
</global>
</config>
Macintosh HD ▸ WWW-local ▸ dexam ▸ htdocs_live ▸ app ▸ code ▸ local ▸ Creare ▸ AgeRestricted ▸ Model ▸ Observer.php
<?php
class Creare_AgeRestricted_Model_Observer
{
public function AgeRestricted(Varien_Event_Observer $observer)
{
Mage::register('feedback', $AgeRestricted);
$event = $observer->getEvent();
$method = $event->getMethodInstance();
$result = $event->getResult();
$AgeRestricted = false;
foreach (Mage::getSingleton('checkout/cart')->getQuote()->getAllVisibleItems() as $item)
{
if($item->getProduct()->getAgeRestricted()){
$AgeRestricted = true;
}
}
}
}
Notice I added the line:
Mage::register('feedback', $AgeRestricted);
then im trying to call this with:
echo Mage::registry('feedback');
in file:
app/design/frontend/dexam/default/template/checkout/onepage/payment.phtml
but it displays nothing at all. I've tested the location in payment.phtml is working.. my test text appears but 'feedback' is not calling the $AgeRestricted.
I tried echo $AgeRestricted; in my controller, which echo'd lots of '1's at the top of my screen so I can see the variable contains the true value.
How can I call $AgeRestricted in payment.phtml?
Many thanks!!
Daz

<?php
class Creare_AgeRestricted_Model_Observer
{
public function AgeRestricted(Varien_Event_Observer $observer)
{
$event = $observer->getEvent();
$method = $event->getMethodInstance();
$result = $event->getResult();
$AgeRestricted = false;
foreach (Mage::getSingleton('checkout/cart')->getQuote()->getAllVisibleItems() as $item)
{
if($item->getProduct()->getAgeRestricted()){
$AgeRestricted = true;
}
}
if(!Mage::register('feedback')){
Mage::register('feedback', $AgeRestricted); // put this line here after all processing
}
}
}
Hope this will help you out

You can use magento checkout sessions to set the value from the observer to payment file
<?php
class Creare_AgeRestricted_Model_Observer
{
public function AgeRestricted(Varien_Event_Observer $observer)
{
$event = $observer->getEvent();
$method = $event->getMethodInstance();
$result = $event->getResult();
$AgeRestricted = false;
foreach (Mage::getSingleton('checkout/cart')->getQuote()->getAllVisibleItems() as $item)
{
if($item->getProduct()->getAgeRestricted()){
$AgeRestricted = true;
}
}
if($AgeRestricted){
Mage::getSingleton('checkout/session')->setRestictedAge($AgeRestricted);
}
}
}
In your payment.phtml
<?php $session = Mage::getSingleton('checkout/session');?>
<?php echo $session->getRestrictedAge();?>

Related

How to prevent an order from being cancelled using event observer?

I am using the following code to prevent the order from being cancelled from the Magento admin panel.
<?xml version="1.0"?>
<config>
<modules>
<Muk_OrderCancel>
<version>1.0.0</version>
</Muk_OrderCancel>
</modules>
<global>
<models>
<ordercancel>
<class>Muk_OrderCancel_Model</class>
</ordercancel>
</models>
<events>
<sales_order_save_before>
<observers>
<ordercancel>
<type>singleton</type>
<class>Muk_OrderCancel_Model_Observer</class>
<method>canCancelOrder</method>
</ordercancel>
</observers>
</sales_order_save_before>
</events>
<helpers>
<ordercancel>
<class>Muk_OrderCancel_Model_Helper</class>
</ordercancel>
</helpers>
</global>
</config>
In the observer I am using the following code:
<?php
class Muk_OrderCancel_Model_Observer
{
public function canCancelOrder( Varien_Event_Observer $observer )
{
$incrementId = $observer->getEvent()->getOrder()->getData('increment_id');
$order = Mage::getModel('sales/order')->loadByIncrementId($incrementId);
$adminUserSession = Mage::getSingleton('admin/session');
$adminUserId = $adminUserSession->getUser()->getUserId();
$adminUserName = $adminUserSession->getUser()->getUsername();
$adminRoleName = Mage::getModel('admin/user')->load($adminUserId)
->getRole()->getData('role_name');
if($adminRoleName) { //some condition
$order->setActionFlag(Mage_Sales_Model_Order::ACTION_FLAG_CANCEL, false);
}
}
}
But even after enabling this module, the order is getting cancelled.
How can I prevent the order from being cancelled?
In the "Mage_Adminhtml_Sales_OrderController" "cancelAction" it goes:
$order->cancel()
->save();
which means the order is first cancelled then your observer fires. Although I found this event:
Mage::dispatchEvent('sales_order_payment_cancel', array('payment' => $this));
in "Mage_Sales_Model_Order_Payment" which fires before: "Mage_Sales_Model_Order" : "registerCancellation" method.
In your observer method which fires on this event you can do this:
if ($adminRoleName) {
$payment = $observer->getEvent()->getPayment();
$order = $payment->getOrder();
$order->setActionFlag(Mage_Sales_Model_Order::ACTION_FLAG_CANCEL, false);
//Get the existing non cancelled orders if they exist, if not create the array and add it to the admin session.
$orderIds = Mage::getSingleton('adminhtml/session')->getNonCancelledOrders();
if (!$orderIds) {
$orderIds = array($order->getId());
} else {
$orderIds[] = $order->getId();
}
Mage::getSingleton('adminhtml/session')->setNonCancelledOrders($orderIds);
}
Next, add one more observer in your etc/config.xml file on the following event: "controller_action_predispatch":
<controller_action_predispatch>
<observers>
<check_session_message>
<type>singleton</type>
<class>Muk_OrderCancel_Model_Observer</class>
<method>checkSessionMessage</method>
</check_session_message>
</observers>
</controller_action_predispatch>
Then in your observer method:
public function checkSessionMessage($observer)
{
//Check if we have admin order view or grid action
$request = Mage::app()->getRequest();
$module = $request->getModuleName();
$controller = $request->getControllerName();
$action = $request->getActionName();
if ($module == 'admin' && $controller == 'sales_order') {
if ($action == 'view' || $action == 'index') {
//Check if we have orderIds
$orderIds = Mage::getSingleton('adminhtml/session')->getNonCancelledOrders();
if ($orderIds && count($orderIds) > 0) {
//Unset them from the session
Mage::getSingleton('adminhtml/session')->unsNonCancelledOrders();
//Clear success message
Mage::getSingleton('adminhtml/session')->getMessages(true);
//Add error message
Mage::getSingleton('adminhtml/session')->addError('You are not allowed to cancel the order(s)');
}
}
}
}

Show cash on delivery methods for some specific cities

HOW to display/hide "Cash on delivery" payment method for some specific cities.
I have tired this link also but not working
This is my observer.php located in app/code/local/MagePsycho/Paymentfilter/Model
class MagePsycho_Paymentfilter_Model_Observer {
public function paymentMethodIsActive(Varien_Event_Observer $observer) {
$event = $observer->getEvent();
$method = $event->getMethodInstance();
$result = $event->getResult();
$currencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
$checkout = Mage::getSingleton('checkout/session')->getQuote();
$shipping = $checkout->getShippingAddress();
$cashOnDeliveryCities = array('test1','test3');
if(in_array($shipping->getCity(), $cashOnDeliveryCities)){
$result->isAvailable = true;
}else{
$result->isAvailable = false;
}
}
}
This is my config.php located in app/code/local/MagePsycho/Paymentfilter/etc
<frontend>
<events>
<payment_method_is_active>
<observers>
<paymentfilter_payment_method_is_active>
<type>singleton</type>
<class>paymentfilter/observer</class>
<method>paymentMethodIsActive</method>
</paymentfilter_payment_method_is_active>
</observers>
</payment_method_is_active>
</events>
</frontend>
Where i am missing, It showing cash on delivery for all cities not filtering
Thanks
It works for me.
Firstly check, that your observer method is executing. Put something like exit() or die();
As you have already said you'd like to add city restriction only for cash_on_delivery - add following code after $currencyCode = ...
if(!($method instanceof Mage_Payment_Model_Method_Cashondelivery))
{
return;
}
Try to debug Mage_Payment_Model_Method_Abstract::isAvailable. Put some Mage::log in this method and determine at which moment which walue have $checkResult->isAvailable

Magento payment method according to product options

I need to perform the next action when a customer is making the purchase of products:
If there is a product with custom options to display only a method of payment and if no other method.
how to do this ... I'm going crazy
thanks
You can do this event observer
create an extension under app/code/local
Bh_ZeroSubtotalpaymentmethod_Model
File of extension are config.xml under
app/code/local/Bh/ZeroSubtotalpaymentmethod/etc
and it code is
<?xml version="1.0" ?>
<config>
<modules>
<Bh_ZeroSubtotalpaymentmethod>
<version>1.0.1</version>
</Bh_ZeroSubtotalpaymentmethod>
</modules>
<global>
<models>
<zerosubtotalpaymentmethod>
<class>Bh_ZeroSubtotalpaymentmethod_Model</class>
</zerosubtotalpaymentmethod>
</models>
</global>
<frontend>
<events>
<payment_method_is_active>
<observers>
<paymentfilter_payment_method_is_active>
<type>singleton</type>
<class>zerosubtotalpaymentmethod/observer</class>
<method>filterpaymentmethod</method>
</paymentfilter_payment_method_is_active>
</observers>
</payment_method_is_active>
</events>
</frontend>
</config>
and Observer file code
is
<?php
class Bh_ZeroSubtotalpaymentmethod_Model_Observer {
public function filterpaymentmethod(Varien_Event_Observer $observer) {
/* call get payment method */
$method = $observer->getEvent()->getMethodInstance();
if($method->getCode()=='paypal_standard')
{ $quote = $observer->getEvent()->getQuote();
if($this->checkcustomoption()==true){
$result = $observer->getEvent()->getResult();
$result->isAvailable = false;
}
return;
}
if($method->getCode()=='free'){
$quote = $observer->getEvent()->getQuote();
if($this->checkcustomoption()==false){
$result = $observer->getEvent()->getResult();
$result->isAvailable = false;
return;
}
}
return;
}
public function checkcustomoption(){
//To get your cart object (in session) :
$quote = Mage::getSingleton('checkout/session')->getQuote();
//Then, to get the list of items in the cart :
$cartItems = $quote->getAllVisibleItems();
//Then, to get the count for each item :
foreach ($cartItems as $item)
{ // check $item->getProduct() give cart item
$item->getProduct();
if(your_logic_match){
return true;
break;
}
}
retrun false;
}
}
?>
for check and custom option used https://magento.stackexchange.com/questions/17867/get-custom-option-price-in-order blog Gavin answer

Change product price on all pages by using observer Magento

I am learning Magento and I have start learning events and observers. A percentage of amount is added to product by setting in admin product area.
It works fine but the discounted price shows only on product page. Can anybody suggest me how can I change the price through out Magento. I mean change price should go to cart, order etc.
Below is the code for observer
<?php
class Xyz_Catalog_Model_Price_Observer
{
public function __construct()
{
}
/**
* Applies the special price percentage discount
* #param Varien_Event_Observer $observer
* #return Xyz_Catalog_Model_Price_Observer
*/
public function apply_discount_percent($observer)
{
$event = $observer->getEvent();
$product = $event->getProduct();
// process percentage discounts only for simple products
if ($product->getSuperProduct() && $product->getSuperProduct()->isConfigurable()) {
} else {
$percentDiscount = $product->getPercentDiscount();
if (is_numeric($percentDiscount)) {
$today = floor(time()/86400)*86400;
$from = floor(strtotime($product->getSpecialFromDate())/86400)*86400;
$to = floor(strtotime($product->getSpecialToDate())/86400)*86400;
if ($product->getSpecialFromDate() && $today < $from) {
} elseif ($product->getSpecialToDate() && $today > $to) {
} else {
$price = $product->getPrice();
$finalPriceNow = $product->getData('final_price');
$specialPrice = $price - $price * $percentDiscount / 100;
// if special price is negative - negate the discount - this may be a mistake in data
if ($specialPrice < 0)
$specialPrice = $finalPriceNow;
if ($specialPrice < $finalPriceNow)
$product->setFinalPrice($specialPrice); // set the product final price
}
}
}
return $this;
}
}
config.xml
<?xml version="1.0"?>
<config>
<global>
<models>
<xyzcatalog>
<class>Xyz_Catalog_Model</class>
</xyzcatalog>
</models>
<events>
<catalog_product_get_final_price>
<observers>
<xyz_catalog_price_observer>
<type>singleton</type>
<class>Xyz_Catalog_Model_Price_Observer</class>
<method>apply_discount_percent</method>
</xyz_catalog_price_observer>
</observers>
</catalog_product_get_final_price>
</events>
</global>
</config>
Please advise how I can use the new discounted price throughout Magento. Thanks
Here is solution
config.xml
<?xml version="1.0"?>
<config>
<modules>
<Seta_DiscountPrice>
<version>0.1.0</version> <!-- Version number of your module -->
</Seta_DiscountPrice>
</modules>
<global>
<models>
<setadiscountprice>
<class>Seta_DiscountPrice_Model</class>
</setadiscountprice>
</models>
<events>
<catalog_product_get_final_price>
<observers>
<seta_discountprice_price_observer>
<type>singleton</type>
<class>Seta_DiscountPrice_Model_Price_Observer</class>
<method>apply_10</method>
</seta_discountprice_price_observer>
</observers>
</catalog_product_get_final_price>
<catalog_product_collection_load_after>
<observers>
<seta_discountprice_price_observer>
<type>singleton</type>
<class>Seta_DiscountPrice_Model_Price_Observer</class>
<method>apply_view</method>
</seta_discountprice_price_observer>
</observers>
</catalog_product_collection_load_after>
</events>
</global>
</config>
Observer.php
<?php
class Seta_DiscountPrice_Model_Price_Observer
{
public function __construct()
{
}
/**
* Applies the special price percentage discount
* #param Varien_Event_Observer $observer
* #return Seta_DiscountPrice_Model_Price_Observer
*/
public function apply_10($observer)
{
$event = $observer->getEvent();
$product = $event->getProduct();
// process percentage discounts only for simple products
if ($product->getSuperProduct() && $product->getSuperProduct()->isConfigurable()) {
} else {
$product->setFinalPrice(10);
}
return $this;
}
public function apply_view($observer)
{
$event = $observer->getEvent();
$myCustomPrice = 10;
$products = $observer->getCollection();
foreach( $products as $product )
{
$product->setPrice( $myCustomPrice );
$product->setFinalPrice( $myCustomPrice );
}
return $this;
}
}
Why not using 'catalog price rules' or 'special price' function of products? These are inbuilt functions to do this kind of stuff.
For add to cart price change, you need another event to observe. Crash course:
You have to build an observer that catches the add-to-cart event sales_quote_add_item and then you can do the php-stuff in the observer like you did on the product page to change the price for the product added to card with:
$observer->getEvent()->getQuoteItem()->setOriginalCustomPrice([your price])
Exactly for this task it's better to use Catalog Price Rules from Promotions menu.
But as I understand you are making this with learning purposes. So when you are not sure for an event you could just log the dispatched events. In app/Mage.php you have a method called dispatchEvent. Then you could just log every dispatched event:
public static function dispatchEvent($name, array $data = array())
{
if(strpos($name, 'product') || strpos($name, 'price')) { // optional
Mage::log($name, null, 'events.log', true);
}
Varien_Profiler::start('DISPATCH EVENT:'.$name);
$result = self::app()->dispatchEvent($name, $data);
Varien_Profiler::stop('DISPATCH EVENT:'.$name);
return $result;
}
Your log file will be created in var/log folder. Of course don't forget to revert Mage.php to it's original version when you're done. It's not a good idea to change core files.

Trying get dynamic content hole-punched through Magento's Full Page Cache

I am using Magento Enterprise 1.10.1.1 and need to get some dynamic content on our product pages. I am inserting the current time in a block to quickly see if it is working, but can't seem to get through full page cache.
I have tried a variety of implementations found here:
http://tweetorials.tumblr.com/post/10160075026/ee-full-page-cache-hole-punching
http://oggettoweb.com/blog/customizations-compatible-magento-full-page-cache/
http://magentophp.blogspot.com/2011/02/magento-enterprise-full-page-caching.html
Any solutions, thoughts, comments, advice is welcome.
here is my code:
app/code/local/Fido/Example/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Fido_Example>
<version>0.1.0</version>
</Fido_Example>
</modules>
<global>
<blocks>
<fido_example>
<class>Fido_Example_Block</class>
</fido_example>
</blocks>
</global>
</config>
app/code/local/Fido/Example/etc/cache.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<placeholders>
<fido_example>
<block>fido_example/view</block>
<name>example</name>
<placeholder>CACHE_TEST</placeholder>
<container>Fido_Example_Model_Container_Cachetest</container>
<cache_lifetime>86400</cache_lifetime>
</fido_example>
</placeholders>
</config>
app/code/local/Fido/Example/Block/View.php
<?php
class Fido_Example_Block_View extends Mage_Core_Block_Template
{
private $message;
private $att;
protected function createMessage($msg) {
$this->message = $msg;
}
public function receiveMessage() {
if($this->message != '') {
return $this->message;
}
else {
$this->createMessage('Hello World');
return $this->message;
}
}
protected function _toHtml() {
$html = parent::_toHtml();
if($this->att = $this->getMyCustom() && $this->getMyCustom() != '') {
$html .= '<br />'.$this->att;
}
else {
$now = date('m-d-Y h:i:s A');
$html .= $now;
$html .= '<br />' ;
}
return $html;
}
}
app/code/local/Fido/Example/Model/Container/Cachetest.php
<?php
class Fido_Example_Model_Container_Cachetest extends Enterprise_PageCache_Model_Container_Abstract {
protected function _getCacheId()
{
return 'HOMEPAGE_PRODUCTS' . md5($this->_placeholder->getAttribute('cache_id') . $this->_getIdentifier());
}
protected function _renderBlock()
{
$blockClass = $this->_placeholder->getAttribute('block');
$template = $this->_placeholder->getAttribute('template');
$block = new $blockClass;
$block->setTemplate($template);
return $block->toHtml();
}
protected function _saveCache($data, $id, $tags = array(), $lifetime = null) { return false; }
}
app/design/frontend/enterprise/[mytheme]/template/example/view.phtml
<?php echo $this->receiveMessage() ?>
snippet from app/design/frontend/enterprise/[mytheme]/layout/catalog.xml
<reference name="content">
<block type="catalog/product_view" name="product.info" template="catalog/product/view.phtml">
<block type="fido_example/view" name="product.info.example" as="example" template="example/view.phtml" />
The <name> in the cache.xml must match your blocks full name in the layout, not the alias, e.g. <name>product.info.example</name>
Also, _getIdentifier() isn't implemented on Enterprise_PageCache_Model_Container_Abstract, just remove it from the string returned by your _getCacheId().
If you need to add some variants, implement _getIdentifier() to return a session id or whatever you need.

Resources