ORM

  • Means by which data is persisted from objects to a relational database
  • Magento's ORM is built around models, resource models and resource collections
    • Models: Data and behaviour
    • Resource Models: Maps data for storage
    • Collections: Groups of models, as well as filtering, sorting and paging
    • Resources: Database connection adapters

Models

  • Models only can manpulate data
  • Models don't concern themselves with data persistence
    • Models' load(), save(), delete() methods are deprecated
  • Persisted Models must extend Magento\Framework\Model\AbstractModel
    • In the _construct() method, a link to the Resource Model class is specified with $this->_init('Namespaced\Path\To\ResourceModel')

Resource Models

  • Resource Model contains the primary ID field name
    • The resource models' CRUD methods should be used to persist models
    • Resource Models extend Magento\Framework\Db\Adapter\Pdo, which extends Zend\Db
  • In the _construct() method, a link to the main table is specified with $this->_init('table_name', 'primary_key_column');

Collections

  • Implement Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
  • In the _construct() method, a link to the Model and Resource Model is specified with $this->_init('Namespaced\Path\To\Model', 'Namespaced\Path\To\ResourceModel');
  • Provide methods
    • addFieldToFilter()
    • getConnection()
    • getSelect()
    • addBindParam()
    • getIdFieldName()
    • distinct()
    • addOrder()
    • setOrder()
    • unshiftOrder()
    • getItems()
    • getSize()
    • getSelectCountSql()
    • load()
    • resetData()
    • walk()
  • Records are lazy-loaded, the first time a list is accessed
  • Query operator maps
    • eq = =
    • neq = !=
    • like = like
    • nlike = not like
    • in = in
    • nin = not in
    • notnull = is NOT NULL
    • null = is NULL
    • gt = >
    • lt = <
    • gteq = >=
    • moreq = >=
    • lteq = <=
    • finset = find_in_set
    • from, to = >= and <=

CRUD Workflow

Loading Models

  • $resourceModel->load($modelId, $field = null)
    • A third parameter allows for loading by a non-ID attribute
    • EAV models should use loadByAttribute() instead
  • Models' _beforeLoad() method fires a model_load_before generically, and also specifically for the model
  • Models' _afterLoad() method fires a model_load_after generically, and also specifically for the model
  • Useful methods
    • save()
    • isDeleted()
    • hasDataChanges
    • validateBeforeSave()
    • isSaveAllowed()
    • afterCommitCallback()

Install and Upgrade Scripts

  • Install scripts run once per module
  • Upgrade scripts are run after subsequent updates
  • Module version is set in (module)etc/module.xml root node's setup_version attribute
  • Versions are stored in the setup_module table
  • Installers implement Magento\Framework\Setup\Install(Data|Schema)Interface's install() method
  • Upgraders implement Magento\Framework\Setup\Upgrade(Data|Schema)Interface's upgrade() method
  • Should start with $installer = $setup; $installer->startSetup(); and end with $installer->endSetup();
  • Scripts are run only when bin/magento setup:upgrade is run

Making changes

  • Raw SQL as a parameter to the run() method
  • $installer->getConnection() contains
    • newTable()
    • createTable()
    • addConstraint()
    • dropTable()

EAV

  • EAV aims to make data storage across multiple website more flexible
  • Means the data is stored across multiple tables
  • Means values and attributes can be decoupled from their entities
  • Data types
    • Meta information: entity type, attributes per entity type, attribute set and groups
    • Content: entity records, attribute values

Tables

  • eav_entity_type contains
    • entity_type_id
    • entity_type_code
    • entity_table
    • default_attribute_set_id
    • increment_model
  • eav_attribute contains
    • attribute_id
    • entity_type_id
    • attribute_code
    • backend_type
    • backend_model
    • source_model
    • frontend_model
  • (entity_type)_entity contains
    • entity_id
    • entity_type_id
    • Any static attribute type values
  • (entity_type)_(backend_type) (int, decimal, varchar, text, datetime) contains
    • value_id
    • entity_type_id
    • entity_id
    • attribute_id
    • value

EAV Loading and Saving

  • Like flat table entities, EAV models extend Magento\Framework\Model\AbstractModel
  • EAV Resource Models however extend Magento\Eav\Entity\AbstractEntity
  • Magento\Eav\Entity\AbstractEntity provides
    • getAttribute() for getting an attribute by code or ID
    • saveAttribute() saves only that value, rather than the full entity
    • getWriteConnection()
    • getEntityTable()
  • Flat entities are loaded
    • $model->load()
    • $resourceModel->load()
    • (Resource table)
    • (Model table)
  • EAV entities are loaded
    • $model->load()
    • $resourceModel->load()
    • eav_entity_type and eav_attrbute
    • (EAV Attributes table)
    • (Attribute values tables)
    • (Attributes and Values)

Collections

  • EAV Collections have a few methods:
    • addAttributeToSelect() adds the attribute values table to the select and the value to the result
    • addAttributeToFilter() joins the attribute table to the join and allows filtering
    • joinAttribute() joins a value table from another entity's attribute

Attribute Management

  • Attribute columns include:

    • attribute_id
    • entity_type_id: for the entity type ID
    • attribute_code: A unique, human readable name
    • attribute_model: Optional model. Unspecified defaults to Magento\Eav\Model\Entity\Attribute
    • backend_model: Optional backend model. Unspecified defaults to Magento\Eav\Model\Entity\Attribute\Backend
    • backend_type: One of static, varchar, datetime, int, text, decimal
    • backend_table: Optional override for the value table
    • frontend_model: Alternative frontend model. Unspecified defaults to Magento\Eav\Model\Entity\Attribute\Frontend\DefaultFrontend
    • frontend_input: Input type for the admin
    • frontend_label: Default label for the admin
    • frontend_class: CSS class name for inputs
    • is_required: client-side validation, and validated on import
    • default_value: displayed if no value is specified
  • Setup scripts use Magento\Eav\Setup\EavSetup, providing:

    • addAttribute($entityType, $attributeCode, $dataArray)
    • updateAttribute($entityType, $attributeCode, $field, $value)
    • Fields are mapped using Magento\Eav\Model\Entity\Setup\PropertyMapperInterface::map()

Config Classes

  • Magento\Eav\Model\Config provides
    • getAttribute($entityType, $attributeCode) returns an attribute instance
    • getEntityType($entityTypeCode) returns an entity type instance

Attribute Models

  • Extend Magento\Eav\Model\Entity\Attribute\(Type)\Abstract(Type)
    • Where Type is one of Frontend, Backend, Source
    • Frontend provides
      • setAttribute($attribute)
      • getAttribute()
      • getInputType()
      • getLabel()
      • getLocalizedLabel()
      • getValue(\Magento\Framework\DataObject $object)
      • isVisible()
      • getClass()
      • getConfigField($fieldName)
      • getOption($optionId)
      • getInputRendererClass()
    • Backend provides
      • setAttribute($attribute)
      • getAttribute()
      • getType()
      • isStatic()
      • getTable()
      • getEntityIdField()
      • setValueId($valueId)
      • setEntityValueId($entity, $valueId)
      • getValueId()
      • getEntityValueId($entity)
      • getDefaultValue()
      • validate($object)
      • Multiple before- and after load and save
  • Magento\Eav\Model\Entity\Attribute\
    • Backend Hooks for save, load and delete
      • ArrayBackend
      • DateTime
      • DefaultBackend
      • Increment
      • Serialized
      • Store
      • Time\Created
      • Time\Updated
    • Source for select/multiselect attribute types
      • Boolean
      • Config
      • Store
      • Table
    • Frontend
      • DateTime
      • DefaultFrontend