Remove index.php from Magento Store URL

In this blog, we will see how to remove index.php from base URL of a Magento store.

To remove “index.php” from the web-site URL, the mod_rewrite module should be enabled on your server.

In case, mod_rewrite is not enabled, follow these steps:

  1. Run this command sudo a2enmod rewrite
  2. Edit your httpd configuration and write following lines
    <Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
  3. Now, restart apache service using this command (the commands might change based on the OS that you use)
    sudo service apache2 restart

You need to following these steps:

  1. Log in to your Magento store admin and go to the Store ⇒ Configuration section. (In case of Magento 1, it’s System  Configuration)
  2. Then click on the Web tab in the leftside menu.
  3. Expand the Search Engines Optimization tab and set the Use Web Server Rewrites option to Yes.
    Search Engines Optimization
  4. Then, go to the Base URLs (Secure) tab and set the Use Secure URLs on Storefront option to Yes, too. Click on the Save Config button.
    Base URLs (Secure) ⇒ Use Secure URLs on Storefront
  5. Make sure your Secure and Unsecure base urls should end with “/”.

Sending Email with Attachment in Magento 2.3.x

Some of the functionalities in Magento 2.3.x is different from previous page. The reason is that in most cases the 2.3.x framework uses Zend Framework 2 (ZF2) and almost totally refuses to applyZend Framework 1 (ZF1). So, due to this, the previous method Magento\Framework\Mail\MailMessageInterface::createAttachment() is deprecated and there is no direct method to do so. In this blog, we will see how to add attachment to emails.

To understand this process, it’s recommened to get an Idea of some of the ZF2 components such as:

As createAttachment() method is no more available, we will override Magento\Framework\Mail\Message and create a class which will implement Magento\Framework\Mail\MailMessageInterface.

In this method, we will redifine/create some methods which would be responsible for different MIME parts which would be merged later before being sent. Let’s see some of the important ones:

Message::setBodyText() Method

public function setBodyText($content)
{
    $textPart = $this->partFactory->create();

    $textPart->setContent($content)
        ->setType(Mime::TYPE_TEXT)
        ->setCharset($this->zendMessage->getEncoding());

    $this->parts[] = $textPart;

    return $this;
}

In this method, we are adding the text MIME part to the email and storing in $this->parts array.

Message::setBodyHtml() Method

public function setBodyHtml($content)
{
    $htmlPart = $this->partFactory->create();

    $htmlPart->setContent($content)
        ->setType(Mime::TYPE_HTML)
        ->setCharset($this->zendMessage->getEncoding());

    $this->parts[] = $htmlPart;

    return $this;
}

In this method, we are doing the same as above but we are setting the HTML part and storing in the same $this->parts array.

Message::setBodyAttachment() Method

public function setBodyAttachment($content, $fileName, $fileType)
{
    $attachmentPart = $this->partFactory->create();

    $attachmentPart->setContent($content)
        ->setType($fileType)
        ->setFileName($fileName)
        ->setDisposition(Mime::DISPOSITION_ATTACHMENT)
        ->setEncoding(Mime::ENCODING_BASE64);

    $this->parts[] = $attachmentPart;

    return $this;
}

Here we set the content of the file, then set a file type and specify its name. In addition, we set disposition. It’s necessary for the file to be treated as an attachment.

Above we’ve described all methods that help us to add mime parts to the message. But we also added to this class one more important method – Message::setPartsToBody().

Message::setPartsToBody() Method

public function setPartsToBody()
{
    $mimeMessage = $this->mimeMessageFactory->create();
    $mimeMessage->setParts($this->parts);
    $this->zendMessage->setBody($mimeMessage);

    return $this;
}

This method is used to put all the pieces together.

Now, we will create a new class TransportBuilder which will extend the actual core class Magento\Framework\Mail\Template\TransportBuilder and instead of the core class, we will be using this new class.

TransportBuilder::addAttachment() Method

public function addAttachment($content, $fileName, $fileType)
{
    $this->message->setBodyAttachment($content, $fileName, $fileType);

    return $this;
}

Now, you can call this method while sending mail as used in this file.

Further, you can find the entire module here. GitHub

Magento 2 Console Command Sortcuts

While working on Magento 2.x, you often need to run several console commands which are actually very handy in terms of managing the things such as cache, upgrades, deploy modes, indexers etc. You can check the entire list of commands by running this command:

php bin/magento list

Well, typing the full long commands are not very pleasant if it has to be done multiple times. So, we can use shortcuts instead full commands. This feature comes due to the Symphony framework which is used by each console class that implement command line functionality. The use Symfony\Component\Console\Command component to implement command line features. You can learn more in the documentation of Symphony framework. You can use shortest unambiguous name intead of full name, e.g. s instead of setup.

Now, let’s see shortcuts for some of the commonly used Magento 2 console commands:

1. Cache Commands

php bin/magento cache:clean ==> php bin/magento c:c

php bin/magento cache:disable ==> php bin/magento c:d

php bin/magento cache:enable [cache_type] ==> php bin/magento c:e [cache_type]

php bin/magento cache:flush [cache_type] ==> php bin/magento c:f [cache_type]

php bin/magento cache:status ==> php bin/magento c:s

Where cache_type is the parameter in which you can pass one or more cache types separated by whitespaces, e.g.

php bin/magento c:c config layout

2. Indexer Commands

php bin/magento indexer:reindex ==> php bin/magento i:rei

php bin/magento indexer:info ==> php bin/magento i:i

php bin/magento indexer:status ==> php bin/magento i:sta

php bin/magento indexer:show-mode ==> php bin/magento i:sho

php bin/magento indexer:reset ==> php bin/magento i:res

You may pass parameters for particular indexer type as well.

3. Compile Command

php bin/magento setup:di:compile ==> php bin/magento s:di:c

4. Setup Upgrade Command

php bin/magento setup:upgrade ==> php bin/magento s:up

5. Static Content Deploy Command

php bin/magento setup:static-content:deploy ==> php bin/magento s:s:d

6. Module Management Commands

php bin/magento module:status ==> php bin/magento mo:s

php bin/magento module:disable Namespace_Module ==> php bin/magento mo:d Namespace_Module

php bin/magento module:enable Namespace_Module ==> php bin/magento mo:e Namespace_Module

php bin/magento module:uninstall Namespace_Module ==> php bin/magento m:u Namespace_Module

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.