How to make custom admin “Save and Continue Edit” button work in Magento 2

I recently created a custom module that has a “Save and Continue Edit” button on the admin edit form. The tricky part is to make the page stay on the edit screen after the button is pressed and the form is saved.

When Save and Continue button is pressed, a back/edit string is appended to the submit url by default, so in the save controller we can check for it and set redirect url accordingly.

The return statement of the save controller should look something like this:

    ...
    //check for 'back' parameter
    if ($this->getRequest()->getParam('back')) {
        //redirect to edit page
        return $resultRedirect->setPath('*/*/edit', ['id' => $model->getId(), '_current' => true]);
    }
 
    //redirect to index page
    return $resultRedirect->setPath('*/*/');
    ...

Use AWS CloudFront with EC2 instance

Hi guys, I haven’t written anything for quite some time due to lack of time (and laziness). In this article I’m going to share my experience on how to put a whole website, hosted on a EC2 instance, behind CloudFront.

If you want your website to have a global presence and to be accessed quickly anywhere around the world, even in China probably, AWS CloudFront is a great tool to do just that. CloudFront supports the distribution of both static and dynamic content, so you can pretty much set it up with any type of website.
Continue reading “Use AWS CloudFront with EC2 instance”

Show address fields on Magento customer registration page

There’s no setting in Magento’s backend to switch on/off address fields display on customer registration page. The easiest way to show address fields is to add a ‘show_address_fields’ argument to the layout file customer_account_create.xml

File: app/design/frontend//Magento_Customer/layout/customer_account_create.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="customer_form_register">
            <arguments>
                <argument name="show_address_fields" xsi:type="number">1</argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Clear cache afterwards and the address fields should appear on the customer account creation page.

Sending emails with High Importance in Magento

I recently had to customize a transactional email and send it with High Importance in Magento 1.9. After googling around found this post explaining how to do it in Zend Mail.

Since Magento’s mail object extends Zend_Mail, here’s how it’s done in Magento.

$mailTemplate = Mage::getModel('core/email_template');
 
//get Zend_Mail and add Importance headers
$mailTemplate->getMail()
             ->addHeader('X-Priority', '1')
             ->addHeader('X-MSMail-Priority', 'High')
             ->addHeader('Importance', 'High');
 
$mailTemplate->setDesignConfig(array('area' => 'frontend'))         
            ->sendTransactional(
                $template_id,
                $sender,
                $mailto,
                null,
                $data
            );
...

Add default alt attribute to all product images in Magento 2

Here’s another good use of the handy Plugin feature introduced in Magento 2.

To make product name as the default value of all product image’s ‘alt’ attribute, all we need to do is to create a simple Plugin.

First, declare the Plugin in your custom module’s di.xml

File: app/code/Vendor/Module/etc/frontend/di.xml

<?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\Catalog\Block\Product\View\Gallery">
	<plugin name="vendor_module_block_product_view_gallery_plugin" type="Vendor\Module\Block\Product\View\Gallery\Plugin" sortOrder="10" />
    </type>
</config>

Now the Plugin’s code. The function we’re targeting is getGalleryImages,

File: app/code/Vendor/Module/Block/Product/View/Gallery/Plugin.php

<?php
namespace Vendor\Module\Block\Product\View\Gallery;
 
class Plugin
{       
    public function afterGetGalleryImages($block, $images)
    {
        if ($images instanceof \Magento\Framework\Data\Collection) {
            $product = $block->getProduct();
            foreach ($images as $image) {
                //check if label is set
                if(!$image->getLabel()){
                    $image->setLabel($product->getName());
                }
            }            
        }
 
        return $images;
    }
}

And that’s it.

Cron job setup in Magento 2

It is important to correctly setup cron job for Magento 2 as some basic functions such as reindexing rely on cron job to execute.

Below is a typical cron job setup on a cPanel server with logging enabled.

* * * * * /usr/local/bin/php /path_to_your_magento_installation/bin/magento cron:run | grep -v "Ran jobs by schedule" >> /path_to_your_magento_installation/var/log/magento.cron.log
* * * * * /usr/local/bin/php /path_to_your_magento_installation/update/cron.php >> /path_to_your_magento_installation/var/log/update.cron.log
* * * * * /usr/local/bin/php /path_to_your_magento_installation/bin/magento setup:cron:run >> /path_to_your_magento_installation/var/log/setup.cron.log

Make sure the jobs are set to run every minute if you’re using the default Magento configurations. If the interval is longer, e.g. every five minutes, the indexer scripts will be missed and a ‘One or more indexers are invalid‘ message will appear in the admin area.

How to add a custom image field to Catalog Category in Magento 2

Update: Magento 2.2 compatible version can be downloaded here. Note: tested in Magento version 2.2.2.

This article explains the steps needed to add a custom image field to categories in Magento 2. The code is tested on Magento version 2.1.2.

First, in the InstallData script of your custom module, insert a category image attribute to Catalog Category model. In this example the attribute name is ‘thumbnail’.
File: app/code/Vendor/Module/Setup/InstallData.php

    ...
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {                
        /** @var \Magento\Catalog\Setup\CategorySetup $categorySetup */
        $categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
 
        $categorySetup->addAttribute(
            \Magento\Catalog\Model\Category::ENTITY,
            'thumbnail',
            [
                'type' => 'varchar',
                'label' => 'Thumbnail',
                'input' => 'image',
                'backend' => 'Magento\Catalog\Model\Category\Attribute\Backend\Image',
                'required' => false,
                'sort_order' => 5,
                'global' => ScopedAttributeInterface::SCOPE_STORE,
                'group' => 'Content',
                'is_used_in_grid' => false,
                'is_visible_in_grid' => false,
                'is_filterable_in_grid' => false
            ]
        );
    }    
    ...

Continue reading “How to add a custom image field to Catalog Category in Magento 2”

magento 2 syntax error during installation, unexpected ‘.’ in AbstractFactory.php on line 93

Recently tried to install Magento v2.1 on a server but got the following error message:

PHP Parse error: syntax error, unexpected '.' in public_html/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93

Line 93 in AbstractFactory.php is return new $type(...array_values($args));

It turns out that ... is a new operator introduced in PHP 5.6, which is also known as the Splat Operator.

Upgrading PHP version to 5.6 solved the problem. The lesson here is to always check the minimum system requirements before installation. The minimum systems requirements for Magento 2.1 can be found here.

Magento 2 useful commands

Here’s a list of Magento 2 commands that I use frequently:

bin/magento deploy:mode:show //show current application mode
bin/magento deploy:mode:set //set application mode, possible values are default, developer, production

bin/magento cache:clean //Clean cache
bin/magento cache:flush //Flushes cache storage, this will clear all frontend sessions

bin/magento module:enable Module_Name //enable a module
bin/magento module:disable Module_Name //disalbe a module

bin/magento indexer:reindex //reindex all index
bin/magento setup:upgrade //update all modules

To display all available commands, use

bin/magento list