3

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 <[email protected]>
 */
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

2 Answers 2

1

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

3
  • Hi, How to override defaultorder.php file. Commented Aug 17, 2019 at 10:10
  • Can you share you updated code? Commented Aug 17, 2019 at 10:10
  • I'm doing this same work Commented Aug 17, 2019 at 10:11
0

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.

1
  • Hello, sorry for the late reply; I've tried that but php return this error: PHP Fatal error: Uncaught Error: Call to a member function getAttr() on null And I don't understand why it's returning null, because I use the same function for getImage() and it works Commented Jul 6, 2017 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.