1

I override core template

Magento_Sales::order/view/history.phtml

to add new checkbox that will allow to send sms along side emails.

I added in this file:

Vendor_Module::order/view/history.phtml

new checkbox to allow sending sms.

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

/** @var \Magento\Sales\Block\Adminhtml\Order\View\History $block */
?>
<div id="order_history_block" class="edit-order-comments">
    <?php if ($block->canAddComment()) : ?>
        <div class="order-history-block" id="history_form">

            <div class="admin__field">
                <label for="history_status" class="admin__field-label"><?= $block->escapeHtml(__('Status')) ?></label>
                <div class="admin__field-control">
                    <select name="history[status]" id="history_status" class="admin__control-select">
                        <?php foreach ($block->getStatuses() as $_code => $_label) : ?>
                            <option value="<?= $block->escapeHtmlAttr($_code) ?>"<?php if ($_code == $block->getOrder()->getStatus()) : ?> selected="selected"<?php endif; ?>><?= $block->escapeHtml($_label) ?></option>
                        <?php endforeach; ?>
                    </select>
                </div>
            </div>

            <div class="admin__field">
                <label for="history_comment" class="admin__field-label">
                    <?= $block->escapeHtml(__('Comment')) ?>
                </label>
                <div class="admin__field-control">
                    <textarea name="history[comment]"
                              rows="3"
                              cols="5"
                              id="history_comment"
                              class="admin__control-textarea"></textarea>
                </div>
            </div>

            <div class="admin__field">
                <div class="order-history-comments-options">
                    <div class="admin__field admin__field-option">
                        <?php if ($block->canSendCommentEmail()) : ?>
                            <input name="history[is_customer_notified]"
                                   type="checkbox"
                                   id="history_notify"
                                   class="admin__control-checkbox"
                                   value="1" />
                            <label class="admin__field-label" for="history_notify">
                                <?= $block->escapeHtml(__('Notify Customer by Email')) ?>
                            </label>
                        <?php endif; ?>
                    </div>
                    <div class="admin__field admin__field-option">
                        <?php if ($block->canSendCommentEmail()) : ?>
                            <input name="history[is_customer_sms_notified]"
                                   type="checkbox"
                                   id="history_notify_sms"
                                   class="admin__control-checkbox"
                                   value="1" />
                            <label class="admin__field-label" for="history_notify_sms">
                                <?= $block->escapeHtml(__('Notify Customer by SMS')) ?>
                            </label>
                        <?php endif; ?>
                    </div>

                    <div class="admin__field admin__field-option">
                        <input name="history[is_visible_on_front]"
                               type="checkbox"
                               id="history_visible"
                               class="admin__control-checkbox"
                               value="1" />
                        <label class="admin__field-label" for="history_visible">
                            <?= $block->escapeHtml(__('Visible on Storefront')) ?>
                        </label>
                    </div>
                </div>

                <div class="order-history-comments-actions">
                    <?= $block->getChildHtml('submit_button') ?>
                </div>
            </div>
        </div>
    <?php endif;?>

    <ul class="note-list">
    <?php foreach ($block->getOrder()->getStatusHistoryCollection(true) as $_item) : ?>
        <li class="note-list-item">
            <span class="note-list-date"><?= /* @noEscape */ $block->formatDate($_item->getCreatedAt(), \IntlDateFormatter::MEDIUM) ?></span>
            <span class="note-list-time"><?= /* @noEscape */ $block->formatTime($_item->getCreatedAt(), \IntlDateFormatter::MEDIUM) ?></span>
            <span class="note-list-status"><?= $block->escapeHtml($_item->getStatusLabel()) ?></span>
            <span class="note-list-customer">
                <?= $block->escapeHtml(__('Customer')) ?>
                <?php if ($block->isCustomerNotificationNotApplicable($_item)) : ?>
                    <span class="note-list-customer-notapplicable"><?= $block->escapeHtml(__('Notification Not Applicable')) ?></span>
                <?php elseif ($_item->getIsCustomerNotified()) : ?>
                    <span class="note-list-customer-notified"><?= $block->escapeHtml(__('Notified')) ?></span>
                <?php else : ?>
                    <span class="note-list-customer-not-notified"><?= $block->escapeHtml(__('Not Notified')) ?></span>
                <?php endif; ?>
            </span>
            <?php if ($_item->getComment()) : ?>
                <div class="note-list-comment"><?= $block->escapeHtml($_item->getComment(), ['b', 'br', 'strong', 'i', 'u', 'a']) ?></div>
            <?php endif; ?>
        </li>
    <?php endforeach; ?>
    </ul>
    <script>
        require(['prototype'], function(){
            if($('order_status'))$('order_status').update('<?= $block->escapeJs($block->escapeHtml($block->getOrder()->getStatusLabel())) ?>');
        });
    </script>
</div>

I create plugin:

Vendor\Module\Plugin\AddCommentPlugin.php
<?php

namespace Vendor\OrderSmsComment\Plugin;

use Magento\Directory\Api\CountryInformationAcquirerInterface;
use Magento\Framework\Event\ManagerInterface as EventManager;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Controller\Adminhtml\Order\AddComment;
use Psr\Log\LoggerInterface;
use Vendor\OrderSmsComment\Helper\CountryPhonePrefix;
use Vendor\SmsSender\Helper\SmsSenderHelper;
use Vendor\SmsSender\Model\SmsEventParams;

class AddCommentPlugin
{
    const SEND_SMS_EVENT = "smssender_sendsms";

    /**
     * @var LoggerInterface
     */
    private $logger;
    /**
     * @var CountryInformationAcquirerInterface
     */
    private $countryInformationAcquirer;
    /**
     * @var CountryPhonePrefix
     */
    private $countryPhonePrefixHelper;
    /**
     * @var EventManager
     */
    private $eventManager;
    /**
     * @var OrderRepositoryInterface
     */
    private $orderRepository;

    public function __construct(LoggerInterface $logger, CountryInformationAcquirerInterface $countryInformationAcquirer, CountryPhonePrefix $countryPhonePrefixHelper, EventManager $eventManager, OrderRepositoryInterface $orderRepository)
    {
        $this->logger = $logger;
        $this->countryInformationAcquirer = $countryInformationAcquirer;
        $this->countryPhonePrefixHelper = $countryPhonePrefixHelper;
        $this->eventManager = $eventManager;
        $this->orderRepository = $orderRepository;
    }

    public function afterExecute(AddComment $subject, $result)
    {
        $id = $subject->getRequest()->getParam('order_id');
        try {
            $order = $this->orderRepository->get($id);

            if ($order) {
                $data = $subject->getRequest()->getPost('history');
                if (empty($data['comment']) && $data['status'] == $order->getDataByKey('status')) {
                    throw new \Magento\Framework\Exception\LocalizedException(
                        __('The comment is missing. Enter and try again.')
                    );
                }
                $notify = $data["is_customer_sms_notified"] ?? false;
                $comment = trim(strip_tags($data['comment']));

                if (strlen($comment) > SmsSenderHelper::MAX_CHARACTERS) {
                    $notify = false;
                }

                if ($notify) {
                    $phone = $order->getBillingAddress()->getTelephone();
                    $country = $this->countryInformationAcquirer->getCountryInfo($order->getBillingAddress()->getCountryId());
                    $countryPhonePrefix = $this->countryPhonePrefixHelper->getCountryPhonePrefixByCode($country->getTwoLetterAbbreviation());
                    $smsParams = new SmsEventParams($phone, $comment, $countryPhonePrefix);
                    $this->eventManager->dispatch(self::SEND_SMS_EVENT, ["sms_params" => $smsParams]);
                }
            }
        } catch (\Exception $exception) {
            $this->logger->debug("No order.");
        }
        return $result;
    }
}

i add it's definition to di.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Sales\Controller\Adminhtml\Order\AddComment">
        <plugin name="Vendor_OrderSmsComment_Plugin" type="Vendor\OrderSmsComment\Plugin\AddCommentPlugin" sortOrder="1" disabled="false"/>
    </type>
</config>

and also add in module.xml:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_OrderSmsComment" setup_version="0.0.1">
        <sequence>
            <module name="Magento_Sales"/>
        </sequence>
    </module>
</config>

Everything is working fine, just one little thing is working in not the way i want.

After adding comment the block order_history_block is reloaded by js. And after that Magento loads not my overrided block but original one - Magento_Sales::order/view/history.phtml.

How i can change this ? How i can tell magento to only load my phtml file ?

Solution:

This strange behavior was because there is another layout just to handle view after you click submit button when adding comment. So, to resolve this problem you need to simple add another layout file to your module: Vendor/Module/view/adminhtml/layout/sales_order_addcomment.xml and in this file just tell Magento what template to use for block you want to replace:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name='order_history' template="Vendor_Module::order/view/history.phtml"/>
    </body>
</page>

Put your template file into this file

app/code/Vendor/Module/view/templates/order/view/history.phtml

  • Try with preference. – Dinesh Rajput Nov 25 '19 at 13:39
  • Can you be more specific ? Preference of what ? Any example ? – Piotr Mucha Dec 2 '19 at 10:19
  • i've added solution – Piotr Mucha Dec 3 '19 at 8:40

Your Answer

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

Browse other questions tagged or ask your own question.