We sacrifice by not doing any other technology, so that you get the best of Magento.

We sacrifice by not doing any other technology, so that you get the best of Magento.

    Magento 2: Add custom column in shipment grid admin panel

    Today we are going to write that how to add a custom column in the sales order grid and show that custom column in the shipment grid.

    Firstly, you need to add that column in the sales_shipment table and sales_shipment_grid table via declarative scema.

    You need to add this file to the custom module

    Magemonkeys/ModuleName/view/adminhtml/ui_component/sales_order_shipment_grid.xml

    <?xml version="1.0" encoding="UTF-8"?>                         
    <listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="sales_order_shipment_columns">
    <column name="new_fieldname">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">text</item>
                <item name="label" xsi:type="string" translate="true">New field column name</item>
                <item name="visible" xsi:type="boolean">false</item>
            </item>
        </argument>
    </column>                                                    
    </columns>                                                   
    </listing>

    Copy column value to grid table.

    For that need to create di.xml file in Magemonkeys/ModuleName/etc/

    <?xml version="1.0"?>                                                   
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="MagentoSalesModelResourceModelOrderShipmentGrid" type="MagentoSalesModelResourceModelGrid">
    <arguments>
        <argument name="columns">
            <item name="new_fieldname" xsi:type="string">sales_shipment.new_fieldname</item>
        </argument>
    </arguments>                                                     
    </virtualType>                                                        
    </config>

    That’s it.

     

     

    How to remove ‘Invalid security or form key. Please refresh the page’ error message when logged in Magento admin 2.4.x?

    If you want to remove ‘Invalid security or form key. Please refresh the page’ error message when logged in to Magento admin 2.4.x, then you need to make changes to the following file.

    Step 1 : Open the vendor file like /vendor/magento/module-backend/App/Action/Plugin/Authentication.php and override to your custom theme

    Step 2 : Find below code in the bottom section of the Authentication.php file. Approx line no. 228

    $requestParts = explode('/', trim($request->getRequestUri(), '/'), 3);
    $baseUrlPath = trim(parse_url($this->backendUrl->getBaseUrl(), PHP_URL_PATH), '/');
    $routeIndex = empty($baseUrlPath) ? 0 : 1;
    $requestUri = $this->_url->getUrl($requestParts[$routeIndex]);

    Step 3 : Replace above code with below mentioned code

    $requestParts = strpos(trim($request->getRequestUri(),'/'), $request->getFrontName()) === 0 ?
                    explode('/', trim($request->getRequestUri(), '/'), 4) :
                    explode('/', trim($request->getRequestUri(), '/'), 3);
    if (($key = array_search($request->getFrontName(), $requestParts)) !== false) {
        unset($requestParts[$key]);
    }
    $requestParams = $request->getParams();
    unset($requestParams['key'], $requestParams['form_key']);
    $requestUri = $this->_url->getUrl(implode('/', $requestParts), $requestParams);
    

     

    Step 4 : After change above code, please run below mentioned commands

    - php bin/magento setup:upgrade
    - php bin/magento setup:static-content:deploy
    - php bin/magento cache:clean

     

     

    That’s it…

    Now logout your admin panel and again logged in and see your error now resolved…

    Magento 2 – how to show including & excluding tax price on product option?

    Step 1: First you need to add di.xml in the following path:

    app/code/Magemonkey/PriceAdjustment/etc/frontend

    Now add the below code:

    <?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="MagentoTaxObserverUpdateProductOptionsObserver" type="MagemonkeyPriceAdjustmentObserverUpdateProductOptionsObserver" />
    </config>

    Step 2: Next, you need to add module.xml file in the following path:

    app/code/Magemonkey/PriceAdjustment/etc

    Add the below code:

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
        <module name="Magemonkey_PriceAdjustment" setup_version="1.0.0">
            <sequence>
                <module name="Magento_Tax"/>
            </sequence>
        </module>
    </config>

    Step 3: Now you need to add registration.php file in the following path:

    app/code/Magemonkey/PriceAdjustment

    Add the below code:

    <?php
    MagentoFrameworkComponentComponentRegistrar::register(
        MagentoFrameworkComponentComponentRegistrar::MODULE,
        'Magemonkey_PriceAdjustment',
        __DIR__
    );

    Step 4: Lastly, you need to add the UpdateProductOptionsObserver.php file in the following path:

    app/code/Magemonkey/PriceAdjustment/Observer

    And add the below code:

    <?php
    namespace MagemonkeyPriceAdjustmentObserver;
    
    use MagentoFrameworkEventObserverInterface;
    
    class UpdateProductOptionsObserver extends MagentoTaxObserverUpdateProductOptionsObserver
    {
        /**
         * Tax data
         *
         * @var MagentoTaxHelperData
         */
        protected $taxData;
    
        /**
         * @var MagentoFrameworkRegistry
         */
        protected $registry;
    
        /**
         * @param MagentoTaxHelperData $taxData
         * @param MagentoFrameworkRegistry $registry
         */
        public function __construct(
            MagentoTaxHelperData $taxData,
            MagentoFrameworkRegistry $registry
        ) {
            $this->taxData = $taxData;
            $this->registry = $registry;
        }
    
        /**
         * Change default JavaScript templates for options rendering
         *
         * @param MagentoFrameworkEventObserver $observer
         * @return $this
         */
        public function execute(MagentoFrameworkEventObserver $observer)
        {
            $response = $observer->getEvent()->getResponseObject();
            $options = $response->getAdditionalOptions();
    
            $_product = $this->registry->registry('current_product');
            if (!$_product) {
                return $this;
            }
    
            $algorithm = $this->taxData->getCalculationAlgorithm();
            $options['calculationAlgorithm'] = $algorithm;
            // prepare correct template for options render
            if ($this->taxData->displayBothPrices()) {
                $options['optionTemplate'] = sprintf(
                    '<%%= data.label %%>'
                    . '<%% if (data.finalPrice.value) { %%>'
                    . ' +<%%= data.basePrice.formatted %%> (%1$s <%%= data.finalPrice.formatted %%>)'
                    . '<%% } %%>',
                    __('Incl. tax:')
                );
            } elseif ($this->taxData->priceIncludesTax() && $this->taxData->displayPriceExcludingTax()) {
                $options['optionTemplate'] = sprintf(
                    '<%%= data.label %%>'
                    . '<%% if (data.basePrice.value) { %%>'
                    . ' +<%%= data.basePrice.formatted %%>'
                    . '<%% } %%>'
                );
            }
    
            $response->setAdditionalOptions($options);
            return $this;
        }
    }

     

    Magento 2 add the product description or custom attribute in order email

    Override the vendor/magento/module-sales/view/frontend/templates/email/items/order/default.phtml file on your theme and add the below code.

    <?php
    /**
     * Copyright © Magento, Inc. All rights reserved.
     * See COPYING.txt for license details.
     */
    
    // phpcs:disable Magento2.Templates.ThisInTemplate
    
    /** @var $block MagentoSalesBlockOrderEmailItemsDefaultItems */
    
    /** @var $_item MagentoSalesModelOrderItem */
    $_item = $block->getItem();
    $_order = $_item->getOrder();
    $objectManager = MagentoFrameworkAppObjectManager::getInstance();
    $product_id = $_item->getProduct()->getId();
    $product = $objectManager->create('MagentoCatalogModelProduct')->load($product_id);
    $optionId = $product->getCustomAttr();
    $optionText = '';
    $attr = $product->getResource()->getAttribute('custom_attr');
     if ($attr->usesSource()) {
           $optionText = $attr->getSource()->getOptionText($optionId);
     }
    ?>
    <tr>
        <td class="item-info<?= ($block->getItemOptions() ? ' has-extra' : '') ?>">
            <p class="product-name"><?= $block->escapeHtml($_item->getName()) ?></p>
            <p class="sku" style="font-size: 11px;"><strong><?=$block->escapeHtml(__('SKU')) ?>:</strong><?=$block->escapeHtml($block->getSku($_item)) ?></p>
            <p class="description" style="font-size: 11px;"><strong><?=$block->escapeHtml(__('Description')) ?>:</strong><?php echo $product->getShortDescription(); ?></p>
            <?php if($optionText){ ?>
            <p class="custom-attr" style="font-size: 11px;"><strong><?=$block->escapeHtml(__('Custom Attribute')) ?>:</strong><?=$block->escapeHtml($optionText) ?></p>
            <?php } ?>
    
    
            <?php if ($block->getItemOptions()) : ?>
                <dl class="item-options">
                <?php foreach ($block->getItemOptions() as $option) : ?>
                    <dt><strong><em><?= $block->escapeHtml($option['label']) ?></em></strong></dt>
                    <dd>
                        <?= /* @noEscape */  nl2br($block->escapeHtml($option['value'])) ?>
                    </dd>
                <?php endforeach; ?>
                </dl>
            <?php endif; ?>
            <?php $addInfoBlock = $block->getProductAdditionalInformationBlock(); ?>
            <?php if ($addInfoBlock) :?>
                <?= $addInfoBlock->setItem($_item)->toHtml() ?>
            <?php endif; ?>
            <?= $block->escapeHtml($_item->getDescription()) ?>
        </td>
        <td class="item-qty"><?= (float) $_item->getQtyOrdered() ?></td>
        <td class="item-price">
            <?= /* @noEscape */ $block->getItemPrice($_item) ?>
        </td>
    </tr>
    <?php if ($_item->getGiftMessageId()
        && $_giftMessage = $this->helper(MagentoGiftMessageHelperMessage::class)
            ->getGiftMessage($_item->getGiftMessageId())
    ) : ?>
        <tr>
        <td colspan="3" class="item-extra">
            <table class="message-gift">
                <tr>
                    <td>
                        <h3><?= $block->escapeHtml(__('Gift Message')) ?></h3>
                        <strong><?= $block->escapeHtml(__('From:')) ?></strong> <?= $block->escapeHtml($_giftMessage->getSender()) ?>
                        <br /><strong><?= $block->escapeHtml(__('To:')) ?></strong> <?= $block->escapeHtml($_giftMessage->getRecipient()) ?>
                        <br /><strong><?= $block->escapeHtml(__('Message:')) ?></strong>
                        <br /><?= $block->escapeHtml($_giftMessage->getMessage()) ?>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
    <?php endif; ?>

     

     

    Magento 2: How to set load custom font as preload?

    Generally, if you load font as preload, it will load first and it will help to increase site speed.

    So If you want to add custom font as preload, you need to perform settings as shown below:

    The first step is to set your font .woff or .woff2 file in your theme web/fonts folder.

    Then after you need to set that font in between head like below in default.xml layout file.

    <?xml version="1.0"?>
    <!--
    /**
    * Copyright © Magento, Inc. All rights reserved.
    * See COPYING.txt for license details.
    */
    -->
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
    <font src="fonts/custom-font.woff2"/>
    </head>
    </page>

    Magento 2 convert registered customer order to guest order after placing order

    create the event.xml on your module under the Vendor/Module/etc/event.xml and add the below code

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
        <event name="checkout_submit_all_after">
            <observer name="checkout_order_place_after" instance="VendorModuleObserverPlaceAfter" />
        </event>
    </config>

    create the PlaceAfter.php on your module under the Vendor/Module/Observer/PlaceAfter.php and add the below code

    <?php
    
    namespace VendorModuleObserver;
    
    use MagentoFrameworkEventObserverInterface;
    use MagentoFrameworkEventObserver as EventObserver;
    use PsrLogLoggerInterface;
    use MagentoSalesApiOrderRepositoryInterface;
    
    
    class PlaceAfter implements ObserverInterface
    {
    
        protected $_customerSession;
        /**
         * @var OrderRepositoryInterface
         */
        protected $orderRepository;
        /**
         * @var LoggerInterface
         */
        protected $logger;
        /**
         * @var MagentoSalesModelOrderFactory
         */
        protected $orderModel;
        /**
         * @var MagentoSalesModelOrderEmailSenderOrderSender
         */
        protected $orderSender;
    
        /**
         * @param MagentoSalesModelOrderFactory $orderModel
         * @param MagentoSalesModelOrderEmailSenderOrderSender $orderSender
         * @param MagentoCheckoutModelSession $checkoutSession
         *
         * @codeCoverageIgnore
         */
        public function __construct(
            MagentoSalesModelOrderFactory $orderModel,
            LoggerInterface $logger,
            MagentoSalesModelOrderEmailSenderOrderSender $orderSender,
            MagentoCustomerModelSession $customerSession,
            OrderRepositoryInterface $orderRepository,
            MagentoSalesApiDataOrderInterface $orderData
        )
        {
            $this->logger = $logger;
            $this->orderModel = $orderModel;
            $this->orderSender = $orderSender;
            $this->_customerSession = $customerSession;
            $this->orderRepository = $orderRepository;
            $this->orderData = $orderData;
        }
    
        /**
         * @param MagentoFrameworkEventObserver $observer
         * @return void
         */
        public function execute(MagentoFrameworkEventObserver $observer)
        {
            $order = $observer->getEvent()->getOrder();
            $orderId = $order->getEntityId();
            $this->logger->info(print_r($orderId,true));
            $guestemail = "test@gmail.com";
            
            $comment = sprintf(
                __("%s customer order converted to : %s guest user"),
                $order->getCustomerEmail(),$guestemail
            );
            $order->addStatusHistoryComment($comment);
            $order->setCustomerId(null);
            $order->setCustomerIsGuest(1);
            $order->setCustomerEmail($guestemail);
            $this->orderRepository->save($order);
    
            $order->setCanSendNewEmailFlag(true);
            $order->save();
            $this->_customerSession->setForceOrderMailSentOnSuccess(true);
            $this->orderSender->send($order);
            
            return $this;
        }
    }

     

    Magento 2 : How to add custom meta tag in product view page?

    If you need a custom meta tag for a specific product page in Magento 2

    Step 1: Go to the below-given path.

    appdesignfrontendMagemonkeysCustomthemeMagento_Cataloglayoutcatalog_product_view.xml

    <?xml version="1.0"?>
    <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <body>
            <referenceBlock name="head.additional">
                <block class="MagentoCatalogBlockProductView" name="meta_type_name" template="Magento_Catalog::product/view/custom_meta_name.phtml" />
            </referenceBlock>
         </body>
    </page>

    Step 2: Create a file named custom_meta_name.phtml at the following path

    appdesignfrontendMagemonkeysCustomthemeMagento_Catalogtemplatesproductview

    Finally, add the below code

    <meta property="og:your_custom_tag_name" content="your_custom_value" />

     

     

    Magento 2: How to auto clear cache product or any admin configuration?

    This article is a catch if you want to clean cache automatically after any admin configuration or product save.

    Follow below two steps to get it done.

    1. Create file event.xml on app/code/Magemonkeys/AutoFlushCache/etc

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
        <event name="controller_action_postdispatch_adminhtml_system_config_save">
            <observer name="auto_flush_cache" instance="MagemonkeysAutoFlushCacheObserverFlushCache"/>
        </event>
    </config>

    2. Create file FlushCache.php on app/code/Magemonkeys/AutoFlushCache/Observer

    <?php
    namespace MagemonkeysAutoFlushCacheObserver;
    
    class FlushCache implements MagentoFrameworkEventObserverInterface
    {
        public function __construct(MagentoFrameworkAppCacheTypeListInterface $cacheTypeList, MagentoFrameworkAppCacheFrontendPool $cacheFrontendPool)
        {
            $this->cacheTypeList = $cacheTypeList;
            $this->cacheFrontendPool = $cacheFrontendPool;
        }
    
        public function execute(MagentoFrameworkEventObserver $observer)
        {
            $types = array(
                'config',
                'layout',
                'block_html',
                'collections',
                'reflection',
                'db_ddl',
                'eav',
                'config_integration',
                'config_integration_api',
                'full_page',
                'translate',
                'config_webservice'
            );
            foreach ($types as $type)
            {
                $this->cacheTypeList->cleanType($type);
            }
            foreach ($this->cacheFrontendPool as $cacheFrontend)
            {
                $cacheFrontend->getBackend()->clean();
            }
        }
    }

     

    Magento 2: Set maxlength on street address field on checkout page

    If you want to add maxlength on the checkout street address field then you need to override on file in your theme

    <vendername>/<theme_name>/Magento_Ui/web/templates/form/element/input.html

    Make the above file & add the below code inside it

    <!--
    /**
    * Copyright © Magento, Inc. All rights reserved.
    * See COPYING.txt for license details.
    */
    -->
    <input class="input-text" type="text" data-bind="
    value: value,
    valueUpdate: 'keyup',
    hasFocus: focused,
    attr: {
    name: inputName,
    placeholder: placeholder,
    'aria-describedby': getDescriptionId(),
    'aria-required': required,
    'aria-invalid': error() ? true : 'false',
    id: uid,
    disabled: disabled,
    maxlength: inputName.slice(0,6) === 'street' ? 35 : 'none'
    }" />

    Note: We have tried this in Magento 2.3.7 version, If your version different then take copy this file from the vendor and add the last maxlength

    How to solve font error like ‘downloadable font: rejected by sanitizer’ in Magento 2?

    If you have faced below font related error in browser console,

    downloadable font: rejected by sanitizer (font-family: “Sofia Pro Regular” style:normal weight:400 stretch:100 src index:0) source: ../../../../../../en_US/fonts/SofiaProRegular.woff2 in magento 2

    Then follow given step-by-step guide to solve the error.

    Step 1: First check used fonts related ttf, woff and woff2 files. It must be available in the font folder with the same name.

    E.g.

    - app/design/frontend/Magemonkey/YourTheme/web/fonts/SofiaProRegular.ttf
    
    - app/design/frontend/Magemonkey/YourTheme/web/fonts/SofiaProRegular.woff
    
    - app/design/frontend/Magemonkey/YourTheme/web/fonts/SofiaProRegular.woff2

     

    Step 2 : Open below file

    app/design/frontend/Magemonkey/YourTheme/web/css/source/_typography.less

    Step 3 : Add below mention line under font path in _typoraphy.less

    E.g. @font-format: ‘woff’,

    See below code after adding above mention line and it should look like below

    .lib-font-face(
        @family-name: 'Sofia Pro Regular',
        @font-path: '@{baseDir}fonts/SofiaProRegular',
        @font-format: 'woff',                             // Add this line for remove above font related error
        @font-weight: 400,
        @font-style: normal,
        @font-display:swap
    );

     

    Step 4: After placing the above code, please run the below-mentioned commands

    - php bin/magento setup:upgrade
    
    - php bin/magento setup:static-content:deploy -f
    
    - php bin/magento cache:clean

    That’s it…

    Now refresh your site and check the console for this font-related error. Your font error should be solved.