Skip to content

Latest commit

 

History

History
276 lines (180 loc) · 6.39 KB

README.md

File metadata and controls

276 lines (180 loc) · 6.39 KB

Magento 2 Coding Jumpstart

Magento and the LEMP Stack

Magento works on the LEMP stack, which consists of:

  • Linux: The OS that offers security and supports PHP.
  • NGINX: The web server that accepts incoming requests and forwards them to various stacks, notably PHP. It provides high performance and low memory usage.
  • MySQL: Used for database management.
  • PHP: A widely used programming language for backend development.

Other components include XML, Elasticsearch, and Redis.

Magento Project and Directory Structure

The most important directories in any Magento project are:

  • app/ – Contains custom modules and themes that you will build.
  • pub/ – Known as the web root, this is where the web server points. The entry point for web requests in Magento is pub/index.php.
  • var/ – Stores generated data such as cache files, logs, and session files.
  • vendor/ – Contains all third-party modules, including Magento core. You should avoid placing files here for long-term use, as this directory may be rebuilt from scratch multiple times.

Common Magento Development Tools

  • PHPStorm – The IDE recommended for Magento development.
  • Plugins – Magento PHPStorm, Xdebug.

Creating a Route in Magento

Every Magento URL consists of three parts:

/<frontName>/<controllerName>/<actionName>

Let's break it down:

  • Front Name: The start of the request, associated with a specific module.
  • Controller Name: Determines the class handling the request.
  • Action Name: Specifies the method responsible for processing the request.

Defining the Route

Routes in Magento are defined using XML. Magento has two main areas:

  • frontend – Handles the storefront.
  • adminhtml – Handles the admin panel.

To create a frontend route, navigate to:

app/code/Macademy/Jumpstart/etc/frontend/

Create a new file named routes.xml with the following format:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="jumpstart" frontName="jumpstart">
            <module name="Macademy_Jumpstart"/>
        </route>
    </router>
</config>

This ensures that Magento listens to requests at /jumpstart.


Creating a Magento Controller

The Controller Name corresponds to a class in the Controller folder of your module.

Steps:

  1. Create a new directory for your module's controller:

    app/code/Macademy/Jumpstart/Controller/
    
  2. Inside this directory, create a subdirectory named after the controller name:

    app/code/Macademy/Jumpstart/Controller/Index/
    
  3. Create the Action Class inside the Index folder:

    app/code/Macademy/Jumpstart/Controller/Index/Index.php
    

Dependency Injection in Magento

Dependency Injection (DI) is a way to manage class dependencies and make code more modular and testable.

Using the new Keyword

A PHP class can rely on other classes using the new keyword:

<?php

declare(strict_types=1);

namespace Macademy\Jumpstart\Model;

class Product
{
    private Category $category;

    public function __construct()
    {
        $this->category = new Category();
    }

    public function getCategoryName(): string
    {
        return $this->category->getName();
    }
}

However, using new creates tightly coupled code, making it harder to test and modify.

Using the Magento Object Manager

Instead of manually instantiating objects, Magento uses ObjectManager, which:

  • Centralizes object creation.
  • Allows for dependency injection.
  • Increases flexibility and testability.

Constructor Property Promotion (PHP 8+)

Since Magento 2.4.4+ supports PHP 8, we can use constructor property promotion to simplify our code.

Before (PHP 7.4):

<?php

declare(strict_types=1);

namespace Macademy\Jumpstart\Model;

class Product
{
    private Category $category;

    public function __construct(Category $category)
    {
        $this->category = $category;
    }

    public function getCategoryName(): string
    {
        return $this->category->getName();
    }
}

After (PHP 8+):

<?php

declare(strict_types=1);

namespace Macademy\Jumpstart\Model;

class Product
{
    public function __construct(private Category $category) {}

    public function getCategoryName(): string
    {
        return $this->category->getName();
    }
}

This reduces boilerplate code while maintaining the same functionality.


Interfaces in Magento

An interface defines a contract for a class, enforcing method consistency across different implementations.

Example:

Instead of relying directly on the Category class, we define an interface:

<?php

declare(strict_types=1);

namespace Macademy\Jumpstart\Api;

interface CategoryInterface
{
    public function getName(): string;
}

Now, any class implementing this interface must define the getName() method.


Class Preference and Service Contracts

Magento uses dependency injection configuration (di.xml) to specify class preferences.

Example di.xml configuration:

<preference for="Macademy\Jumpstart\Api\CategoryInterface"
            type="Macademy\Jumpstart\Model\Category"/>

Why Use Service Contracts?

  • Promotes loose coupling between modules.
  • Makes replacing implementations easier.
  • Allows for future flexibility (e.g., switching data sources without breaking code).

Standard Page Response in Magento

Instead of terminating execution with echo, Magento provides a layout system for rendering pages.

Injecting PageFactory

To generate a page response, we inject PageFactory into our controller:

<?php

declare(strict_types=1);

namespace Macademy\Jumpstart\Controller\Index;

use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\View\Result\Page;

class Index implements HttpGetActionInterface
{
    private PageFactory $pageFactory;

    public function __construct(PageFactory $pageFactory)
    {
        $this->pageFactory = $pageFactory;
    }

    public function execute(): Page
    {
        return $this->pageFactory->create();
    }
}

This ensures that our controller returns a properly structured Magento page.