I have been pulling my hair out over trying to get a hole punched out for the price block on the product page. I have looked at numerous sources, including some from you good people at stackoverflow, but I have been getting a fatal error, so something is incorrect. Here are some sources that I used:
http://invisiblezero.net/magento-ee-punch-hole-in-full-page-cache/
http://www.kingletas.com/2012/09/how-does-magento-full-page-cache-works.html
Magento full page cache
Trying get dynamic content hole-punched through Magento's Full Page Cache
How to implement magento cache hole punching for shopping cart block
As you can see, I have been all over, and I have read more in addition to this but some of them conflict a litt, and I think that is where I have my issue, now let me post some code for you.
cache.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<placeholders>
<SpecialPrice>
<block>catalog/product_price</block>
<name>product.pricing</name>
<placeholder>CATALOG_PRODUCT_PRICE</placeholder>
<container>MyStore_SpecialPrice_Model_Container_Cache</container>
<cache_lifetime>8640</cache_lifetime>
</SpecialPrice>
</placeholders>
</config>
cache.php
<?php
class MyStore_SpecialPrice_Model_Container_Cache extends Enterprise_PageCache_Model_Container_Abstract
{
/**
* Get customer identifier from cookies
*
* #return string
*/
protected function _getIdentifier()
{
return $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER, '');
}
/**
* Get cache identifier
*
* #return string
*/
protected function _getCacheId()
{
return 'CATALOG_PRODUCT_PRICE' . md5($this->_placeholder->getAttribute('cache_id') . $this->_getIdentifier());
}
/**
* Render block content
*
* #return string
*/
protected function _renderBlock()
{
$blockClass = $this->_placeholder->getAttribute('block');
$template = $this->_placeholder->getAttribute('template');
$block = new $blockClass;
$block->setTemplate($template);
return $block->toHtml();
}
}
congig.xml
<?xml version="1.0"?>
<config>
<modules>
<MyStore_SpecialPrice>
<version>0.1.0</version>
</MyStore_SpecialPrice>
</modules>
<frontend>
<events>
<catalog_product_get_final_price>
<observers>
<MyStore_SpecialPrice_Model_Observer>
<class>MyStore_SpecialPrice_Model_Observer</class>
<method>setSpecialPrice</method>
</MyStore_SpecialPrice_Model_Observer>
</observers>
</catalog_product_get_final_price>
</events>
</frontend>
<admin>
<routers>
<SpecialPrice>
<use>admin</use>
<args>
<module>MyStore_SpecialPrice</module>
<frontName>SpecialPrice</frontName>
</args>
</SpecialPrice>
</routers>
</admin>
<global>
<models>
<SpecialPrice>
<class>MyStore_SpecialPrice_Model</class>
</SpecialPrice>
</models>
</global>
</config>
snippet from local.xml
<reference name="right">
<block type="catalog/product_price" name="product.pricing" template="catalog/product/product-price-block.phtml" before="-" >
Let me know if there is anything that jumps out to you.
Related
I'm having trouble getting a new module to work. To begin with I just want to add an additional tab to the Product Edit screen in the adminhtml. I want this tab to show underneath the standard "Custom Options" tab. I have my module showing up in the Configuration > Advanced > Advanced > Disable Module output section.
So here's what I have, seen any mistakes?
Path : app\etc\modules\ns>_CustomerHistory.xml
<?xml version="1.0"?>
<config>
<modules>
<<ns>_CustomerHistory>
<active>true</active>
<codePool>local</codePool>
</<ns>_CustomerHistory>
</modules>
</config>
Path: app\code\local\\CustomerHistory\etc\config.xml
<?xml version="1.0"?>
<config>
<modules>
<<ns>_CustomerHistory>
<version>0.1.0</version>
</<ns>_CustomerHistory>
</modules>
<global>
<blocks>
<CustomerHistory>
<class><ns>_CustomerHistory_Block</class>
</CustomerHistory>
</blocks>
<models>
<CustomerHistory>
<class><ns>_CustomerHistory_Model</class>
</CustomerHistory>
</models>
</global>
<adminhtml>
<layout>
<updates>
<CustomerHistory>
<file>CustomerHistory.xml</file>
</CustomerHistory>
</updates>
</layout>
</adminhtml>
</config>
Path : app\code\local\ns>\CustomerHistory\Block\Adminhtml\Product\Edit\Tab.php
<?php
class <ns>_CustomerHistory_Block_Adminhtml_Catalog_Product_Edit_Tab extends Mage_Adminhtml_Block_Widget
implements Mage_Adminhtml_Block_Widget_Tab_Interface
{
public function canShowTab()
{
return true;
}
public function getTabLabel()
{
return $this->_('Custom Tab');
}
public function getTabTitle()
{
return $this->_('Custom Tab');
}
public function isHidden()
{
return false;
}
public function getTabUrl()
{
return $this->getUrl('*/*/customtab', array('_current' => true));
}
public function getTabClass()
{
return 'ajax';
}
}
?>
Path : app\design\adminhtml\default\default\layout\CustomerHistory.xml
<?xml version="1.0"?>
<layout>
<adminhtml_catalog_product_edit>
<reference name="product_tabs">
<block type="CustomerHistory/adminhtml_catalog_product_edit_tab" name="custom_tab" template="CustomerHistory/catalog/product/edit/tab.phtml" />
<action method="addTab">
<name>Custom Tab</name>
<block>custom_tab</block>
</action>
</reference>
</adminhtml_catalog_product_edit>
</layout>
Path : app\design\adminhtml\default\default\template\CustomerHistory\catalog\product\edit\tab.phtml
<?php
/**
* Custom tab template
*/
?>
<div>
<h1>Hello</h1>
</div>
It goes without saying here, any help would be greatly appreciated!
I have a parts configurator that I only want to have appear for a certain product SKU. In my catalog/product/view.html file I have included the following code:
<?php
if ($_product->getSku() == '10007-') {
echo $this->getLayout()->createBlock('cms/block')->setBlockId('partfinder_selector')->toHtml();
}
?>
Then, in the xml file for the configurator:
<catalog_product_view>
<reference name="content">
<block type="partfinder/selector" name="partfinder_selector" before="-" template="partfinder/selector.phtml"/>
</reference>
The issue is, with this setup, the configurator appears on all product pages. Do I have something wrong in my code, or is there a better method for what I am trying to accomplish. Any help would be appreciated.
Note, this solution doesn't require any 'configurator xml', so you can leave that out. You'll be able to use an if statement like in your example to select only the sku you want.
Create directories:
app/code/local/Partfinder/Selector/Block
app/code/local/Partfinder/Selector/etc
For your app/etc/modules as Partfinder_Selector.xml:
<config>
<modules>
<Partfinder_Selector>
<active>true</active>
<codePool>local</codePool>
</Partfinder_Selector>
</modules>
</config>
In your app/code/local/Partfinder/Selector/etc as config.xml:
<?xml version="1.0"?>
<config>
<modules>
<Partfinder_Selector>
<version>0.1.0</version>
</Partfinder_Selector>
</modules>
<global>
<blocks>
<partfinderselector>
<class>Partfinder_Selector_Block</class>
</partfinderselector>
</blocks>
</global>
</config>
In your app/code/local/Partfinder/Selector/Block as Menu.php:
<?php
class Partfinder_Selector_Block_Menu extends Mage_Core_Block_Template
{
}
?>
In your app/design/pkgname/themename/template/Partfinder save a file called selector.phtml containing your block code.
In catalog/product/view.phtml:
<?php if ($_product->getSku() == "10007-"): ?>
<?php echo $this->getLayout()->createBlock('partfinderselector/menu')->setTemplate('partfinder/selector.phtml')->toHtml(); ?>
<?php endif; ?>
First, when you use echo $this->getLayout()->createBlock('cms/block')--setBlockId('partfinder_selector')->toHtml()
Magento tries to output the static block with the id partfinder_selector.
Second, <reference name="content"> refers to the content block which is a "core/text_list" which automatically outputs its children, so your block will be automatically output by the content block.
The solution would be, in your xml file use
<reference name="product.info"> instead of "content"
and use $this->getChildHtml('partfinder_selector') in catalog/product/view.html
You are require to follow below steps to do this:
1) - In the /Namespace/Module/etc/config.xml you have to write the following thing:
<config>
<modules>
<Namespace_Module>
<version>0.1.0</version>
</Namespace_Module>
</modules>
<global>
<helpers>
<module>
<class>>Namespace_Module_Helper</class>
</module>
<catalog>
<rewrite>
<product_view>Namespace_Module_Helper_View</product_view>
</rewrite>
</catalog>
</helpers>
</global>
</config>
2) - Register module in magento module list under app/etc/modules/Namespace_Module.xml
<config>
<modules>
<Namespace_Module>
<active>true</active>
<codePool>local</codePool>
<depends />
</Namespace_Module>
</modules>
</config>
3) - You have to create your file under /Namespace/Module/Helper/view.php.
Please find below code
class KNamespace_Module _Helper_View extends Mage_Catalog_Helper_Product_View
{
public function initProductLayout($product, $controller)
{
$design = Mage::getSingleton('catalog/design');
$settings = $design->getDesignSettings($product);
if ($settings->getCustomDesign()) {
$design->applyCustomDesign($settings->getCustomDesign());
}
$update = $controller->getLayout()->getUpdate();
$update->addHandle('default');
$controller->addActionLayoutHandles();
$update->addHandle('PRODUCT_TYPE_' . $product->getTypeId());
$update->addHandle('PRODUCT_' . $product->getId());
//update code
if(preg_match('/10007-/',$product->getSku())){$update->addHandle('PRODUCT_NEWLAYOUT');}
$controller->loadLayoutUpdates();
// Apply custom layout update once layout is loaded
$layoutUpdates = $settings->getLayoutUpdates();
if ($layoutUpdates) {
if (is_array($layoutUpdates)) {
foreach($layoutUpdates as $layoutUpdate) {
$update->addUpdate($layoutUpdate);
}
}
}
$controller->generateLayoutXml()->generateLayoutBlocks();
// Apply custom layout (page) template once the blocks are generated
if ($settings->getPageLayout()) {
$controller->getLayout()->helper('page/layout')->applyTemplate($settings->getPageLayout());
}
$currentCategory = Mage::registry('current_category');
$root = $controller->getLayout()->getBlock('root');
if ($root) {
$controllerClass = $controller->getFullActionName();
if ($controllerClass != 'catalog-product-view') {
$root->addBodyClass('catalog-product-view');
}
$root->addBodyClass('product-' . $product->getUrlKey());
if ($currentCategory instanceof Mage_Catalog_Model_Category) {
$root->addBodyClass('categorypath-' . $currentCategory->getUrlPath())
->addBodyClass('category-' . $currentCategory->getUrlKey());
}
}
return $this;
}
}
add code in catalog.xml:-
partfinder/selector.phtml
Hope this will work for you. :)
Best of luck.
Jitendra Padmashali, KrishInc
I'm pretty new to Magento, and having problems trying to set a custom shipping method programmatically. I'm converting an xml from a thrid party into an order, and everything else (that I've worked on so far) is working fine. Also I'm having problems spelling "programmatically" but I won't ask for you help with that.
I set up my custom shipping method as follows:
To activate the shipping module in
app/etc/modules/Extension_Shipping.xml
<?xml version=
"1.0"?>
<config>
<modules>
<Extension_Shipping>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Shipping/>
</depends>
</Extension_Shipping>
</modules>
</config>
then to configure it in
app/code/local/Extension/Shipping/etc/config.xml
<?xml version=
"1.0" ?>
<config>
<modules>
<Extension_Shipping>
<version>0.1.0</version>
</Extension_Shipping>
</modules>
<global>
<models>
<extension_shipping>
<class>Extension_Shipping_Model</class>
</extension_shipping>
</models>
</global>
<default>
<carriers>
<extension_myrate>
<active>1</active>
<model>extension_shipping/carrier_myrate</model>
<title>Extension Shipping</title>
<name>Default Rate</name>
</extension_myrate>
</carriers>
</default>
</config>
then to add the class in
app/code/local/Extension/Shipping/Model/Carrier/MyRate.php
<?php
class Extension_Shipping_Model_Carrier_MyRate
extends Mage_Shipping_Model_Carrier_Abstract
implements Mage_Shipping_Model_Carrier_Interface
{
protected $_code = 'extension_myrate';
protected $_isFixed = true;
public function collectRates(Mage_Shipping_Model_Rate_Request
$request)
{
if (!$this->getConfigFlag('active')) {
return false;
}
$result = Mage::getModel('shipping/rate_result');
$method = Mage::getModel('shipping/rate_result_method');
$method->setCarrier('extension_myrate');
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod('extension_myrate');
$method->setMethodTitle($this->getConfigData('name'));
$method->setPrice(5);
$method->setCost(2);
$result->append($method);
return $result;
}
public function getAllowedMethods()
{
return array('extension_myrate' => $this->getConfigData('name'));
}
}
Basically I followed http://www.magentotricks.com/creating-a-customer-magento-shipping-method/
I thought it all worked fine, as the shipping method now shows up in the checkout screen, and can be set both by customers or in the admin "create new order." However, I'm not able to set it programmatically.
In my controller I'm trying to set the shipping method using the code
$shippingAddress = $quote->getShippingAddress()->addData($addressData);
$shippingAddress->setCollectShippingRates(true)->collectShippingRates()
->setShippingMethod('extension_myrate')
->setPaymentMethod('checkmo');
To add to my confusion, it worked once. but only once out of quite a few test orders. changing the "setShippingMethod" to "freeshipping_freeshipping" or "flatrate_flatrate" makes it update the shipping to those correctly. because of that and because I'm new and still having problems with the file structure, I'm guessing my problem is with setShippingMethod('extension_myrate') but I'm not entirely sure. Any advice would be helpful and appreciated.
Im trying to call an Observer after the order has been created, and AFTER payment has been captured.
So far I've tried;
checkout_submit_all_after,
sales_order_payment_place_end,
sales_order_place_after,
sales_order_payment_pay,
sales_order_payment_capture,
sales_order_payment_transaction_save_after
Just to name the main ones.
I've also logged all Event Dispaches inside dispatchEvent() but found nothing that stands out and is only fired when i need it.
the issue i'm having is that the status of the order is always ether 'Payment Pending' or something that predated this; meaning that i don't know whether the order will fail or succeed.
My aim, is to fire a function only on successful orders.
thanks.
after much more testing i found the following Observer to do the trick;
checkout_onepage_controller_success_action
This returns just the order id, so;
$order_id = $observer->getData('order_ids');
$order = Mage::getModel('sales/order')->load($order_id);
and you see that the order status is 'processing' and the payment is aproved (or not).
1 ) here is custom config.xml for call observer file
<?xml version="1.0"?>
<config>
<modules>
<Namespace_Modulename>
<version>0.1.0</version>
</Namespace_Modulename>
</modules>
<frontend>
<events>
<checkout_submit_all_after>
<observers>
<Namespace_Modulename_Customevent>
<type>singleton</type>
<class>Namespace_Modulename_Model_Observer</class>
<method>customFunction</method>
</Namespace_Modulename_Customevent>
</observers>
</checkout_submit_all_after>
</events>
</frontend>
</config>
2 ) create observer.php file inside your module/Model directory and paste this code
<?php
class Namespace_Modulename_Model_Observer
{
public function customFunction(Varien_Event_Observer $observer)
{
$order = $observer->getEvent()->getOrder();
//here you can add your custom code
}
}
please try this.. sure it will help you !
I have also tried all event but didn't get success. Then I moved to override Mage OnePageController and called my custom function. Below is the code to override onestep checkout.
app\etc\modules\Namespace_Module.xml
<Namespace_Checkout>
<active>true</active>
<codePool>local</codePool>
</Namespace_Checkout>
app\code\local\Namespace\Checkout\etc\config.xml
<?xml version="1.0"?>
<config>
<modules>
<Namespace_Checkout>
<version>0.1.0</version>
</Namespace_Checkout>
</modules>
<frontend>
<routers>
<checkout>
<args>
<modules>
<Namespace_Checkout before="Mage_OneStepCheckout">Namespace_Checkout</Namespace_Checkout>
</modules>
</args>
</checkout>
</routers>
</frontend>
</config>
app\code\local\Namespace\Checkout\controllers\OnepageController.php
<?php
require_once 'Mage/Checkout/controllers/OnepageController.php';
class Namespace_Checkout_OnepageController extends Mage_Checkout_OnepageController{
public function successAction(){
$session = $this->getOnepage()->getCheckout();
if (!$session->getLastSuccessQuoteId()) {
$this->_redirect('checkout/cart');
return;
}
$lastQuoteId = $session->getLastQuoteId();
$lastOrderId = $session->getLastOrderId();
$lastRecurringProfiles = $session->getLastRecurringProfileIds();
if (!$lastQuoteId || (!$lastOrderId && empty($lastRecurringProfiles))) {
$this->_redirect('checkout/cart');
return;
}
$this->customFunction(); // Custom function to call
$session->clear();
$this->loadLayout();
$this->_initLayoutMessages('checkout/session');
Mage::dispatchEvent('checkout_onepage_controller_success_action', array('order_ids' => array($lastOrderId)));
$this->renderLayout();
}
function customFunction(){
// This function is calling before clearing order session
//Here you can put all your custom code
}
}
?>
In the above controller, I have added customFunction() wher you can put your custom code.
Hope it will help you!
I have created an event observer that will send email on order completion.
I am sending email to email_address1 when a product is ordered from the category1 and sending email to email_address2 when a product is ordered from the cateogory2. Therefore I have created an observer event for this.
But when I click on the "Place Order" button nothing happens. What is the problem?
in magento/app/etc/modules/Custom_Email.xml:
<?xml version="1.0"?>
<config>
<modules>
<Custom_Email>
<codePool>local</codePool>
<active>true</active>
</Custom_Email>
</modules>
</config>
in magento/app/code/local/Custom/Email/etc/config.xml:
<?xml version="1.0"?>
<config>
<global>
<models>
<customemail>
<class>Custom_Email_Model</class>
</customemail>
</models>
<events>
<sales_order_place_after>
<observers>
<custom_email_order_observer>
<type>singleton</type>
<class>customemail/order_observer</class>
<method>sendOrder</method>
</custom_email_order_observer>
</observers>
</sales_order_place_after>
</events>
</global>
</config>
in magento/app/code/local/Custom/Email/Model/Order/Observer.php:
<?php
class Custom_Email_Model_Order_Observer
{
public function __contruct()
{
}
/**
* Exports new orders to an xml file
* #param Varien_Event_Observer $observer
* #return Feed_Sales_Model_Order_Observer
*/
public function sendOrder($observer){
$order = $observer->getEvent()->getOrder();
$cat_id = Mage::getModel('catalog/layer')->getCurrentCategory()->getId();
echo $cat_id;
//Implement logic here
...
$emailTemplate = Mage::getModel('core/email_template')
->loadDefault('rehab');
$emailTemplateVariables = array();
$emailTemplateVariables['order'] = $order;
$emailTemplate->setSenderName('Your shops name');
$emailTemplate->setSenderEmail('addres#from.com');
$emailTemplate->setTemplateSubject('Subject');
$emailTemplate->send('to#addres.com','Name', $emailTemplateVariables);
echo 'email sent';
}
}
?>
So any one know where is the problem?
The layer does not exist in the order context, nor is the category from which the product was selected available as a property of quote or order items. It's a known deficiency in Magento which unfortunately limits segmentation.