The EAV is a data model that is used in Magento to provide flexibility in the description of characteristics of a product or a collection of products. So having this flexibility you do not have the need to change the structure of your database design in any new attribute that added by the merchant.

  • Entity  represents data items and the records are stored  in table eav_entity_attribute and there are eight types of these records
    • customer
    • customer address
    • catalog category
    • catalog product
    • catalog product
    • invoice
    • creditmemo
    • shipment
  • Attribute are data items that describe entity record like SKU, description
  • Value is the assign that an attribute is taken from a possible set of attributes

A simple  ER diagram on this model and the attributes are stored in database design is the following, so you can understand basic definitions like

  • attribute set
  • attribute group
  • attribute

Despite the advantage of having this type of flexibility one of the downsides is the system may have a slow performance on high traffic will have to be supported by cache mechanism

 In this can setup specific rules like discounts that can apply in specific categories of the catalogue or to products with specific attributes

In the admin panel to take a look at the attribute default set will have to go

Admin -> stores -> Attribute Set -> Default

Model View Controller (MVC)

Magento follows the ORM approach and there are two types of models (M) from MVC pattern, the first one is the simplest one, is the pattern of Active Record type that means that a model is a class for an object that represents data record from only one table. So if want to have a list of records you have a query a collection of models so when you create a new model

Usually, there are three files to manage data from the database

  • Model extends \Magento\Framework\Model\AbstractModel
    this file contains the database logic does not execute sql queries
  • Resource Model extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
    A resource model inherits and contains specialized functions to fetch data
    namespace Vontikakis\DataFirst\Model\ResourceModel;
    
    class DataBridge extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
    {
    	
    	public function __construct(
    		\Magento\Framework\Model\ResourceModel\Db\Context $context
    	)
    	{
    		parent::__construct($context);
    	}
    	
    	protected function _construct()
    	{
    		$this->_init('vontikakis_datafirst_databridge, 'databridge_id');
    	}
    	
    }
    
  • Collection Model extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection

CRUD

  • Magento\Framework\EntityManager\Operation\Read
  • Magento\Framework\EntityManager\Operation\Create
  • Magento\Framework\EntityManager\Operation\Update
  • Magento\Framework\EntityManager\Operation\Delete

The loading etc process for EAV models are handled by

CRUD in Attributes

Magento\Framework\EntityManager\Operation\AttributePool

  • Magento\Eav\Model\ResourceModel\CreateHandle
  • Magento\Eav\Model\ResourceModel\UpdateHandler
  • Magento\Eav\Model\ResourceModel\ReadHandler

EAV Attributes in the general structure

IN EAV there 3 types of models the backend models that perform create, update, delete, read, existing operations and validation of attributes. The source model that provide the list for dropdown and multi-select attributes. Finally, the frontend model that map the attributes to the template.

If we want to add new attribute to a product like a multi select field usually we have to make a Database Migration that is used to change the structure of a database but as we previously mention EAM model exist in a fixed number of MySQL tables in the sense of a virtual DB, so we only will add some data that describe columns and datatype using a migration script.

class InstallData implements InstallDataInterface
{
   protected $eavSetupFactory;
public function __construct(EavSetupFactory $eavSetupFactory) { $this->eavSetupFactory = $eavSetupFactory; } public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context) { $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]); $eavSetup->addAttribute( \Magento\Catalog\Model\Product::ENTITY, 'recommended_price', [ 'type' => 'decimal', 'label' => 'Recommended Price', ...... ] ); }

Migration is like a versioning tool to track changes in a database but in our case is versions o EAV model. We will execute this script using a command from the Magento CLI tool so we perform this installation task.

php bin/magento setup:upgrade

When to use EAV architecture

There is functionality in admin to change the storage between EAV and flat tables from but it's best to use EAV in a new entity when

  • The scope should be included in Entity
  • Other modules or Managers could add new attributes to an entity from the admin panel or change the data types to existing one
  • The number of attributes for a specific entity needs to be more than 1017 because in a flat table in MySQL this is limit of number columns in a table.
  • If the indexes of INDEX type need to be more than 64

Pricing and Products

As we mention above attributes describe characteristics of a product there are some default attributes one of the most important is the Price. The price and its generation process are subject to many rules that can be adjusted by managers in the admin panel. First, before dive in pricing let's mention the 6 types of product

  1. Simple Product: it is the simplest form a product a single SKU it is physical has weight.
  2. Virtual Product: usually are not physical products like subscriptions, membership, services, etc.
  3. Configurable Product: this type is a collection of simple products with different options such as size and color in our SaaS these options we call them variants of a product.
  4. Grouped Product: when you want to buy products in groups within a lower price it all the products on the same page
  5. Bundle Product: can be purchased only all together with the price, SKU, quantity can be fixed or dynamic.
  6. Download Product: usually are in digital format like video, software when someone makes a purchase he can download them from a link

If you want to obtain a specific type of product this is stored to catalog_product_entity.type_id field so when we query the catalog in ORM functions we can filter the collections searching for only virtual products using

 

$productCollection->addFieldToFilter('type_id', 'virtual');

 

Final Price is the one that is used when the products are added to the cart and also depends on the product type. After we see the source code for the final price let's give some definitions of the price

 Magento\Catalog\Model\Product\Type\Price

  • Configurable Price: is the default price for all options of a simple product but you can set up different price to children products like XL size item may higher price than a medium size item
  • Downloadable Price
  • Grouped Price: It is a set of simple products where if the purchased all together may exist a lower total price compare to the case that they purchased individually
  • Bundle Price: This is similar to grouped products but with the difference that the seller can choose from options (size, color) to add to the cart.
  • Catalog Rule Price Modifier: In this can set up specific rules like discounts, start and end date  that applies the rules, application in specific categories of the catalog or to products with specific attributes
    • Base Price
      • min Special Price: In this case a price with discount in a fixed time duration
      • min Tier Price: in this case, a discount can be applied to the product if the user buys above the lower quantity of this product

Price Generation Process

There are various methods to change and modify the price process

  • New Virtual Price Type. A virtual type is a way to change the dependencies and arguments that are injected to another class. It is constructor dependency injection that is defined to di.xml files. Let's take the example that we want to add a new field called Recommended Price in admin, first, we will add new price as an attribute as described in the previous section "EAV Attributes in general structure" using an installData class. Assuming that we done that we will add a new price by extend BasePriceProviderInterface and AbstractPrice class.
    use Magento\Framework\Pricing\Price\AbstractPrice;
    use Magento\Framework\Pricing\Price\BasePriceProviderInterface;
    
    class RecommendedPrice extends AbstractPrice
    {
        const PRICE_CODE = 'recommended_price';
    public function getValue() { ... } }
    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <virtualType name="Magento\Catalog\Pricing\Price\Pool">
            <arguments>
                <argument name="prices" xsi:type="array">
                    <item name="recommended_price" xsi:type="string">Vontikakis\DataFirst\Pricing\Price\RecommendedPrice</item>
                </argument>
            </arguments>
        </virtualType>
    </config>
    
  • Plugin for overriding methods. Plugins in Magento are interceptors that means that they intercept and modify the behavior of public methods in a class. This technique that changes methods functionality in another php framework like the Yii framework is named Behavior and the general term in software engineering is mixin

    Let's take an example where the store owner wants to add 3$ to all units in the scenario that he wants to offer "free returns and shipping back to you" so the products in the online catalog may cost 3 unit hights will have to customize the getPrice()

    namespace Vontikakis\DataFirst\Plugin;
    use Magento\Catalog\Model\Product;
    
    class Product
    {
        public function afterGetPrice($subject,  $result)
        {
            return ($result+3);
        }
    }
  • Override Specific Type of Product
  • Override the price class

Quote

What is a quote? Quote the process that the system starts to track the activity of a user from the time that starts to add items to the cart until he ends his checkout process by abandoned the cart or place his order. So in quote includes information such customer contact data, shipping address, the products, the payment method, the shipping method and cost,  total price,  subtotal and discounts.

So All the tables in the DB that start with the prefix quote_  will store the data

  • quote
  • quote_address
  • quote_address_item
  • quote_id_mask
  • quote_item
  • quote_item_option
  • quote_item_payment
  • quote_shipping_rate

As  mention the quote includes all the relevant information about the order. One key part of this process of Totals. This is defined from the following class

Magento\Quote\Model\Quote\TotalsCollector

This class has some methods that calculate the total some in quote like the total price of items, total cost of shipping and the total price of an order per address.We can modify the process and our custom total model methods, to this we have to create a custom class that inherits from

\Magento\Quote\Model\Quote\Address\Total\AbstractTotal

Shopping Cart Rules

 
\Magento\SalesRule\Model\RuleFactory