Monday, 26 March 2018

Add Custom JS on Magento 2 admin

I was creating a new extension that involves customization on Magento 2 Admin panel. As part of it, I needed to add custom javascript on the admin panel.

There are two ways you can add your custom JS on admin panel.

  • Including it with blocks
  • Including it in head and loading by require js

Including it with Blocks

create folder structure like this view/adminhtml/layout/
create new file default.xml inside it.

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nonamespaceschemalocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
         <referencecontainer name="js">
            <block class="Magento\Backend\Block\Template" name="admincustomjs" template="Your_Modulename::system/config/additional_script.phtml">
        </block></referencecontainer>
    </body>
</page>

If you want to include your script in footer just replace the referencecontainer name="footer"

In additional_script.phtml you can include your custom script like this.
<script type="text/javascript">
    require(
        ['jquery'],
        function($) {
            $(function() {
              console.log('custom script included successfully');
            });
          });
</script>

If you see page source of the system config page or any other page in admin panel, you can see there are few custom scripts included by Magento Just above the Footer tag.

Including it in head and loading by require js

When using this method don't use default.xml to include your script in <head> tag. This will load your script BEFORE the main require js is loaded and it will create a JS error.

create folder structure like this  view/adminhtml/layout/adminhtml_system_config_edit.xml

You can change the xml file name inside layout folder as per your admin page action. EG: customer_index_edit.xml


<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
<link src="Your_Modulename::js/custom_require.js"/>
    </head>
    <body/>
</page>


You need to place the custom_require.js inside view/adminhtml/web/js/ 
In custom_require.js use require method to include your custom javascript.

require([
    'Your_Modulename/custom_system_config'
]);
Create custom_system_config.js file inside view/adminhtml/web/
place your custom javascript in this file

define([
  "jquery"
],&nbsp
function($) {
  "use strict";
    $(document).ready(function($){
        console.log("custom script included successfully");
    });
    return;
});
If you want to include any third party min JS files you can place it here and you can call its API. 
Using this method, your custom javascript file will be called using require js.

You can see Magento 2 core modules uses both the methods. 

For First method, you can refer vendor\magento\module-paypal\view\adminhtml\layout\adminhtml_system_config_edit.xml

For Second method, you can refer vendor\magento\module-customer\view\adminhtml\layout\customer_index_edit.xml

Sunday, 2 April 2017

Custom logger in magento 2 | FirePhp | Console log

In my previous post I have explained how to use logger in Magento 2. This post details using FirePHP logging in Magento 2.

This awesome logging will output the Log data on your Browser console. I have tested on Chrome & Firefox. In this post I will be referencing Chrome.

Step 1:
Install Extension for Chrome.
You need to install two extensions, one is regular logging and Other is for logging during Ajax requests.

Step 2:
Now we need to add our codes to ignore the regular logging to files and output the logs on our browser console.
Creating Logger instance using DI is explained in previous post. Please go though if you haven't yet.
Magento 2 includes FirePHP by default. We just need to call it for logging.

After creating the $this->_logger Object. use below code.

$this->_logger->pushHandler(new \Monolog\Handler\FirePHPHandler());
$this->_logger->addDebug('Debug log');

There are multiple types for logging.

$this->_logger->addInfo();
$this->_logger->addNotice();
$this->_logger->addError();
$this->_logger->addWarning();
$this->_logger->addEmergency();
$this->_logger->addCritical();
$this->_logger->addAlert();

NOTE: If you want to log an array(), you need to pass it as a second argument which is optional.

$this->_logger->addDebug('Debug array', $arrayVar);

Example output















Friday, 31 March 2017

Magento 2 cannot login on frontend

After installing Sample data on localhost, I was not able to login with the dummy user login.
Am using xampp on windows 7, and working on Chrome browser.

Recently I found I cannot add any products to cart and found a solution for it.

The same solution applies here. This issue is due to form key mismatch. As I suggested in previous post, this is recommended only for testing environment i.e only on your localhost.

Quick Fix.


Go to vendor/magento/module-customer/Controller/Account/LoginPost.php execute() method.
Comment out the first if condition which checks the session and posted form key.

// if ($this->session->isLoggedIn() || !$this->formKeyValidator->validate($this->getRequest())) {

      // /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */

      // $resultRedirect = $this->resultRedirectFactory->create();

      // $resultRedirect->setPath('*/*/');

      // return $resultRedirect;

// } 

Magento 2 cannot add products to cart

On localhost environment, there is this annoying issue on CHROME browser. When you add products to cart, you will see no errors displayed, but products will not be added to cart.

Few of the stack overflow post suggest to change the localhost URL to 127.0.0.1 OR adding a vhost entry to change the localhost url to something else. I have found a quick fix for this issue. This fix is not recommended for Production environment.  This is only for the developers who are working on their local environment.


Problem


There is a form_key mismatch. Form key which gets posted during add to cart action and the stored Session value form key is mismatched.


Quick fix.


Go to vendor/magento/module-checkout/Controller/Cart/Add.php execute() method.
Comment out the first if condition which checks the session and posted form key.

//if (!$this->_formKeyValidator->validate($this->getRequest())) {

        //return $this->resultRedirectFactory->create()->setPath('*/*/');

//}

Wednesday, 3 June 2015

Get system config values in magento 2

How to get data from Magento 2 System Configuration ? Here's how to.

We need to call the default method available.

Just Use \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
In your constructor argument and create an Object $this->scopeConfig = $scopeConfig;

Now to Get the configuration value just use
$this->_scopeConfig->getValue('dev/debug/template_hints', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);

First argument is the value which we need from system configuration and the Second argument is the Store scope.

Demo

public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
) {
$this->_scopeConfig = $scopeConfig;
}


public function helloWorld(){

   $showTemplateHint =  $this->_scopeConfig->getValue('dev/debug/template_hints', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);

}

Friday, 29 May 2015

Logging in magento 2 including FirePHP

Magento 2 uses Monolog library to log messages. More information about the monolog is here

You can find the Library package in the following location in Magento 2
MAGENTO2_ROOT/vendor/monolog

Log files will be created inside var/log folder.

To add logging to your class we need to add an instance of the monolog class. As magento 2 uses Dependency Injection(DI)  we need to pass the instance in the constructor of your class.

Just for testing, we are going to add this in one of the magento's default class. Go to app/code/Magento/Cms/Block/Page.php

And add the below lines After Protected $pageConfig


/**
* @var \Psr\Log\LoggerInterface
*/
protected $_logger;

And add this line \Psr\Log\LoggerInterface $logger,  as the parameter of the __construct() 

Now we need to create an object. so add these line inside the function

$this->_logger = $logger;
$this->_logger->addDebug('some text or variable');

So Finally our Constructor function will look like this.


public function __construct(
        \Magento\Framework\View\Element\Context $context,
        \Magento\Cms\Model\Page $page,
        \Magento\Cms\Model\Template\FilterProvider $filterProvider,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Cms\Model\PageFactory $pageFactory,
        \Magento\Framework\View\Page\Config $pageConfig,
        \Psr\Log\LoggerInterface $logger,
        array $data = []
    ) {
        parent::__construct($context, $data);
        // used singleton (instead factory) because there exist dependencies on \Magento\Cms\Helper\Page
        $this->_page = $page;
        $this->_filterProvider = $filterProvider;
        $this->_storeManager = $storeManager;
        $this->_pageFactory = $pageFactory;
        $this->pageConfig = $pageConfig;
        $this->_logger = $logger;
        $this->_logger->addDebug('some text or variable');
    }

TO USE FIREPHP LOGGING

Detailed Article here

Monolog has inbuilt FirePHP logging library. FirePHP is used to send log messages to the FireBug Console. More information here. Install FirePHP Firefox / Chrome addon to use this.

Now to Use FirePHP in Magento 2 just use this line
$this->_logger->pushHandler(new \Monolog\Handler\FirePHPHandler());
above
$this->_logger->addDebug('some text here');

You can see the message available on the Firebug Console panel, instead of creating a log file.

Friday, 22 May 2015

Configurable Product not adding to cart

Community edition 1.9 and Enterprise edition 1.14 both have this problem. There will be a memory exhausted issue or the browser keeps loading forever.

There is a patch for this fix which is available on github.
More discussion can be found on the magento.stackexchange website.