Wednesday, 30 September 2020

 

How to Upgrade magento version from 2.3.x [EE] to 2.3.x [EE]



Here are the steps I used to successfully update Magento 2.3.3 [EE] to 2.3.5 [EE] I have divided the steps into parts:

Here are the steps to upgrade Magento 2.3.x to 2.3.x

Upgrade Magento 2 using composer: –

  • Backup code and database
  • Backup the composer.json & index.php file.
  • cp composer.json composer.json.bak
  • cp index.php index.php.bak
  • php bin/magento deploy:mode:set developer
  • php bin/magento cache:disable
  • php bin/magento maintenance:enable
  • composer require magento/product-enterprise-edition=2.3.5 –no-update

–> Message : ./composer.json has been updated.

  • composer update

–> PHP Fatal error:

Uncaught Error: Undefined class constant ‘PRE_COMMAND_RUN’ in /var/www/html/m23x/ontime/vendor/laminas/laminas-dependency-plugin/src/DependencyRewriterPlugin.php:63

–> composer –version

–> Solution:

  • It’s just because of the composer’s old version, you need to install the new version (composer version >= Composer 1.9.1)
  • composer update
  • rm -rf var/cache/* var/page_cache/* generated/code/*
  • php bin/magento setup:upgrade

Error: Element ‘route’: Missing child element(s). Expected is ( resources ).

Solution: Magento_MysqlMq [disable this module]

  • php bin/magento setup:di:compile

Errors:

  1. Fatal error: Declaration of

Magento\PageBuilder\Model\Dom\NodeList::item($index): ?Magento\PageBuilder\Model\Dom\Adapter\ElementInterface must be compatible with Magento\PageBuilder\Model\Dom\Adapter\NodeListInterface::item(int $index): ?Magento\PageBuilder\Model\Dom\Adapter\ElementInterface in /var/www/html/m23x/ontime/vendor/magento/module-page-builder/Model/Dom/NodeList.php on line 19

Solution:

vendor/magento/module-page-builder/Model/Dom/NodeList.php (On line 47 change as follows) public function item(int $index): ?ElementInterface

  • php bin/magento cache:enable
  • php bin/magento maintenance:disable
  • php bin/magento deploy:mode:set production –skip-compilation
  • service varnish restart [If you use Varnish for page caching, restart it.]
  • php bin/magento indexer:reindex && php bin/magento cache:clean && php bin/magento cache:flush

SUCCESSFULLY UPGRADED – MAGENTO 2.3.3 To MAGENTO 2.3.5 [EE]

replace OLD index.php file

  • rm -rf var/cache/* var/view_preprocessed/* generated/* pub/static/*
  • php bin/magento setup:upgrade
  • php bin/magento setup:di:compile
  • php bin/magento setup:static-content:deploy -f

You may face the below issue at the time of deploying.

1) Error:

The contents from the “/var/www/html/pub/static/adminhtml/Magento/backend/en_US/requirejs-min-resolver.min.js” file can’t be read. Warning!

file_get_contents(/var/www/html/pub/static/adminhtml/Magento/backend/en_US/requirejs-min-resolver.min.js): failed to open stream: No such file or directory.

Solution: Disable Minify CSS / JS OR JS/CSS Merge

  • php bin/magento config:set dev/js/merge_files 0
  • php bin/magento config:set dev/js/enable_js_bundling 0
  • php bin/magento config:set dev/js/minify_files 0
  • php bin/magento config:set dev/css/merge_css_files 0
  • php bin/magento config:set dev/css/minify_files 0

++++++++++++++++++++++++++

  • php bin/magento indexer:reindex && php bin/magento c:c && php bin/magento c:f
  • chmod -R 777 var/ generated/ pub/static/
  • service varnish restart

+++++++++++++++++++++++

Checkout page errors:–

  1. Magento 2.3.4 Checkout Infinite loop detected.

Infinite loop detected, review the trace for the looping path.

Bug in Code File of 2.3.5

Message:

vendor/magento/module-checkout/Model/Session.php line 240 code is a bug On line 240 we have the code: if ($this->isLoading) { … which throw this exception. The private member $isLoading is set to false by default and is only set to true on line number 243 in the Session.php the code will never reach this line as the Quote is not already created and need to be created at line number 244 but we are throwing an error on line 241 which breaks the script. No matter what we select in the payment method the code always breaks.

Temp Solution:

vendor/magento/module-checkout/Model/Session.php Try to replace this file with version 2.3.3 and try to checkout again.

+++++++++++

Note: Vendor file changes as follows below.

vendor/magento/module-checkout/Model/Session.php

vendor/magento/module-page-builder/Model/Dom/NodeList.php


Thursday, 4 June 2020

HOW TO CREATE A CUSTOM THEME IN MAGENTO 2

Here Are The List Of Steps You Need To Follow For A Custom Theme Development:

  1. Create a directory for the theme

  2. Add a declaration for theme

  3. Add a composer.json file

  4. Add registration.php

  5. Create directories for CSS, JavaScript, images, and fonts

  6. Configure your theme in the Admin panel

  7. Final Deployment

 

Requirements For Theme Development

It is also very important to check whether your server meets the minimal Magento 2 requirements:

Apache: 2.2 or 2.4

PHP: 5.5.x or 5.6.x

MySQL: 5.6.x

Also, we assume that you have some knowledge of Magento 2 and Magento 2 is installed on your server as well as on your local computer to test this new theme development.

 

1. Create a directory for the theme

Go to: <your Magento 2 root directory>/app/design/frontend and create a new directory with the vendor name you want for theme package,

For example I have used name here : /app/design/frontend/Akshaweb 

Now in your vendor directory, create your theme directory, for example – Mytheme:

/app/design/frontend/Akshaweb/Mytheme/

 

2. Add a declaration for theme

Once you have created directory structure of your theme, now we have to declare that theme by creating theme.xml file to declare it.

theme.xml defines basic theme configuration, including at least the title and usually the parent theme that’s being extended.

Create the theme.xml file under app/design/frontend/Akshaweb/Mytheme/theme.xml and use the code below:

<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
  <title>Mytheme</title>
  <parent>Magento/Luma</parent>
  <media>
     <preview_image>media/mytheme-theme-image.jpg</preview_image>
  </media>
</theme>

3. Add a composer.json file

To distribute your theme as a package, add a composer.json file to the theme directory and register the package on a packaging server. 

app/design/frontend/Akshaweb/Mytheme/composer.json to register the package on a packaging server. This file is provided in the theme dependency information.



{
    "name": "Akshaweb/Mytheme",
    "description": "N/A",
    "require": {
        "php": "~5.5.0|~5.6.0|~7.0.0",
        "Akshaweb/Mytheme": "100.0.*",
        "magento/framework": "100.0.*"
    },
    "type": "magento2-theme",
    "version": "100.0.1",
    "license": [
        "OSL-3.0",
        "AFL-3.0"
    ],
    "autoload": {
        "files": [
            "registration.php"
        ]
    }
}

4. Add registration.php

To register your theme in the Magento system, you need to create registration.php file in your theme directory: app/design/frontend/Akshaweb/Mytgeme/registration.php and use the following code in your registration.php:

Code:

<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::THEME,
'frontend/<Akshaweb>/<Mytheme>',
 __DIR__
);

5. Create directories for CSS, JavaScript, images, and fonts

Theme package consists of many types of files: styles, fonts, JavaScript and images. Each one have to be stored in its own sub-directory of web in theme directory:


Tip:

In Magento 2, theme or extension development, when you update any files in app/design/frontend/Akshaweb/Mytheme/web folder, you have two static folders which are located at pub/static and var/view_preprocessed. You will need to compile and recreate static files, otherwise, you will see there is still no change in frontend.

 

Directory Structure in Magento 2 Theme Development

At this point you can see how your theme directory should look like. I am using my own Vendor and directory name.

 

app/design/frontend/Mycompany/


├── default/
│   ├── etc/
│   │   ├── view.xml
│   ├── web/
│   │   ├── images/
│   │   │   ├── logo.svg
│   │   ├── css/
│   │   │   ├── source/
│   │   │   │   ├── _theme.less
│   │   ├── fonts/
│   │   ├── js/
│   ├── registration.php
│   ├── theme.xml
│   ├── composer.json

6. Configure your theme in the Admin panel

 

Step 1:  Go to Magento 2 backend, then go to Content > Design > Themes. And make sure your theme appears on this list.

Step 2:  Go to  Store => Configuration => Design => Choose your newly created theme from those shown in the image below.

Step 3:  Select Mytheme from the Applied Theme drop down menu and click on Save Configuration.

After you select your theme, click on the “Save Config” button.

Clear the cache.

 

7. Final Deployment

Open the SSH terminal and go to the root directory of your Magento 2. Now run all these commands one by one:


rm -rf var/di/* var/generation/* var/cache/* var/log/* var/page_cache/* var/session/* var/view_preprocessed/* pub/static/*
php bin/magento setup:upgrade
php bin/magento setup:db-schema:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy
php bin/magento indexer:reindex
php bin/magento cache:clean
php bin/magento cache:flush 

Magento2 get cart and checkout link in block or phtml

Magento2 get cart and checkout link in block or phtml

In Magento2 get cart and checkout link in block or phtml then you need to call getUrl() method.It is every easy to get those url at Phtml or block class.

Also, there is no need to write layout xml code for getting cart and checkout page url at magento 2.

If want to get cart & checkout link at PHTML file then try below code:

Checkout Url

<?php echo $block->getUrl('checkout', ['_secure' => true]);?>

Cart Url

<?php echo $block->getUrl('checkout/cart', ['_secure' => true]);?>

 

If you want to call at block class try with

Checkout link:

$this->getUrl('checkout', ['_secure' => true]);

 

and Cart link:

$this->getUrl('checkout/cart', ['_secure' => true]);

I hope this will help lots.


Magento2 Checkout shipping address autofill

Magento2 Checkout shipping address autofill

Magento2 Checkout shipping address autofill.

If you want to Magento2 Checkout shipping address autofill during checkout then you have to use Magento 2 plugin.

I have used plugin over on Class below classes for autofill checkout Shipping address:

Magento\Checkout\Block\Checkout\AttributeMerger::merge
Magento\Checkout\Model\DefaultConfigProvider::getConfig

Magento\Checkout\Block\Checkout\AttributeMerger is  main classis the main class where i able to auto fill firstname,lastname,street,city,postcode,country_id,region,region_id,telephone,companyabove fields value using after

Create after Plugin (Devbera\AutofillCheckoutAddress\Plugin\Magento\Checkout::afterMerge ) on Magento\Checkout\Block\Checkout\AttributeMerger::merge for shipping address fields autofill up.

Step1:Define Plugin classes:

First Create di.xml at app/code/{VendorName}/{ModuleName}/etc/frontent where we are define the plugin classes.

Code

<?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\Checkout\Block\Checkout\AttributeMerger">
        <plugin disabled="false" name="checking_shipping_address_auto_full"
                sortOrder="10" type="{VendorName}\{ModuleName}\Plugin\Magento\Checkout\AttributeMergerPlugin"/>
    </type>
    <type name="Magento\Checkout\Model\DefaultConfigProvider">
        <plugin disabled="false" name="checking_email_auto_full" sortOrder="10"
                type="{VendorName}\{ModuleName}\Plugin\Magento\Checkout\Model\DefaultConfigProviderPlugin"/>
    </type>
</config>

Step2: Declare plugin class

Create First plugin class AttributeMergerPlugin.php at app/code/{VendorName}/{ModuleName}/Plugin/Magento/Checkout/

Code

<?php
/**
 * @category   Devbera
 * @package    Devbera_AutofillCheckoutAddress
 * @author     Amit Bera <dev.amitbera@gmail.com>
 * @website    http://www.amitbera.com
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */

namespace {VendorName}\{ModuleName}\Plugin\Magento\Checkout;

class AttributeMergerPlugin
{
    /**
     * @var \Psr\Log\LoggerInterface
     */
    private $logger;

    public function __construct(
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->logger = $logger;
    }

    public function afterMerge(
        \Magento\Checkout\Block\Checkout\AttributeMerger $subject,
        $fields
    ) {
        $this->logger->info(__METHOD__);
        
        $fieldNames = $this->shippingAddressFieldAnAutoFillValues();

        foreach ($fields as $attributeCode => $field) {
            //$this->logger->info(print_r($field, true));
            if (in_array($attributeCode, $fieldNames)) {
                //  Different Code for set Value for Street
                if ($attributeCode == 'street' &&
                    isset($field['children'][0]['config']['customScope'])
                    && $field['children'][0]['config']['customScope'] == 'shippingAddress') {
                    $fields[$attributeCode]['children'][0]['value'] = 'Oregon State University';
                }
                // Checking Address Type Shipping and Attribute is not Street
                if ($attributeCode != 'street' &&
                    (isset($field['config']['customScope']) && ($field['config']['customScope'] == 'shippingAddress'))) {
                    
                     $this->logger->info($attributeCode);
                    switch ($attributeCode) {
                        case "firstname":
                            $fields[$attributeCode]['value'] = 'John';
                            break;
                        case "lastname":
                            $fields[$attributeCode]['value'] = 'Deo';
                            break;
                        case "city":
                            $fields[$attributeCode]['value'] = 'Corvallis';
                            break;
                        case "country_id":
                            $fields[$attributeCode]['value'] = 'US';
                            break;
                        case "region_id":
                            $fields[$attributeCode]['value'] = 49;
                            break;
                        case "telephone":
                            $fields[$attributeCode]['value'] = '+1 541-737-1000';
                            break;
                        case "company":
                            $fields[$attributeCode]['value'] = 'Public school';
                            break;
                        case "postcode":
                            $fields[$attributeCode]['value'] = '973331';
                            break;
                        case "region":
                            $fields[$attributeCode]['value'] = 'Oregon';
                            break;
                        default:
                           // echo "ELSE";
                    }
                }
            }
        }
        return $fields;
    }

    /**
     * Makeing an array of
     * @return array
     */
    private function shippingAddressFieldAnAutoFillValues()
    {
        return [
            'firstname',
            'lastname',
            'city' ,
            'postcode',
            'country_id',
            'region',
            'region_id' ,
            'telephone',
            'street',
            'company'
        ];
    }
 
}

Second plugin class which will auto fill email id for NON _login customer

Create seocnf plugin class DefaultConfigProviderPlugin.php at app/code/{VendorName}/{ModuleName}/Plugin/Magento/Checkout/Modelt/

<?php
/**
 * @category   Devbera
 * @package    Devbera_AutofillCheckoutAddress
 * @author     Amit Bera <dev.amitbera@gmail.com>
 * @website    http://www.amitbera.com
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */

namespace {VendorName}\{ModuleName}\Plugin\Magento\Checkout\Model;

use Magento\Framework\App\Http\Context as HttpContext;
use Magento\Customer\Model\Context as CustomerContext;

class DefaultConfigProviderPlugin
{
    /**
     * @var HttpContext
     */
    private $httpContext;

    public function __construct(
        HttpContext $httpContext
    ) {
        $this->httpContext = $httpContext;
    }

    public function afterGetConfig(
        \Magento\Checkout\Model\DefaultConfigProvider $subject,
        $result
    ) {
        if (!$this->isCustomerLoggedIn() && is_array($result)) {
            $result['validatedEmailValue'] = 'john.deo@gmail.com';
        }
        return $result;
    }
    /**
     * Check if customer is logged in
     *
     * @return bool
     * @codeCoverageIgnore
     */
    private function isCustomerLoggedIn()
    {
        return (bool)$this->httpContext->getValue(CustomerContext::CONTEXT_AUTH);
    }
}

Disabled Autofill fields

If you want to disallow this autofill fields from editable for the customer then you have to add below code

$fields[$attributecode]['disabled'] = true; 

after autofill value set like you want disable first name field disable for customer after auto fill then add below code:

case "firstname":
    $fields[$attributeCode]['value'] = 'John';
    // Disable first  name field 
    $fields[$attributecode]['disabled'] = true; 		
    break;
case "lastname":
    $fields[$attributeCode]['value'] = 'Deo';
    break

Autofills Street field

Here, you may be seen that I have used different condition for the street because of this field is multiline code field. By default Magento street field is two lines, then you can use below code

 $fields[$attributecode]['children'][1]['value'] = 'Mayer road';

Here , at associated array value is 1 ( [‘children’][1]) as its line no is 2.


Thursday, 5 December 2019

Adding a new step to checkout page


Step 1: Create the .js file implementing the view model.

Create the checkout-login-step.js file under Akshweb/HelloWorld/view/frontend/web/js/view directory.
Basically, we need step_codestep_titleorder and the condition that allows to display this step.

Here is the code (Read code comment to get more info)

define(
    [
        'ko',
        'uiComponent',
        'underscore',
        'Magento_Checkout/js/model/step-navigator',
        'Magento_Customer/js/model/customer'
    ],
    function (
        ko,
        Component,
        _,
        stepNavigator,
        customer
    ) {
        'use strict';
        /**
        * check-login - is the name of the component's .html template
        */
        return Component.extend({
            defaults: {
                template: 'Akshaweb_HelloWorld/check-login'
            },

            //add here your logic to display step,
            isVisible: ko.observable(true),
            isLogedIn: customer.isLoggedIn(),
            //step code will be used as step content id in the component template
            stepCode: 'isLogedCheck',
            //step title value
            stepTitle: 'Logging Status',

            /**
            *
            * @returns {*}
            */
            initialize: function () {
                this._super();
                // register your step
                stepNavigator.registerStep(
                    this.stepCode,
                    //step alias
                    null,
                    this.stepTitle,
                    //observable property with logic when display step or hide step
                    this.isVisible,

                    _.bind(this.navigate, this),

                    /**
                    * sort order value
                    * 'sort order value' < 10: step displays before shipping step;
                    * 10 < 'sort order value' < 20 : step displays between shipping and payment step
                    * 'sort order value' > 20 : step displays after payment step
                    */
                    15
                );

                return this;
            },

            /**
            * The navigate() method is responsible for navigation between checkout step
            * during checkout. You can add custom logic, for example some conditions
            * for switching to your custom step
            */
            navigate: function () {

            },

            /**
            * @returns void
            */
            navigateToNextStep: function () {
                stepNavigator.next();
            }
        });
    }
);

Step 2: Create an .html template for the component.

In the above step, we use Akshaweb_HelloWorld/check-login as our template, let’s create it.

Create a new html file named check-login.html under Akshaweb/HelloWorld/view/frontend/web/template directory.

Here is the code

<!--Use 'stepCode' as id attribute-->
<li data-bind="fadeVisible: isVisible, attr: { id: stepCode }">
<div class="step-title" data-bind="i18n: stepTitle" data-role="title"></div>
    <div id="checkout-step-title"
         class="step-content"
         data-role="content">
         <p>The customer is <span data-bind="if: !isLogedIn">not</span> Logged-in</p>
        <form data-bind="submit: navigateToNextStep" novalidate="novalidate">
            <div class="actions-toolbar">
                <div class="primary">
                    <button data-role="opc-continue" type="submit" class="button action continue primary">
                        <span><!-- ko i18n: 'Next'--><!-- /ko --></span>
                    </button>
                </div>
            </div>
        </form>
    </div>
</li>

Step 3: Add the new step to the Checkout page layout.

We need to extend the checkout page’s layout to be able to display the new step
Add this file in our module:

Akshaweb/HelloWorld/view/frontend/layout/checkout_index_index.xml

The content as follow:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
                <arguments>
                    <argument name="jsLayout" xsi:type="array">
                        <item name="components" xsi:type="array">
                            <item name="checkout" xsi:type="array">
                                <item name="children" xsi:type="array">
                                    <item name="steps" xsi:type="array">
                                        <item name="children" xsi:type="array">
                                            <!-- The new step you add -->
                                            <item name="check-login-step" xsi:type="array">
                                                <item name="component" xsi:type="string">Akshaweb_HelloWorld/js/view/checkout-login-step</item>
                                                    <!--To display step content before shipping step "sortOrder" value should be < 1-->
                                                    <!--To display step content between shipping step and payment step  1 < "sortOrder" < 2 -->
                                                    <!--To display step content after payment step "sortOrder" > 2 -->
                                                <item name="sortOrder" xsi:type="string">2</item>
                                                <item name="children" xsi:type="array">
                                                    <!--add here child component declaration for your step-->
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </argument>
                </arguments>
        </referenceBlock>
    </body>
</page>

That’s the steps to add a new step to checkout page.
Clean cache and refresh your browser, the result will appear like this
check login step

  How to Upgrade magento version from 2.3.x [EE] to 2.3.x [EE] Here are the steps I used to successfully update Magento 2.3.3 [EE] to 2.3.5 ...