Add block to order success page

attribute-setcheckout-pagemagento2.3

I need to display a static block to success page depending on the attribute-set of products in the order

Best Answer

To fulfill your requirements, your can follow below steps and you need to use event observer.

  1. Create a Block app/code/StackExchange/Magento/Block/Checkout/Success.php which is responsible for render content.

Code

<?php

namespace StackExchange\Magento\Block\Checkout;

use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context ;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Order;

class Success extends Template
{
    /**
     * @var OrderRepositoryInterface
     */
    private $orderRepository;

    public function __construct(
        OrderRepositoryInterface $orderRepository,
        Context $context, array $data = [])
    {
        parent::__construct($context, $data);
        $this->orderRepository = $orderRepository;
    }

    /**
     * @param $orderId
     * @return false|OrderInterface
     */
    public function getOrderById($orderId)
    {
        try {
            $order = $this->orderRepository->get($orderId);
        }catch (NoSuchEntityException $exception){
                return false;
        }
        return  $order;
    }
    public function getCmsBlock($identifier)
    {
        $cmsBlock = $this->_layout->createBlock(\Magento\Cms\Block\Block::class)
            ->setBlockId($identifier)
            ->toHtml();
        return $cmsBlock;
    }
}

  1. Create a phtml which where the cms block will be rendered based on condition

path like : app/code/StackExchange/Magento/view/frontend/templates/custom-block.phtml

Code

<?php
/**
 * @var  \StackExchange\Magento\Block\Checkout\Success $block
 */
?>

<?php if (!empty($block->getOrderIds())):?>
    <?php foreach ($block->getOrderIds() as $orderId):?>
            <?php $order = $block->getOrderById((int) $orderId);?>
            <?php if ($order):?>
                 <?php /**  @var \Magento\Sales\Model\Order\Item $item */ ?>
                <?php foreach($order->getAllVisibleItems() as $item) { ?>
                    <?php $product = $item->getProduct() ;?>
                    <?php if (null !== $product):?>
                            <?php if ($product->getAttributeSetId() === 'SomeId'){ ?>
                                    // Static block'
                                    <?=  $block->getCmsBlock('My_CMS_BLOCK_IDENTIFIER')?>
                            <?php  } ?>
                     <?php endif; ?>
                <?php } ?>
            <?php endif; ?>
    <?php endforeach ;?>
<?php endif; ?>
  1. Most important, Create an observer which is passed order id to step1 Block class.

Observer class path: app/code/StackExchange/Magento/Observer/Frontend/Checkout/OnepageControllerSuccessAction.php

code

<?php
/**
 * Copyright ©  All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace StackExchange\Magento\Observer\Frontend\Checkout;

use Magento\Framework\Event\Observer;
use Magento\Framework\View\LayoutInterface;

class OnepageControllerSuccessAction implements \Magento\Framework\Event\ObserverInterface
{
    /**
     * @var LayoutInterface
     */
    private $layout;

    public function __construct(LayoutInterface $layout)
    {
        $this->layout = $layout;
    }
    /**
     * Execute observer
     *
     * @param Observer $observer
     * @return void
     */
    public function execute(
        Observer $observer
    ) {
        $orderIds = $observer->getEvent()->getOrderIds();
        if (empty($orderIds) || !is_array($orderIds)) {
            return;
        }
        $block = $this->layout->getBlock('checkout.success.custom.block');
        if ($block) {
            $block->setOrderIds($orderIds);
        }
    }
}

  1. Next to create an event.xml file where define observer.

File path: app/code/StackExchange/Magento/etc/frontend/events.xml

code

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        si:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="checkout_onepage_controller_success_action">
        <observer name="pass_order_to_success"
                  instance="StackExchange\Magento\Observer\Frontend\Checkout\OnepageControllerSuccessAction"/>
    </event>
</config>

5.Last step to create a layout which is responsible for content to success page

File Path: app/code/StackExchange/Magento/view/frontend/layout/checkout_onepage_success.xml

code

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="StackExchange\Magento\Block\Checkout\Success"
                   name="checkout.success.custom.block"
                   template="StackExchange_Magento::custom-block.phtml"/>
        </referenceContainer>
    </body>
</page>
Related Topic