Magento – How to Get Downloadable Product URL in Email Template

ce-1.9.1.0downloadableemail-templates

As the title suggest and as screeshot show, how can I get only the downloadable product URL of every product ordered and show it in email template?

I want to highlight the link(s) in the email sent.

enter image description here

Best Answer

One way to do it would be to create a block in a custom module that fetches download links from the database for current order. It is similar to how download links are currently generated for each order item. Block can be added to order emails using custom layout update handle, same way order items are added.

Module structure is pretty simple, we only need two files. First one is our module configuration in app/code/local/Custom/Module/etc/config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Custom_Module>
            <version>1.0.0.0</version>
        </Custom_Module>
    </modules>

    <global>
        <blocks>
            <custom_module>
                <class>Custom_Module_Block</class>
            </custom_module>
        </blocks>
    </global>
</config>

And our block: app/code/local/Custom/Module/Block/Email/Download/Links.php

class Custom_Module_Block_Email_Download_Links extends Mage_Core_Block_Template
{
    protected $_linksCollection;

    public function getDownloadLinksCollection()
    {
        if (is_null($this->_linksCollection)) {
            $this->_linksCollection = Mage::getModel('downloadable/link_purchased_item')->getCollection();
            $this->_linksCollection->getSelect()->where('order_item_id IN (?)', $this->_getItemIds());
        }

        return $this->_linksCollection;
    }

    public function getPurchasedLinkUrl($item)
    {
        return $this->getUrl('downloadable/download/link', array(
            'id'        => $item->getLinkHash(),
            '_store'    => $this->getOrder()->getStore(),
            '_secure'   => true,
            '_nosid'    => true
        ));
    }

    protected function _getItemIds()
    {
        $itemIds = array();

        foreach ($this->getOrder()->getAllItems() as $item) {
            $itemIds[] = $item->getId();
        }

        return $itemIds;
    }
}

Obviously we will also need a template file for our block and a layout update file to add our handle.

Template location is arbitrary, I saved it in app/design/frontend/your_package/your_theme/template/custommodule/email/download/links.phtml and it looks like this:

<?php if ($this->getDownloadLinksCollection()->getSize()): ?>
    <table cellpadding="0" cellspacing="0" border="0" width="100%">
        <thead>
        <tr>
            <th style="font-family: Verdana, Arial; font-weight: 700; padding: 10px 15px; background: #f1f1f1; text-transform: uppercase; text-align: left; font-size: 11px;" class="cell-name">
                <?php echo $this->__('Download Links') ?>
            </th>
        </tr>
        </thead>
        <tbody>
        <?php foreach ($this->getDownloadLinksCollection() as $link): ?>
            <tr>
                <td style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-collapse: collapse; padding: 6px 18px; margin: 0; width: 100%; background: #e1f0f8;">
                    <a style="color:#1E7EC8;" href="<?php echo $this->getPurchasedLinkUrl($link) ?>">
                        <?php echo $this->escapeHtml($link->getLinkTitle()) ?>
                    </a>
                </td>
            </tr>
        <?php endforeach ?>
        </tbody>
    </table>
<?php endif ?>

I didn't want to register new layout file so I opted for local.xml instead. File is saved in app/design/frontend/your_package/your_theme/layout/local.xml

<?xml version="1.0"?>
<layout version="0.1.0">

    <email_download_links>
        <block type="custom_module/email_download_links" name="email.download.links" as="email.download.links" template="custommodule/email/download/links.phtml"/>
    </email_download_links>

</layout>

Now we just have to insert this in our email template and we are done. I did it from admin (System > Transactional Emails) since I already had order email configured there. You just have to find a suitable location, depending on your markup, and insert this piece of code:

{{layout handle="email_download_links" order=$order}}

Of course you can always change markup in links.phtml to fit your specific needs.

And that's all there is to it. Hope this makes sense :)