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.

    How to Add Colour Picker in Magento 2 System Configuration?

    Le’ts add a color picker to textbox through system.xml file located at
    appcodeVendorExtensionetcadminhtml

    <system>
    	<section>
        	<group id="my_color_group" ...>
            	<field id="my_color_option" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Background Color</label>
                    <comment><![CDATA[Background color]]></comment>
                    <frontend_model>VendorExtensionBlockColor</frontend_model>                     
                </field>
        	</group>
    	</section>
    </system>

    Now we have to create one Color.php file at below location under the hood of extension
    appcodeVendorExtensionBlock

    <?php
    namespace VendorExtensionBlock; 
    class Color extends MagentoConfigBlockSystemConfigFormField { 
    	public function __construct(
        MagentoBackendBlockTemplateContext $context, array $data = []
    	) {
            parent::__construct($context, $data);
    	}
     
    	protected function _getElementHtml(MagentoFrameworkDataFormElementAbstractElement $element) {
        	$html = $element->getElementHtml();
        	$value = $element->getData('value');
     
        	$html .= '<script type="text/javascript">
                require(["jquery","jquery/colorpicker/js/colorpicker"], function ($) {
                    $(document).ready(function () {
                    	var $el = $("#' . $element->getHtmlId() . '");
                        $el.css("backgroundColor", "'. $value .'");
     
                    	// Attach the color picker
                        $el.ColorPicker({
                        	color: "'. $value .'",
                            onChange: function (hsb, hex, rgb) {
                                $el.css("backgroundColor", "#" + hex).val("#" + hex);
                        	}
                    	});
                	});
            	});
    	        </script>';
        	return $html;
    	}
     
    }

     

    We need to implement JavaScript color picker library to adminhtml_system_config_edit.xml file available at appcodeVendorExtensionviewadminhtmllayout

    <?xml version="1.0" encoding="UTF-8"?>
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
    	<head>
        	<css src="jquery/colorpicker/css/colorpicker.css"/>
        	<link src="jquery/colorpicker/js/colorpicker.js"/>
    	</head>
    </page>

     

    Magento 2: How to Create Customers Programmatically?

    Check the following root script to create customer programmatically:

    use MagentoFrameworkAppBootstrap;
     
    require 'app/bootstrap.php';
    $bootstrap = Bootstrap::create(BP, $_SERVER);
    $objectManager = $bootstrap->getObjectManager();
    $state = $objectManager->get('MagentoFrameworkAppState');
    $state->setAreaCode('frontend');
     
     
    $storeManager = $objectManager->get('MagentoStoreModelStoreManagerInterface');
    $storeId = $storeManager->getStore()->getId();
     
    $websiteId = $storeManager->getStore($storeId)->getWebsiteId();
     
    try {
        $customer = $objectManager->get('MagentoCustomerApiDataCustomerInterfaceFactory')->create();
        $customer->setWebsiteId($websiteId);
        $email = 'ex00@example.com';
        $customer->setEmail($email);
        $customer->setFirstname("example first");
        $customer->setLastname("example last");
        $hashedPassword = $objectManager->get('MagentoFrameworkEncryptionEncryptorInterface')->getHash('MyNewPass', true);
     
        $objectManager->get('MagentoCustomerApiCustomerRepositoryInterface')->save($customer, $hashedPassword);
     
        $customer = $objectManager->get('MagentoCustomerModelCustomerFactory')->create();
        $customer->setWebsiteId($websiteId)->loadByEmail($email);
    } catch (Exception $e) {
        echo $e->getMessage();
    }

    Run the above script code in a loop and create multiple customers at a time, by changing the email ID every time.

    That’s it!

    Magento 2 CSS inlining error: DOMXPath::query() Invalid expression in selector in all email sent

    In some versions of Magento 2 we are facing issues like this where error occurs in all sent mails.

    I tried so many solutions related .less file also tried adding “pelago/emogrifier”: “1.0.0 as 0.1.1” in our root composer.json

    But it never worked out. If you wish, you can try it and check. In case, if you get negative signal, try below proven method which helped me.

    Go to Admin Marketing Menu – Email Templates and add new custom template then click on Load template button and load Magento_Email – Header

    After load that template content remove below line and save it,

    {{inlinecss file="css/email-inline.css"}}

    This one works in most of the cases. It worked for me in Magento 2.3 versions, Hope this will help you to solve the error.

    How to get drop-down attribute values in Magento 2?

    Sometime we customise code , so we need to get drop-down attribute values in custom file.

    So the below code will help to retrieve attribute based on attribute id

    $objectManager = MagentoFrameworkAppObjectManager::getInstance();
    $attributeId = 101;
    $eavModel = $objectManager->create('MagentoCatalogModelResourceModelEavAttribute');
    $eavModel->load($attributeId);
    $attributeCode = $eavModel->getAttributeCode();
    $productAttributeRepository = $objectManager->create('MagentoCatalogModelProductAttributeRepository');
    $options = $productAttributeRepository->get($attributeCode)->getOptions();
    
    
    ?>
    
    <div class="field required">
        <label class="label"><?= /* @escapeNotVerified */ __('Colour') ?>:</label>
    <div class="control">
    <select name="product[color]" id="color" class="required-entry input-text">
    <?php
    foreach ($options as $option) {
        $value = $option->getValue();  // Value
        $label = $option->getLabel();  // Label              
        ?>
        <option value="<?php echo $value; ?>"><?php echo $label; ?></option>
        <?php 
    } ?>
    </select>
    </div>
    </div>

    that’s it. Happy coding.

    Generate Invoice for the orders via Cronjob

    One of our client came up with a requirement where he adjusted payment type as authorize along with new orders to be placed as processing status.

    Our work was to do execute cronjob such a way that it generates an invoice and capture the payment under technical limitation capped by client.

    To execute the job we created a cronjob & set it at every minute.

    Have a look on step-by-step explaination.

    Step 1:  We create a crontab.xml in module at app/code/Magemonkeys/Generateinvoice/etc/crontab.xml and add the following code in the XML.

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
        <group id="default">
            <job name="magemonkeys_generateinvoice_programmatically" instance="MagemonkeysGenerateinvoiceCronInvoicegenerate" method="execute">
                <schedule>* * * * *</schedule>
            </job>
        </group>
    </config>
    

    Step 2: Then, we create an Invoicegenerate.php at app/code/Magemonkeys/Generateinvoice/Cron/Invoicegenerate.php and add the following code in this file.

    <?php
    
    namespace MagemonkeysGenerateinvoiceCron;
    
    use MagentoFrameworkExceptionLocalizedException;
    
    class Invoicegenerate
    {
        /**
         * @var MagentoSalesApiOrderRepositoryInterface 
         */
        private $_orderRepository;
    
        /**
         * @var MagentoSalesModelServiceInvoiceService 
         */
        private $_invoiceService;
    
        /**
         * @var MagentoFrameworkDBTransactionFactory 
         */
        private $_transactionFactory;
    
        /**
         * @var MagentoSalesModelOrderEmailSenderInvoiceSender 
         */
        private $_invoiceSender;
    
        /**
         * @var MagentoSalesModelResourceModelOrderCollectionFactory 
         */
        private $_orderCollectionFactory;
    
        public function __construct(
            MagentoSalesApiOrderRepositoryInterface $orderRepository,
            MagentoSalesModelServiceInvoiceService $invoiceService,
            MagentoFrameworkDBTransactionFactory $transactionFactory,
            MagentoSalesModelOrderEmailSenderInvoiceSender $invoiceSender,
            MagentoSalesModelResourceModelOrderCollectionFactory $orderCollectionFactory
        )
        {
            $this->_orderRepository = $orderRepository;
            $this->_invoiceService = $invoiceService;
            $this->_transactionFactory = $transactionFactory;
            $this->_invoiceSender = $invoiceSender;
            $this->_orderCollectionFactory = $orderCollectionFactory;
        } 
    
        public function execute()
        {
    
            $orderCollection = $this->_orderCollectionFactory->create()
                ->addAttributeToSelect('*')
                ->addFieldToFilter('status', 'processing');
    
            $objectManager = MagentoFrameworkAppObjectManager::getInstance();
            $logger = $objectManager->get("PsrLogLoggerInterface");
            
            foreach ($orderCollection as $order) {
                if($order->hasInvoices()) { 
                    $logger->info('Order #'.$order->getId().' has already been invoiced.'); 
                    continue;
                }
    
                
                $payment = $order->getPayment();
                $method = $payment->getMethodInstance();
                $methodTitle = $method->getTitle();
                if(strtolower($methodTitle) == 'credit card'){
                    try {
                        
                        $order = $this->_orderRepository->get($order->getId());
    
                        if (!$order->getId()) {
                            $logger->info('Order #'.$order->getId().' no longer exists.'); 
                            continue;
                        }
    
                        if(!$order->canInvoice()) {
                            $logger->info('Order #'.$order->getId().' does not allow an invoice to be created.');
                            continue;
                        }
    
                        $invoice = $this->_invoiceService->prepareInvoice($order);
                        
                        if (!$invoice) {
                            $logger->info("Order #".$order->getId()." can't save the invoice right now.");
                            continue;
                        }
                        
                        if (!$invoice->getTotalQty()) {
                            $logger->info("Order #".$order->getId()." create an invoice without products.");
                            continue;
                        }
    
                        $invoice->setRequestedCaptureCase(MagentoSalesModelOrderInvoice::CAPTURE_ONLINE);
                        $invoice->register();
                        $invoice->getOrder()->setCustomerNoteNotify(false);
                        $invoice->getOrder()->setIsInProcess(true);
                        $order->addStatusHistoryComment('Automatically INVOICED', false);
                        $transactionSave = $this->_transactionFactory->create()->addObject($invoice)->addObject($invoice->getOrder());
                        $transactionSave->save();
    
                        // send invoice emails
                        try {
                            $this->_invoiceSender->send($invoice);
                            $logger->info("Order #".$order->getId()." - Invoice has been created successfully.");
                        } catch (Exception $e) {
                            $logger->info("Order #".$order->getId()." - We can't send the invoice email right now.");
                        }
                    } catch (Exception $e) {
                        
                       $logger->info($e->getMessage());
                    }
                }
            }
        }
    }
    

     

    Add Product Custom Option Programmatically Magento2

    We will use the event catalog_product_save_before to create product custom option programmatically in magento2.

    <?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="catalog_product_save_before">
            <observer name="magemonkeys_customoption_add_custom_option" instance="MagemonkeysCustomoptionObserverCatalogProductSaveBeforeObserver"/>
        </event>
    </config>

    In our CatalogProductSaveBeforeObserver class we get the product object. We have to check if the custom option with name “Custom Option” and type field already exists.

    If not existed, we have to create an array with the options to be created.

    <?php
    
    namespace MagemonkeysCustomoptionObserver;
    
    use MagentoFrameworkEventObserverInterface;
    use MagentoCatalogApiDataProductCustomOptionInterface;
    use MagentoCatalogModelProductOptionFactory;
    
    class CatalogProductSaveBeforeObserver implements ObserverInterface
    {
        /**
         * @var OptionFactory
         */
        protected $productOptionFactory;
    
        /**
         * Catalog Product After Save constructor.
         * @param OptionFactory $productOptionFactory
         */
        public function __construct(
            OptionFactory $productOptionFactory
        ) {
            $this->productOptionFactory = $productOptionFactory;
        }
    
        /**
         * Catalog Product Before Save
         *
         * @param MagentoFrameworkEventObserver $observer
         * @return void
         */
        public function execute(MagentoFrameworkEventObserver $observer)
        {
            $product = $observer->getEvent()->getProduct();
    
            $exist = false;
            //check if the custom option exists
            foreach ($product->getOptions() as $option) {
                if ($option->getGroupByType() == ProductCustomOptionInterface::OPTION_TYPE_FIELD
                    && $option->getTitle() == 'Custom Option') {
                    $exist = true;
                }
            }
    
            if (!$exist) {
                try {
                    $optionArray = [
                        'title' => 'Custom Option',
                        'type' => 'field',
                        'is_require' => false,
                        'sort_order' => 1,
                        'price' => 0,
                        'price_type' => 'fixed',
                        'sku' => '',
                        'max_characters' => 0
                    ];
                    $option = $this->productOptionFactory->create();
                    $option->setProductId($product->getId())
                        ->setStoreId($product->getStoreId())
                        ->addData($optionArray);
                    $product->addOption($option);
                } catch (Exception $e) {
                    //throw new CouldNotSaveException(__('Something went wrong while saving option.'));
                }
            }
        }
    }

     

    How to get configurable product children ids Magento 2?

    To get all the children product ids from the configurable product in Magento 2, you need to retrieve the list of child item ids by the configurable product id.

    <?php
    namespace MagemonkeysChildIdsModel;
    
    use MagentoConfigurableProductModelProductTypeConfigurable;
    
    class ConfigurableChildrenIds
    {    
        private $configurable;
        public function __construct(
            Configurable $configurable
        ) {
            $this->configurable = $configurable;
        }
        
        public function getChildrenIds(int $id)
        {
            $childItemId = $this->configurable->getChildrenIds($id);
            return $childItemId;
        }
    } ?>
    

    List out the children items id for a configurable product by using below commands.

    $configurableId = 1478;
    $superAttributeByChild = $this->getChildrenIds($configurableId);

     

    How to show sub category image with sub category name on list page in Magento 2?

    If you want to show sub category image with sub category name of current category page then follow below process.

    Get subcategory of current category

    Step 1 : create sub-category.phtml file under ../app/design/frontend/[VendorName]/[theme]/Magento_Catalog/templates/category/

    and paste below code inside it

    <?php
        $objectManager = MagentoFrameworkAppObjectManager::getInstance();
        $category = $objectManager->get('MagentoFrameworkRegistry')->registry('current_category');    //get current category
        $subcategories = $category->getChildrenCategories();
        $_helper = $this->helper('MagentoCatalogHelperOutput');
    ?>
    
    <ul class="sub-category">
        <?php
        foreach ($subcategories as $sub_category) {
                $_category = $objectManager->create('MagentoCatalogModelCategory')->load($sub_category->getId());
                $_outputhelper = $this->helper('MagentoCatalogHelperOutput');
                $subcategoryurl = $sub_category->getUrl();            
                $catimgHtml = '';
                echo '<li>';
                if ($catimgUrl = $_category->getImageUrl()) {
                    $catimgHtml = '<img src="' . $catimgUrl . '" />';
                    $catimgHtml = $_outputhelper->categoryAttribute($_category, $catimgHtml, 'image');
                    /* @escapeNotVerified */
                    echo '<a href="' . $subcategoryurl . '" title="' . $sub_category->getName() . '">' . $catimgHtml . '</a>';
                }
                echo '<h2><a href="' . $subcategoryurl . '" title="' . $sub_category->getName() . '">' . $sub_category->getName() . '</a></h2>';
                echo '</li>';
        } ?>
    </ul>

     

    Step 2 : Add below mention code in ../app/design/frontend/[VendorName]/[theme]/Magento_Catalog/layout/catalog_category_view.xml

    <referenceContainer name="columns.top">
        <!-- Add this below code -->
        <container name="category.view.customcatlink" htmlTag="div" htmlClass="custom-category-link" before="category.view.container">
            <block class="MagentoCatalogBlockCategoryView" name="custom.category.links" template="Magento_Catalog::category/custom-cat-links.phtml"/>
        </container>

     

    After that run below commands

    – php bin/magento setup:upgrade
    – php bin/magento setup:di:compile
    – php bin/magento cache:clean

    That’s it.

    Now, sub category image with sub category name will show on list page.