Magento 2 coding standards

Magento 2 Coding Standards

Magento 2 uses out of the box coding standards which you can run against your custom module(s). It allows
you to automatically check your code against some of the common Magento and PHP coding issues, for example:

  1. – raw SQL queries;
  2. – SQL queries inside a loop;
  3. – direct instantiation of Mage and Enterprise classes;
  4. – unnecessary collection loading;
  5. – excessive code complexity;
  6. – use of dangerous functions;
  7. – use of PHP Superglobals;

It consists of two rulesets – MEQP1 for Magento 1 and MEQP2 for Magento 2. Each of them contains the rules depending on the requirements of each version.

Here is the step by step guide to install and run coding standards against your code base.

Step 1 – Go to your Magento 2 root folder and install all dependencies via composer using the following command:

$ composer create-project --repository=https://repo.magento.com magento/marketplace-eqp magento-coding-standard

You’re required to authenticate; see Get your authentication keys for details.

Step 2 – Set dynamic sniffs, Sniffs with complex logic, like MEQP2.Classes.CollectionDependency and MEQP2.SQL.CoreTablesModification require Magento 2 installation path. You can specify it by running following command:

$ vendor/bin/phpcs --config-set m2-path /path/to/magento2

Step 3 – Go to magento-coding-standard folder which should be installed on your magento root folder using the following command

$ cd magento-coding-standard

Step 4 – Run your code against Magento 2 coding standards and see if it passes the standards or not

$ vendor/bin/phpcs /path/to/your/extension --standard=MEQP1

and

$ vendor/bin/phpcs /path/to/your/extension --standard=MEQP2

Step 5 – Fixing Errors Automatically

PHP_CodeSniffer offers the PHP Code Beautifier and Fixer (phpcbf) tool. It can be used in place of phpcs to automatically generate and fix all fixable issues. We highly recommend run following command to fix as many sniff violations as possible

$ vendor/bin/phpcbf /path/to/your/extension --standard=MEQP1

and

$ vendor/bin/phpcbf /path/to/your/extension --standard=MEQP2

If you are building extension for Magento Marketplace then make sure you run the following command on your version before submitting the extension for technical review

$ vendor/bin/phpcs /path/to/your/extension --standard=MEQP2 --severity=10 --extensions=php,phtml

Here is the list of things our developers follow when they write custom Magento 2 code

  • Files MUST use only <?php tag.
  • Class names MUST be declared in StudlyCaps.
  • Class constants MUST be declared in all upper case with underscore separators.
  • Method names MUST be declared in camelCase.
  • Class constants MUST be declared in all upper case with underscore separators. For example:
     const VERSION = '1.0'; const DATE_PUBLISHED = '2019-05-27';
    
  • Code MUST use an indent of 4 spaces, and MUST NOT use tabs for indenting.
    N.b.: Using only spaces, and not mixing spaces with tabs, helps to avoid problems with diffs, patches, history, and annotations. The use of spaces also makes it easy to insert fine-grained sub-indentation for inter-line alignment.
  • PHP keywords MUST be in lower case.
  • The extends and implements keywords MUST be declared on the same line as the class name.
    class ClassName extends ParentClass implements ArrayAccess, Countable
    { }
    
  • Visibility MUST be declared on all properties.
    namespace VendorPackage; class ClassName
    { public $foo = null; private $fooPrivate = null; protected $fooProtected = null;
    }
    
  • Visibility MUST be declared on all methods.
  • Function argument list, there MUST NOT be a space before each comma, and there MUST be one space after each comma.
    namespace VendorPackage; class ClassName
    { public function foo($arg1, &$arg2, $arg3 = []) { // method body }
    }
    
  • An if structure looks like the following. Note the placement of parentheses, spaces, and braces; and that else and elseif are on the same line as the closing brace from the earlier body.
    if ($expr1) { // if body
    } elseif ($expr2) { // elseif body
    } else { // else body;
    }
    
  • A switch structure looks like the following.
    switch ($expr) { case 0: echo 'First case, with a break'; break; case 1: echo 'Second case, which falls through'; // no break case 2: case 3: case 4: echo 'Third case, return instead of break'; return; default: echo 'Default case'; break;
    }
    
  • A while statement looks like the following. Note the placement of parentheses, spaces, and braces.
    while ($expr) { // structure body
    }
    
  • A do while statement looks like the following. Note the placement of parentheses, spaces, and braces.
    do { // structure body;
    } while ($expr);
    
  • A for statement looks like the following. Note the placement of parentheses, spaces, and braces.
    do { // structure body;
    } while ($expr);
    
  • A foreach statement looks like the following. Note the placement of parentheses, spaces, and braces.
    foreach ($iterable as $key => $value) { // foreach body
    }
    
  • A try catch block looks like the following. Note the placement of parentheses, spaces, and braces.
    try { // try body
    } catch (FirstExceptionType $e) { // catch body
    } catch (OtherExceptionType $e) { // catch body
    }
    
  • Comment your classes and methods using php docblocks like @param, @returns, and @throws

    Class should look this -:

    /** * Order Status Api main class for creating invoice and shipping * * @category Scommerce * @package Scommerce_Custom * @author Sagar Nayyar * */
    namespace ScommerceCustomModel; /** * Class OrderStatus * @package ScommerceCustomModel */
    class OrderStatus
    {
    

    Constructor should look this -:

     /** * @param MagentoSalesModelServiceInvoiceService $invoiceService * @param MagentoSalesModelOrderShipmentFactory $shipmentFactory * @param MagentoFrameworkDBTransactionFactory $transactionFactory * @param MagentoSalesApiInvoiceRepositoryInterface $invoiceRepository * @param MagentoSalesModelOrderShipmentTrackFactory $shipmentTrackFactory * @param MagentoPaypalModelAdminhtmlExpressFactory $authorisationFactory */ public function __construct( MagentoSalesModelServiceInvoiceService $invoiceService, MagentoSalesModelOrderShipmentFactory $shipmentFactory, MagentoFrameworkDBTransactionFactory $transactionFactory, MagentoSalesApiInvoiceRepositoryInterface $invoiceRepository, MagentoSalesModelOrderShipmentTrackFactory $shipmentTrackFactory, MagentoPaypalModelAdminhtmlExpressFactory $authorisationFactory ) {
    

    Method should look this -:

     /** * This function will do validation as part of inventory transaction * @param $skuId string * @param $updatedQty int * @param $siteId string * @param $tDateTime datetime * @return $this * @throws MagentoFrameworkExceptionLocalizedException */ protected function initiateStockChange($skuId, $updatedQty, $siteId, $tDateTime) {