Question

I have a custom attribute for products set in the admin that I'd like to render on the new Order transactional email; I've tried in different ways but I am not able to make it works.

this is my code:

Vendor/Email/Block/Order/Email/Items/DefaultItems.php

    <?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace <Vendor>\Email\Block\Order\Email\Items;

use Magento\Sales\Model\Order\Creditmemo\Item as CreditmemoItem;
use Magento\Sales\Model\Order\Invoice\Item as InvoiceItem;
use Magento\Sales\Model\Order\Item as OrderItem;
use Magento\Catalog\Model\ProductFactory;

/**
 * Sales Order Email items default renderer
 *
 * @author     Magento Core Team <core@magentocommerce.com>
 */
class DefaultItems extends \Magento\Framework\View\Element\Template
{


    public $productFactory;
    /**
     * Constructor
     *
     * @param Template\Context $context
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        ProductFactory $productFactory,
        array $data = []
    )
    {
        $this->productFactory = $productFactory;

        parent::__construct($context, $data);
    }


    /**
     * Retrieve current order model instance
     *
     * @return \Magento\Sales\Model\Order
     */
    public function getOrder()
    {
        return $this->getItem()->getOrder();
    }

    /**
     * @return array
     */
    public function getItemOptions()
    {
        $result = [];
        if ($options = $this->getItem()->getOrderItem()->getProductOptions()) {
            if (isset($options['options'])) {
                $result = array_merge($result, $options['options']);
            }
            if (isset($options['additional_options'])) {
                $result = array_merge($result, $options['additional_options']);
            }
            if (isset($options['attributes_info'])) {
                $result = array_merge($result, $options['attributes_info']);
            }
        }

        return $result;
    }

    /**
     * @param string|array $value
     * @return string
     */
    public function getValueHtml($value)
    {
        if (is_array($value)) {
            return sprintf(
                '%d',
                $value['qty']
            ) . ' x ' . $this->escapeHtml(
                $value['title']
            ) . " " . $this->getItem()->getOrder()->formatPrice(
                $value['price']
            );
        } else {
            return $this->escapeHtml($value);
        }
    }

    /**
     * @param mixed $item
     * @return mixed
     */
    public function getSku($item)
    {
        if ($item->getOrderItem()->getProductOptionByCode('simple_sku')) {
            return $item->getOrderItem()->getProductOptionByCode('simple_sku');
        } else {
            return $item->getSku();
        }
    }

    /**
     * Return product additional information block
     *
     * @return \Magento\Framework\View\Element\AbstractBlock
     */
    public function getProductAdditionalInformationBlock()
    {
        return $this->getLayout()->getBlock('additional.product.info');
    }

    /**
     * Get the html for item price
     *
     * @param OrderItem|InvoiceItem|CreditmemoItem $item
     * @return string
     */
    public function getItemPrice($item)
    {
        $block = $this->getLayout()->getBlock('item_price');
        $block->setItem($item);
        return $block->toHtml();
    }

    public function getImage($id)
    {
        $product = $this->productFactory->create()->load($id);
        return $this->getBaseUrl() . 'media/catalog/product' . $product->getImage();
    }

    public function getAttr($id)
    {
        $product = $this->productFactory->create()->load($id)->getAttributes();
        return $product;
    }

}

And this is the code for the template file:

Vendor/Email/view/frontend/templates/email/items/order/default.phtml

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

/** @var $block \Magento\Sales\Block\Order\Email\Items\DefaultItems */

/** @var $_item \Magento\Sales\Model\Order\Item */
$_item = $block->getItem();
$_order = $_item->getOrder();
?>
<tr>
    <td class="item-info<?php if ($block->getItemOptions()): ?> has-extra<?php endif; ?>">
            <img src="<?php echo $block->getImage($_item->getProductId()); ?>" alt="<?php echo $block->escapeHtml($_item->getName()); ?>"
                 class="product-image" width="149" height="109" />
        <div class="product-info">
                <p class="product-name"><strong><?= $block->escapeHtml($_item->getName()) ?></strong></p>                  
                <p><?php echo $block->getAttr();   ?></p> 
            <?php if ($block->getItemOptions()): ?>
                <dl class="item-options">
                <?php foreach ($block->getItemOptions() as $option): ?>
                    <dt class="<?= /* @escapeNotVerified */  $option['label'] ?>"><?= /* @escapeNotVerified */  $option['label'] ?>:
                    <span class="<?= /* @escapeNotVerified */  $option['label'] ?>">
                        <?= /* @escapeNotVerified */  nl2br($option['value']) ?>
                    </span>
                    </dt>

                <?php endforeach; ?>
                </dl>
            <?php endif; ?>
            <?php $addInfoBlock = $block->getProductAdditionalInformationBlock(); ?>
            <?php if ($addInfoBlock) :?>
                <?= $addInfoBlock->setItem($_item)->toHtml() ?>
            <?php endif; ?>
            <?= $block->escapeHtml($_item->getDescription()) ?>
        </div>
    </td>
    <td class="item-qty"><?= /* @escapeNotVerified */  $_item->getQtyOrdered() * 1 ?></td>
    <td class="item-price">
        <?= /* @escapeNotVerified */  $block->getItemPrice($_item); ?>
    </td>
</tr>
<?php if ($_item->getGiftMessageId() && $_giftMessage = $this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessage($_item->getGiftMessageId())): ?>
<tr>
    <td colspan="3" class="item-extra">
        <table class="message-gift">
            <tr>
                <td>
                    <h3><?= /* @escapeNotVerified */  __('Gift Message') ?></h3>
                    <strong><?= /* @escapeNotVerified */  __('From:'); ?></strong> <?= $block->escapeHtml($_giftMessage->getSender()) ?>
                    <br /><strong><?= /* @escapeNotVerified */  __('To:'); ?></strong> <?= $block->escapeHtml($_giftMessage->getRecipient()) ?>
                    <br /><strong><?= /* @escapeNotVerified */  __('Message:'); ?></strong>
                    <br /><?= $block->escapeHtml($_giftMessage->getMessage()) ?>
                </td>
            </tr>
        </table>
    </td>
</tr>
<?php endif; ?>

So my method is getAttr() but it always return NULL, I was trying to echo all the attributes and then target the ones I am interested in, but I can't get it to work at the moment. i was able the get the product image with the getImage() method

Was it helpful?

Solution

I will answer my own question in case someone else will stumble upon it,

This is what I ultimately did (I changed the method name to a more accurate one):

Like @kusum suggested

In <Vendor>/Email/Block/Order/Email/Items/DefaultItems.php I put

public  function getProductModel($id)
    {
        $product = $this->productFactory->create()->load($id);
        return $product;
    }

and in <Vendor>/Email/view/frontend/templates/email/items/order/default.phtml I've called the method like so:

$_product = $block->getProductModel($_item->getProductId());
<?php echo $_product->getAttributeText("lead_time_title");   ?>

but what ultimately did the trick was to copy the exact same method over to

<Vendor>/Email/Block/Order/Email/Items/Order/DefaultOrder.php

Otherwise getProductModel it would always return null

OTHER TIPS

You need to change your way to get product attributes in phtml: you can get attributes using <?php $attributes = $block->getAttr($_item->getProductId()); ?> and after that you need to change function defined in block as:

public function getAttr($id)
{
     $product = $this->productFactory->create()->load($id);
     return $product;
}

Now you can get all attributes in below way:

echo $attributes->getName();
echo $attributes->getPrice();

In this way you can get any other custom attribute's value.

Hope this was helpful.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top