Magento 2 – How to Get Base URL, Media URL, Current URL, Base Path, Media Path

In this blog, both methods are demonstrated, using Dependency Injection and using ObjectManager

Using Dependency Injection

Here is the sample code. It has been used in a block class but you may use it in any class you want. We will be using three classes:

\Magento\Store\Model\StoreManagerInterface
\Magento\Framework\Filesystem\DirectoryList and
\Magento\Framework\UrlInterface
as follows:
<?php

namespace Excellence\MagentoBlog\Block;

class DataBlock extends \Magento\Framework\View\Element\Template
{
    protected $_storeManager;
    protected $_urlInterface;
    protected $_dir;

    public function __construct(
        \Magento\Backend\Block\Template\Context $context,        
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Filesystem\DirectoryList $dir,
        \Magento\Framework\UrlInterface $urlInterface,    
        array $data = []
    ) {
        $this->_storeManager = $storeManager;
        $this->_dir = $dir;
        $this->_urlInterface = $urlInterface;
        parent::__construct($context, $data);
    }

    /**
     * This function prints all of the required data using:
     * \Magento\Store\Model\StoreManagerInterface
     */
    public function getStoreManagerData()
    {    
        echo $this->_storeManager->getStore()->getId() . '<br />';
        
        /**#@+
        Standard Function Call:

        $this->_storeManager->getStore()->getBaseUrl(Url type);
        
         * Possible URL types
        const URL_TYPE_LINK = 'link';
        const URL_TYPE_DIRECT_LINK = 'direct_link';
        const URL_TYPE_WEB = 'web';
        const URL_TYPE_MEDIA = 'media';
        const URL_TYPE_STATIC = 'static';
        const URL_TYPE_JS = 'js';
        */
        
        // by default: URL_TYPE_LINK is returned

        echo $this->_storeManager->getStore()->getBaseUrl() . '<br />';        
        
        echo $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB) . '<br />';
        echo $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_DIRECT_LINK) . '<br />';
        echo $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . '<br />';
        echo $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_STATIC) . '<br />';
        
        /* To get custom URL based on url key */
        echo $this->_storeManager->getStore()->getUrl('url_key') . '<br />';
        
        /* To get Current URL */
        echo $this->_storeManager->getStore()->getCurrentUrl(false) . '<br />';

        echo $this->_storeManager->getStore()->getBaseMediaDir() . '<br />';
            
        echo $this->_storeManager->getStore()->getBaseStaticDir() . '<br />';    
    }

    /**
     * This function prints all of the required data using:
     * \Magento\Framework\UrlInterface
     */
    public function getUrlInterfaceData()
    {
        echo $this->_urlInterface->getCurrentUrl() . '<br />';
        
        echo $this->_urlInterface->getUrl() . '<br />';
        
        /* To get custom URL based on url key */
        echo $this->_urlInterface->getUrl('url_key') . '<br />';
        
        echo $this->_urlInterface->getBaseUrl() . '<br />';
    }

    /**
     * This function prints all of the directory paths using:
     *  \Magento\Framework\Filesystem\DirectoryList
     */
    public function getDirectoryPaths()
    {
        echo $this->_dir->getRoot()."<br>"; // Output: /var/www/html/myproject

        echo $this->_dir->getPath('media')."<br>"; // Output: /var/www/html/myproject/pub/media

        echo $this->_dir->getPath('pub')."<br>"; // Output: /var/www/html/myproject/pub

        echo $this->_dir->getPath('static')."<br>"; // Output: /var/www/html/myproject/pub/static

        echo $this->_dir->getPath('var')."<br>"; // Output: /var/www/html/myproject/var

        echo $this->_dir->getPath('app')."<br>"; // Output: /var/www/html/myproject/app

        echo $this->_dir->getPath('etc')."<br>"; // Output: /var/www/html/myproject/app/etc

        echo $this->_dir->getPath('lib_internal')."<br>"; // Output: /var/www/html/myproject/lib/internal

        echo $this->_dir->getPath('lib_web')."<br>"; // Output: /var/www/html/myproject/lib/web

        echo $this->_dir->getPath('tmp')."<br>"; // Output: /var/www/html/myproject/var/tmp

        echo $this->_dir->getPath('cache')."<br>"; // Output: /var/www/html/myproject/var/cache

        echo $this->_dir->getPath('log')."<br>"; // Output: /var/www/html/myproject/var/log

        echo $this->_dir->getPath('session')."<br>"; // Output: /var/www/html/myproject/var/session

        echo $this->_dir->getPath('setup')."<br>"; // Output: /var/www/html/myproject/setup/src

        echo $this->_dir->getPath('di')."<br>"; // Output: /var/www/html/myproject/var/di

        echo $this->_dir->getPath('upload')."<br>"; // Output: /var/www/html/myproject/pub/media/upload

        echo $this->_dir->getPath('generation')."<br>"; // Output: /var/www/html/myproject/var/generation

        echo $this->_dir->getPath('view_preprocessed')."<br>"; // Output: /var/www/html/myproject/var/view_preprocessed

        echo $this->_dir->getPath('composer_home')."<br>"; // Output: /var/www/html/myproject/var/composer_home

        echo $this->_dir->getPath('html')."<br>"; // Output: /var/www/html/myproject/var/view_preprocessed/html

    }
}
You can see more functions in following classes:
/var/www/html/myproject/vendor/magento/module-store/Model/Store.php
/var/www/html/myproject/vendor/magento/framework/Url.php

Using ObjectManager

Well, this approach is never recommended as you know that using ObjectManager is never recommended in Magento 2. Find more about this here.

Though, we will see some of the methods to get work done:

<?php
$objectManager =  \Magento\Framework\App\ObjectManager::getInstance();        
 
$appState = $objectManager->get('\Magento\Framework\App\State');
$appState->setAreaCode('frontend');
 
$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$store = $storeManager->getStore();
 
echo $store->getUrl('product/33'); echo '<br>';
echo $store->getCurrentUrl(); echo '<br>';
echo $store->getBaseUrl(); echo '<br>';
echo $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB); echo '<br>';
echo $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA); echo '<br>';
?>

How to create admin user using Command Line Interface | Magento 2

As you know a Magento Administrator can create a new user of any role from admin panel, but in some cases, one might need to create it from some other means rather than the conventional method (i.e. using Magento Admin Panel). E.g. if you forget admin login credentials, and you are unable to reset it by normal methods, then you will need some alternate way. This blog explains how you can add a new admin user using command line interface.

This is the command for adding new admin user:

php bin/magento admin:user:create --admin-user="username" --admin-password="password" --admin-email="[email protected]" --admin-firstname="First Name" --admin-lastname="Last Name"

You need to put proper information for username, password and email id and make sure neither username or email should be attached with existing admin users.

That’s all folks. You are all set to create new admin user using CLI.

Creating Customer Attribute Programmatically in Magento 2

As we know, in Enterprise edition of Magneto, a customer attribute can be created from Admin Panel itself. But, no such option is available for Community Edition.

But no worries, a customer attribute can be created programmatically in both of the editions. A custom module needs to be created for this one. The setup script of the module (InstallData.php) will be used to perform this task. Follow these steps:

1. Create setup script (InstallData.php)

Create file app/code/Excellence/Hello/Setup/InstallData.php

Add following code to the file:

<?php

namespace Excellence\Hello\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Model\Config;
use Magento\Customer\Model\Customer;

class InstallData implements InstallDataInterface
{
    private $eavSetupFactory;
    
    public function __construct(EavSetupFactory $eavSetupFactory, Config $eavConfig)
    {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->eavConfig       = $eavConfig;
    }
}

In this class, we define the EAV setup model which will be used to interact with Magento 2 attribute.

2. Defining The Install() method

In this step, we will be creating Install() method and create EAV setup model which we will do the job

public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
    $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
    $eavSetup->addAttribute(
        \Magento\Customer\Model\Customer::ENTITY,
        'sample_attribute',
        [
            'type'         => 'varchar',
            'label'        => 'Sample Attribute',
            'input'        => 'text',
            'required'     => false,
            'visible'      => true,
            'user_defined' => true,
            'position'     => 999,
            'system'       => 0,
        ]
    );
    $sampleAttribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'sample_attribute');

    // more used_in_forms ['adminhtml_checkout','adminhtml_customer','adminhtml_customer_address','customer_account_edit','customer_address_edit','customer_register_address']
    $sampleAttribute->setData(
        'used_in_forms',
        ['adminhtml_customer']

    );
    $sampleAttribute->save();
}

Here, the used_in_forms is used to show the attribute in different kind of forms such as customer registration page, account information page etc.

Complete Install Script:

Here is the complete Install script which is to be used in InstallData.php:

<?php

namespace Excellence\Hello\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Model\Config;
use Magento\Customer\Model\Customer;

class InstallData implements InstallDataInterface
{
    private $eavSetupFactory;
    
    public function __construct(EavSetupFactory $eavSetupFactory, Config $eavConfig)
    {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->eavConfig       = $eavConfig;
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
        $eavSetup->addAttribute(
            \Magento\Customer\Model\Customer::ENTITY,
            'sample_attribute',
            [
                'type'         => 'varchar',
                'label'        => 'Sample Attribute',
                'input'        => 'text',
                'required'     => false,
                'visible'      => true,
                'user_defined' => true,
                'position'     => 999,
                'system'       => 0,
            ]
        );
        $sampleAttribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'sample_attribute');

        // more used_in_forms ['adminhtml_checkout','adminhtml_customer','adminhtml_customer_address','customer_account_edit','customer_address_edit','customer_register_address']
        $sampleAttribute->setData(
            'used_in_forms',
            ['adminhtml_customer']

        );
        $sampleAttribute->save();
    }
}

After that run setup:upgrade and setup:static-content:deploy to see the changes. Also, you might need to set permissions of directories like pub, vargenerated etc.

Magento 2 – Request Response JSON

In this blog, we will learn about different operations on request and response in magento2. First of all, let’s start with reading GET/POST data. In many cases, we need to read data passed using GET or POST method such as data passed from form. To process this data, we need to first read the data. The method is similar to magento 1.

To read data passed via get Method we simply use following two methods:

$this->getRequest()->getParams()

this will read all the get data but to read any specific data we use

$this->getRequest()->getParam('data');

To read data passed via POST method, we use following method:

$this->request->getPost()

this will read all the the data being passed via post. But if we want to read specific data then we will use

$this->getRequest()->getPost('data');

But, if you go through the magento2 core files, then you will find getPostvalue() method used instead of getPost(). It is defined in lib\internal\Magento\Framework\HTTP\PhpEnvironment\Request.php:

public function getPostValue($name = null, $default = null)
{
    $post = $this->getPost($name, $default);
    if ($post instanceof ParametersInterface) {
        return $post->toArray();
    }
    return $post;
}

You can access the post data by using:

$post = $this->getRequest()->getPostValue();

Although both the methods, getPost() & getPostValue() have almost similar functionality but there is slight difference in the format they return data. In magento2, it is supposed to be good practice to use getPostValue().

Following example will make you understand better:

When we use getPost(), then it returns an instance like Zend\Stdlib\Parameters Object ( [storage:ArrayObject:private] => Array ( [data] => Array ( [title] => abc [status] => 1 [submit] => Save ) ) )

But when we use getPostValue() then we get a well structured array like: Array ( [data] => Array ( [title] => abc [status] => 1 [submit] => Save ) ) which is easy to manipulate. This is the reason, getPostValue is preferred over getPost() method.

then It get the getPost value from vendor\zendframework\zend-http\src\Request.php:

public function getPost($name = null, $default = null)
{
    if ($this->postParams === null) {
        $this->postParams = new Parameters();
    }

    if ($name === null) {
        return $this->postParams;
    }

    return $this->postParams->get($name, $default);
}

The above methods will work if you are trying this from a controller that extends Magento\Framework\App\Action\Action you can get the request. In other cases you need to inject request in the constructor as:

class ClassName 
{
     protected $request;
     public function __construct(
     \Magento\Framework\App\Request\Http $request,
     ....//rest of parameters here
     ) {
          $this->request = $request;
          ...//rest of constructor here
     }
     public function getPost()
     {
          return $this->request->getPost();
     }
}

Sending Custom Header/Response from Controller:

In magento2, it is possible, from a controller execute method, to manipulate the request to send a custom header and error page.

First of all, to comply with action controller interface \Magento\Framework\App\ActionInterface::execute(), your action must return an instance of \Magento\Framework\Controller\ResultInterface (\Magento\Framework\App\ResponseInterface is also supported, but is legacy and will be removed in future releases of M2, when all core usages are refactored).

So choose from available implementations of \Magento\Framework\Controller\ResultInterface. The most suitable for custom REST API (assuming it operates with JSON) seems to be \Magento\Framework\Controller\Result\Json. However, if you need something even more custom, consider \Magento\Framework\Controller\Result\Raw.

Here is code snippet which will help you to understand it better:

namespace VendorName\ModuleName\Controller;

/**
 * Demo of authorization error for custom REST API
 */
class RestAuthorizationDemo extends \Magento\Framework\App\Action\Action
{
    /** @var \Magento\Framework\Controller\Result\JsonFactory */
    protected $jsonResultFactory;

    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $jsonResultFactory
    ) {
        parent::__construct($context);
        $this->jsonResultFactory = $jsonResultFactory;
    }

    public function execute()
    {
        /** @var \Magento\Framework\Controller\Result\Json $result */
        $result = $this->jsonResultFactory->create();
        /** You may introduce your own constants for this custom REST API */
        $result->setHttpResponseCode(\Magento\Framework\Webapi\Exception::HTTP_FORBIDDEN);
        $result->setData(['error_message' => __('What are you doing here?')]);
        return $result;
    }
}

The code above will result in response with HTTP status code 403 and body

{“error_message”:”Authorization Failed”}