Magento Cart Items – Getting Child Product Items

This is how it’s done in the Mage_Checkout_Block_Cart_Item_Renderer_Configurable class. It will return the simple product if available otherwise it will return the product of the cart item.

<?php
public function getChildProduct()
{
    if ($option = $this->getItem()->getOptionByCode('simple_product')) {
        return $option->getProduct();
    }
    return $this->getProduct();
}

Getting Attribute Values

There are a few ways to get get attribute values in Magento:

<?php
$product->getAttributeCode();

$product->getData(attribute_code);

These two methods do the same thing, however if the attribute is a type of select or multiselect then the ID of the value will be returned rather than the text of the attribute.

For these methods, the frontend attribute can be obtained from the product and used to get the attribute value:

<?php
// Get the type of the attribute as dictated by the attribute's *frontend_model* field.
// This will be a Mage_Catalog_Model_Resource_Eav_Attribute model:
$attr = $product->getResource()->getAttribute($attributeName);

// Get the value from the frontend type of the attribute. The frontend type is dictated by the frontend_model column in the eav_attribute table.  By default, this will be Mage_Eav_Model_Entity_Frontend_Default if the frontend_model field is empty.

$val = $attr->getFrontend()->getValue($product);

Note If an attribute value is not set, (I.e. NULL) the frontend attribute will return “No”. This happens in the Mage_Eav_Model_Entity_Attribute_Frontend_Abstract class’ getValue method:

 if (!$valueOption) {
    $opt     = Mage::getModel('eav/entity_attribute_source_boolean');
    $options = $opt->getAllOptions();

    if ($options) {
        foreach ($options as $option) {
            if ($option['value'] == $value) {
                $valueOption = $option['label'];
            }
        }
    }
}

– It uses the “eav/entity_attribute_source_boolean” and defaults to one of the values set within in.

getAttributeText

Another way to get the value of a select attribute is to use

<?php
$product->getAttributeText(attribute_name);

This will use the attribute’s source_model (typically used in getting all possible values in adminhtml), and looks up the text of the attribute based on the value’s ID (this is set on the product’s data array):

<?php
   public function getAttributeText($attributeCode)
    {
        return $this->getResource()
            ->getAttribute($attributeCode)
                ->getSource()
                    ->getOptionText($this->getData($attributeCode));
    }

Outputting Attributes

Product attributes have various non-standard EAV options to control how they’re output, such as escaping HTML characters. To honour these settings, product attributes should be passed through the catalog/output helper:

<?php
$helper = Mage::helper('catalog/output');

echo $helper->productAttribute($product, $value, 'attribute_name');

Outputting a list of Attributes

Magento provides a block to output product attributes on the product detail page, provided they’re set to be visible on front. Use the Mage_Catalog_Block_Product_View_Attributes. If an attribute isn’t set, it will return “N/A”, if this is not required then this could be overridden and this line replaced with a continue;.

Magento Tax Snippets

Getting the Customer’s Address Country For Tax Calculations

The following will perform the following fallbacks:

-The quote’s shipping address
-The customer’s shipping address
-The customer’s billing address
-The default system configuration country

class Namespace_Module_Helper_Data extends Mage_Core_Helper_Abstract {
    const COUNTRY_CODE_GB = "GB";

    public function isDeliveryAddressUk(){
        /** @var Mage_Sales_Model_Quote $quote */
        $quote = Mage::getSingleton('checkout/session')->getQuote();
        $address = $quote->getShippingAddress();

        if($address && $address->getCountryId()){
            return $address->getCountryId() == self::COUNTRY_CODE_GB;
        }

        $cSession = Mage::getSingleton('customer/session');

        if($cSession->isLoggedIn()){
            $customer = $cSession->getCustomer();
            $address = $customer->getDefaultShippingAddress();

            if($address && $address->getCountryId()){
                return $address->getCountryId() == self::COUNTRY_CODE_GB;
            }

            $customer->getDefaultBillingAddress();

            if($address && $address->getCountryId()){
                return $address->getCountryId() == self::COUNTRY_CODE_GB;
            }
        }
        
        return Mage::getStoreConfig(Mage_Tax_Model_Config::CONFIG_XML_PATH_DEFAULT_COUNTRY) == self::COUNTRY_CODE_GB;
    }
}

Checking the Tax Display Type

// Including Tax
if(Mage::helper('tax')->getPriceDisplayType() == Mage_Tax_Model_Config::DISPLAY_TYPE_INCLUDING_TAX){
    ...
}

// Excluding Tax
if(Mage::helper('tax')->getPriceDisplayType() == Mage_Tax_Model_Config::DISPLAY_TYPE_EXCLUDING_TAX){
    ...
}

Twitter Cards & Magento

Twitter cards offer rich ways to share content from websites. Here’s how to implement Twitter’s card data and add a share link to product pages!

Create A Head Block

This will allow us to implement Twitter’s meta tags into Magento’s head block. Creating this as a text list will also allow us to reuse this for pages other than product detail.

<default>
    <reference name="head">
        <block type="core/text_list" name="twitter.head.extra" />
    </reference>
</default>

Add The Meta Card Data

<catalog_product_view>
    <reference name="twitter.head.extra">
        <block type="modulename/catalog_product_view_meta" name="twitter.product.meta" template="catalog/product/view/meta.phtml" />
    </reference>
</catalog_product_view>

Create The Meta Template

Create this in the location catalog/product/view/meta.phtml

<?php
$_imageUrl = $this->getImageUrl();
$_product = $this->getProduct();

?>
<?php if($_imageUrl): ?>
    <meta name="twitter:card" content="summary" />
    <meta name="twitter:image" content="<?php echo $_imageUrl; ?>">
    <meta name="twitter:site" content="@twitter_handle" />
    <meta name="twitter:title" content="<?php echo $this->htmlEscape($_product->getName()); ?>" />
    <meta name="twitter:description" content="<?php echo $this->htmlEscape($_product->getShortDescription()); ?>" />
<?php endif; ?>

Create The Block Class

This is the class we reference in our XML and should correspond to modulename/catalog_product_view_meta

<?php
class Namespace_Module_Block_Catalog_Product_View_Meta extends Mage_Core_Block_Template
{
    protected function getProduct()
    {
        return Mage::registry('product');
    }

    public function getImageUrl()
    {
        if(!($product = $this->getProduct())){
            return;
        }

        return Mage::helper('catalog/image')->init($product, 'small_image');
    }
}

Add A Sharing Link

If the above steps are working correctly, all of the product meta tags included in the head of the product page’s head. Now, we just nee to create a sharing link from the page and Twitter should do the rest for us!

<?php 
$_product = $this->getProduct();
$_helper = $this->helper('catalog/output');
$_productName = urlencode(trim($_helper->productAttribute($_product, $_product->getName(), 'name')));
$_productUrl = urlencode(trim($_product->getProductUrl()));
?>

<a class="icon icon-twitter" href="<?php echo 'http://twitter.com/home?status=' . $_productName . "  " . $_productUrl; ?>" target="_blank" title="<?php echo Mage::helper('core')->quoteEscape($this->__('Share on Twitter')) ?>">
    <span><?php echo $this->__('Share on Twitter') ?></span>
</a>

Excluding Selectors From ManaPro Layered Nav SEO Plus

Use the method setInterceptedLinkContainers on the m_ajax_update block to choose the containers which will be used.

<catalog_category_layered>
	<reference name="m_ajax_update">
            <action method="setInterceptedLinkContainers"><css_selector>.mb-mana-catalog-leftnav,.mb-mana-catalog-rightnav,.block-layered-nav.m-topmenu,.block-layered-nav.m-top,.toolbar</css_selector></action>  
	</reference>
</catalog_category_layered>

To remove links from any containers, simply make them more specific to your DOM’s structure.

Any link which calls a window.setLocation from this point will be intercepted by Mana which will check whether the link is contained in any of the elements set above.

window.setLocation 

Mana redefines the window.setLocation method in its Ajax.js file. It takes two parameters – the first being the URL and the second being the element; if an element is not passed in as this parameter then the interception will always succeed. In these cases, in may be necessary to pass this in as the second parameter.

_callInterceptionCallback, _findMatchingInterceptor, _matchedInterceptorCache