3

I am trying to put template /vendor/magento/module-payment/view/frontend/templates/info/default.phtml to my theme on below path

app/design/frontend/Smartwave/porto/Magento_Payment/templates/info/default.phtml

Another template works perfect. Above file is used in email template so I can't check by template path hint but I have put some html to test but its not taking from theme its take from vendor folder only.

I have removed cache,removed pub/static and did static content deploy. There is not layout related to it so I have not override it.

But no luck.

Edit:

I've also override info block to see if its work. below is code.

di file

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Payment\Block\Info" type="Vendor\Module\Block\Info" />
</config>

and block class file.

<?php
namespace Vendor\Module\Block;
use Magento\Framework\View\Element\Template;
class Info extends \Magento\Payment\Block\Info {
    /**
     * Payment rendered specific information
     *
     * @var \Magento\Framework\DataObject
     */
    public $_paymentSpecificInformation;

    /**
     * @var string
     */
    public $_template = 'Vendor_Module::info/default.phtml';

    /**
     * Retrieve info model
     *
     * @return \Magento\Payment\Model\InfoInterface
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getInfo()
    {
        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/infoblock.log');
            $logger = new \Zend\Log\Logger();
            $logger->addWriter($writer);
            $logger->info("Info block");

        $info = $this->getData('info');
        if (!$info instanceof \Magento\Payment\Model\InfoInterface) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('We cannot retrieve the payment info model object.')
            );
        }
        return $info;
    }

    /**
     * Retrieve payment method model
     *
     * @return \Magento\Payment\Model\MethodInterface
     */
    public function getMethod()
    {
        return $this->getInfo()->getMethodInstance();
    }

    /**
     * Render as PDF
     * @return string
     */
    public function toPdf()
    {
        $this->setTemplate('Magento_Payment::info/pdf/default.phtml');
        return $this->toHtml();
    }

    /**
     * Getter for children PDF, as array. Analogue of $this->getChildHtml()
     *
     * Children must have toPdf() callable
     * Known issue: not sorted
     * @return array
     */
    public function getChildPdfAsArray()
    {
        $result = [];
        foreach ($this->getLayout()->getChildBlocks($this->getNameInLayout()) as $child) {
            if (method_exists($child, 'toPdf') && is_callable([$child, 'toPdf'])) {
                $result[] = $child->toPdf();
            }
        }
        return $result;
    }

    /**
     * Get some specific information in format of array($label => $value)
     *
     * @return array
     */
    public function getSpecificInformation()
    {
        return $this->_prepareSpecificInformation()->getData();
    }

    /**
     * Render the value as an array
     *
     * @param mixed $value
     * @param bool $escapeHtml
     * @return array
     */
    public function getValueAsArray($value, $escapeHtml = false)
    {
        if (empty($value)) {
            return [];
        }
        if (!is_array($value)) {
            $value = [$value];
        }
        if ($escapeHtml) {
            foreach ($value as $_key => $_val) {
                $value[$_key] = $this->escapeHtml($_val);
            }
        }
        return $value;
    }

    /**
     * Check whether payment information should show up in secure mode
     * true => only "public" payment information may be shown
     * false => full information may be shown
     *
     * @return bool
     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
     */
    public function getIsSecureMode()
    {
        if ($this->hasIsSecureMode()) {
            return (bool)(int)$this->_getData('is_secure_mode');
        }

        $method = $this->getMethod();
        if (!$method) {
            return true;
        }

        $store = $method->getStore();
        if (!$store) {
            return false;
        }

        $methodStore = $this->_storeManager->getStore($store);
        return $methodStore->getCode() != \Magento\Store\Model\Store::ADMIN_CODE;
    }

    /**
     * Prepare information specific to current payment method
     *
     * @param null|\Magento\Framework\DataObject|array $transport
     * @return \Magento\Framework\DataObject
     */
    protected function _prepareSpecificInformation($transport = null)
    {
        if (null === $this->_paymentSpecificInformation) {
            if (null === $transport) {
                $transport = new \Magento\Framework\DataObject();
            } elseif (is_array($transport)) {
                $transport = new \Magento\Framework\DataObject($transport);
            }
            $this->_paymentSpecificInformation = $transport;
        }
        return $this->_paymentSpecificInformation;
    }
}
  • Yeah looks good to me also, anyting showing up in logs? – harri Dec 4 '17 at 15:13
  • Can you post the content of email template in Marketing/Communications/Email Templates? – Nero Phung Dec 6 '17 at 19:37
  • Also does the theme have parent tag? – Nero Phung Dec 6 '17 at 19:48
3

This is a bug in Magento. It’s been already reported here: https://github.com/magento/magento2/issues/10402 but closed due to inactivity.

The theme template overrides are not resolved correctly when the admin is trying to emulate the frontend (note that emails are sent via the admin but the environment emulation is supposed to take the correct theme template from the frontend based on the store id of the order). However, it always take the default template, making impossible an overwrite by copying the template into your theme.

I’m currently looking for a workaround and will post it here if I find one.

UPDATE:

Just found a workaround to force Magento to take the overwritten template from your custom theme. You need to overwrite the function

getInfoBlockHtml()

from vendor/magento/module-payment/Helper/Data.php

Specifically, by passing the $force = true option to the startEnvironmentEmulation() method it picks up the correct theme and will render the modified template.

In a custom module add the following preference to the app/code/[Vendor]/[ModuleName]/etc/di.xml file:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Payment\Helper\Data" type="[Vendor]\[ModuleName]\Helper\Payment\Data" />
</config>

Now create a new helper file that extends the original helper: app/code/[Vendor]/[ModuleName]/Helper/Payment/Data.php

<?php
namespace [Vendor]\[ModuleName]\Helper\Payment;

use Magento\Payment\Model\InfoInterface;

/**
 * Payment module base helper
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 *
 * @api
 * @since 100.0.2
 */
class Data extends \Magento\Payment\Helper\Data
{
    /**
     * Render payment information block
     *
     * @param InfoInterface $info
     * @param int $storeId
     * @return string
     * @throws \Exception
     */
    public function getInfoBlockHtml(InfoInterface $info, $storeId)
    {
        // add the area and most importantly set the "force" parameter to true to allow the theme template override
        $this->_appEmulation->startEnvironmentEmulation($storeId, \Magento\Framework\App\Area::AREA_FRONTEND, true);
        // end of custom code

        try {
            // Retrieve specified view block from appropriate design package (depends on emulated store)
            $paymentBlock = $this->getInfoBlock($info);
            $paymentBlock->setArea(\Magento\Framework\App\Area::AREA_FRONTEND)
                     ->setIsSecureMode(true);
            $paymentBlock->getMethod()
                     ->setStore($storeId);
            $paymentBlockHtml = $paymentBlock->toHtml();
        } catch (\Exception $exception) {
            $this->_appEmulation->stopEnvironmentEmulation();
            throw $exception;
        }

        $this->_appEmulation->stopEnvironmentEmulation();

        return $paymentBlockHtml;
    }
}

Now your custom template at app/design/frontend/[Vendor]/[theme_name]/Magento_Payment/templates/info/default.phtml will be used instead of the default one. Enjoy!

  • This solution works like a charm for me. Thank you!! – Dhara Bhatti Feb 18 at 11:25
0

Try running setup upgrade and then static content deploy. It may help.

  • No luck. And I don't think setup upgrade required – Kul Dec 4 '17 at 15:12
  • Smartwave/porto - In the module name "P" should be in caps? – Kalyan Chakravarthi V Dec 4 '17 at 15:17
  • Thanks but its theme name and other templates work fine for me. – Kul Dec 4 '17 at 15:26
0
+50

I am not totally sure about my answer because I do not have enough time to follow my logic but I discovered following issues:

  1. Is the payment method really use default.phtml? Most of them (if not all) configure specific info template inside of its block class (eg. Info\Checkmo > protected $_template = "custom template here". Since you are overriding default template there is a chance than non of payment methods really use it.

  2. Another trail might be configuration through protected class' attribute rather than by layout file as usual. I do not have a full insight into frontend processes but it is reasonable to check if overriding Payment\Block\Info.php to set your custom template will work for you. I mean, it have to - that is for sure. The true question is why you cant override it by placing phtml in custom design. My answer is because it is not configured in layout but in class itself and therefore it do not follow the templates fallback logic.

  • I've tried to extend class as well. see updated question – Kul Dec 7 '17 at 5:00
  • Ok, but are you 100% sure that default.phtml is the right template? Most payment info blocks override this attribute to set its own template. – Bartosz Herba Dec 7 '17 at 5:58
  • Yes. I have added class to 1 div of default.html to check and get html with that class in email. so i am 100% sure. And this templae is also called on order view in customer account and email when pay with cc payment method only. – Kul Dec 7 '17 at 6:17
  • Well, i just created custom theme and override this template without any problems. There is then something particularly related to your template. Maybe something is already changing the template? – Bartosz Herba Dec 7 '17 at 6:43
  • Are you getting overridden template content in email? It will work for customer account sales view but not for email. email will always take from vendor. – Kul Dec 8 '17 at 9:26
0

You can try move source template to:

Vendor/Module/view/frontend/templates/info/default.phtml

This solution works for me ;) And run all important setup: scripts

  • Yes. I have already tried it. but no luck – Kul Dec 8 '17 at 9:27
0
  1. Maybe you are not using that template in your theme?
  2. Try remove var/view_preprocessed and static files under pub/static/frontend and deploy new files and then flush cache.
0

It depends of you Payment provider. For example with Braintree you would have to override Block\Info with:

protected $_template = 'BigHippo_Email::info/default.phtml';

di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Braintree\Block\Info" type="BigHippo\Email\Block\Info"/>
</config>

BigHippo\Email\Block\Info.php

<?php
namespace BigHippo\Email\Block;

class Info extends \Magento\Braintree\Block\Info
{
    /**
     * @var string
     */
    protected $_template = 'BigHippo_Email::info/default.phtml';

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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