Magento is an open-source e-commerce platform written in PHP; a highly customizable e-commerce platform and content management system that can be used to build online stores for selling merchandise.
It provides common e-commerce features, such as shopping carts and inventory management, and encourages extensive customization to meet organization’s specific goals.
Magento is also an object-oriented PHP Framework that can be used to develop modern, dynamic web applications that tap into Magento's eCommerce features.
The major characteristics of Magento platform are:
Get formatted images url and avoid theme dependences.
exceptions.log
no matter if logging is enabled in configuration.Logging can be enabled by logging into Magento Admin and proceeding to:
Enabled
dropdown list.Even though documentation defines that message should be a string, if an array is passed there's a code block in that method to take care of that with print_r
:
if (is_array($message) || is_object($message)) {
$message = print_r($message, true);
}
If the level parameter is set to null then DEBUG level is taken.
$level = is_null($level) ? Zend_Log::DEBUG : $level;
The levels are declared in file: lib\Zend\log.php
const EMERG = 0; // Emergency: system is unusable
const ALERT = 1; // Alert: action must be taken immediately
const CRIT = 2; // Critical: critical conditions
const ERR = 3; // Error: error conditions
const WARN = 4; // Warning: warning conditions
const NOTICE = 5; // Notice: normal but significant condition
const INFO = 6; // Informational: informational messages
const DEBUG = 7; // Debug: debug messages
Constants in form of Zend_Log::INFO
or integer number in range specified above can be passed as log level parameter.
/var/log/
Typically the system.log and exception.log file will exist in the
/var/log/
folder. These contain most of the information you will need. You can check to see if these are enabled and what the names of the exception and system log are by going toSystem > Configuration > System > Developer > Log Settings
.
/var/report/
Report files are generated in this folder after a user has encountered an error. Each file only includes the details for one error. These are used in order to hide the error details from the public. On the error page there will be a report number which is a reference to the corresponding file with the same name in the
/var/report/
folder.
Modules exist to be extended. You cannot change the app/code/
files without prohibiting any future updates. Instead we add a module to the app/code/local
directory (the local directory may be missing, if so, it needs to be manually created. This is common in later versions of Magento) for added custom local functionality.
All Module config files begin with a <config>
tag. The new module is declared inside of the <modules>
tag. We will be calling a module named YOUR_COMPANY_HelloWorld, therefore the <YOUR_COMPANY_HelloWorld>
tags are used. In here we define the version (very first = 0.0.1)
A list of XML events can be found at: http://www.magentocommerce.com/wiki/5_-_modules_and_development/reference/module_config.xml
If you are having any trouble then check out: http://coding.smashingmagazine.com/2012/11/30/introducing-magento-layout/
MAGENTO_ROOT/shell
php -f indexer.php help
abstract.php
indexer.php
compiler.php
log.php
Sometimes we need to access Magento outside of a webbrowser to ommmit execution times or set different things that won't affect the frontend.
There are 2 ways to bootstrap Magento but only one is the Magento way. Read more above in examples section.
Filter Comparison Arguments
Magento also offers a flexible way of filtering using comparison operators as well. Here is a list of valid operators and their syntax:
All comparison arguments can be passed to the second parameter of either the addFieldToFielter()
or addAttributeToFilter()
methods.
$collection_of_products->addAttributeToFilter('visible',array("eq"=>1));
Comparison | Argument Array | Resulting SQL Snippet |
---|---|---|
Equals | array("eq"=>$var) | WHERE (`my_field` = $var) |
Not Equal | array("neq"=>$var) | WHERE (`my_field` != $var) |
Like | array("like"=>$var) | WHERE (`my_field` LIKE $var) |
Not Like | array("nlike"=>$var) | WHERE (`my_field` NOT LIKE $var) |
Is | array("is"=>$var) | WHERE (`my_field` IS $var) |
In | array("in"=>$var) | WHERE (`my_field` IN($var)) |
Not In | array("nin"=>$var) | WHERE (`my_field` NOT IN($var)) |
Null | array("null"=>true) | WHERE (`my_field` IS NULL) |
Not Null | array("notnull"=>true) | WHERE (`my_field` IS NOT NULL) |
Greater Than | array("gt"=>$var) | WHERE (`my_field` > $var) |
Less Than | array("lt"=>$var) | WHERE (`my_field` < $var) |
Greater Than or Equal | array("gteq"=>$var) | WHERE (`my_field` >= $var) |
Less Than or Equal | array("lteq"=>$var) | WHERE (`my_field` <= $var) |
Find in Set | array("finset"=>array($var)) | WHERE (find_in_set($var,`my_field`) |
From and To | array("from"=>$var1, "to"=>$var2) | WHERE (`my_field` >= $var1 AND `my_field` <= $var2) |
https://gist.github.com/arosenhagen/2397824
Many many snippets very helpful
Entity
Stores information about the type of the data being stored. In the case of Magento this is customer, product, category, etc.
Attribute
The individual properties of each of the entities, e.g. name, weight, email address etc.
Value
The value of a given entity and attribute. For example, we may specify the customer entity and the email attribute and then give it the value [email protected].
Database Schema
eav_entity
The entity table.
eav_entity_attribute
The attribute table.
eav_entity_{type}
The values tables. Types are datetime, decimals, int, text and varchar.
Important to note that eav_entity_varchar table has the type varchar for values even if date or integer would suit the value better.
Models Versus Resource Models
All the models inside Mage/Eav/Model/Resource are Mysql4 and are resource models.
In addition Entity/Abstract.php and Entity/Setup.php.
Flat Versus EAV
The EAV models are more complex, providing logic to save and load from multiple tables, whereas the flat or standard models are relatively straightforward (traditional).
Standard models mainly manage their properties with data setters and getters working with a single table. EAV models mainly manage their attribute models. Standard models only save their data to a table and load from it. EAV models load all (or a specific set) attributes after loading base data and save attributes after saving data (including inserting, updating and deleting attributes).
EAV Resource Model Examples
To find entities using the EAV storage schema searching for the string extends Mage_Eav_Model_Entity_Abstract can be used. This should reveal all resource models based on the EAV structure. However, the resulting list will include many obsolete classes from the Mage_Sales module that no longer are being used.
The only modules containing entities using the EAV storage schema are Mage_Catalog (categories and products) and Mage_Customer (customers and addresses).
Customer Groups use the flat table storage schema. All the sales entities where converted to flat table entities with the release of Magento 1.4.
The reason that EAV is used is so that entities can have an undetermined number of properties and therefore remain flexible. For example, when you add a new attribute to a Customer entity (which is an EAV entity), the database table does not need to be altered for this new attribute to be added.
Advantages
Flexibility Database schema doesn’t need to change with the model Quick to implement
Disadvantages
A query returning 20 columns normally would consist of 20 self joins in EAV. However, the Mage_Eav module generally does not use joins to load the attribute value data. Instead union selects are used. Joins are only used for filtering EAV collections.
Website and Store Scopes
To handle website and store scope attribute values within EAV, a store_id value exists on the catalog entity to show scope which links back to core_store. Along with the normal stores (store views) there is also a store ‘0’ which is the global value. When on a particular store, the system will first check for an entity value on the current store and then fall back to the global entity. Mage_Customer EAV entities do not have a store_id scope column.
Insert, Update and Delete
To determine if an insert, update or delete needs to be performed on an attribute, a comparison is made against the original object. The original object is basically a duplicate of the data object when the entity was retrieved from the database.
Attribute Management
Attribute Models
Attribute Model Represents the attribute in the database form, its logic is standard across all attributes and is difficult to change.
Frontend Model
The attribute’s interface to the frontend and provides any logic that the attribute requires on the frontend, e.g. the getUrl() method on images.
Backend Model
These perform validation on the attribute before it is saved to the database. For example, the password backend model converts the password into a hash before it is saved. It also checks that the password and password confirmation match before saving.
Source Models
Used to populate the options available for an attribute, e.g. catalog/product_status has enabled and disabled.
Required Methods
A source model requires:
<?php
public function getAllOptions();
public function getOptionText($value);
?>
Usually only getAllOptions() needs to be implemented though since an implementation for getOptionText() already exists in the abstract source model Mage_Eav_Model_Entity_Attribute_Source_Abstract.
A frontend model does not require the method getValue().
A backend model requires:
<?php
public function getTable();
public function isStatic();
public function getType();
public function getEntityIdField();
public function setValueId($valueId);
public function getValueId();
public function afterLoad($object);
public function beforeSave($object);
public function afterSave($object);
public function beforeDelete($object);
public function afterDelete($object);
public function getEntityValueId($entity);
public function setEntityValidId($entity, $valueId);
?>
All these methods are implemented in the abstract backend model Mage_Eav_Model_Entity_Attribute_Backend_Abstract. For custom backend models only the methods requiring customisation need to be overridden.
System Configuration Source Models
Cannot be used for EAV attributes. EAV source models implement the getAllOptions method while adminhtml source models implement the toOptionArray() method.
Default system configuration source models can be found in Mage/Adminhtml/Model/System/Config/Source/.
Attribute Source Models
The purpose of Attribute Source Models is to supply the list of options and values for select and multiselect attributes. They also supply the column information to the catalog flat table indexer if required.
To get a list of all options for an attribute, perform the following:
<?php
$options = $attribute->getSource()->getAllOptions(false);
// or for admin
$options = $_attribute->getSource()->getAllOptions(true, true);
?>
Default Attribute Models
If no class is specified as a frontend, backend or - for select or multiselect attributes - source models, a default class is used.
The default attribute frontend model is Mage_Eav_Model_Entity_Attribute_Frontend_Default.
The default attribute backend model depends on the attribute code and is determined in the method Mage_Eav_Model_Entity_Attribute::_getDefaultBackendModel().
<?php
protected function _getDefaultBackendModel()
{
switch ($this->getAttributeCode()) {
case 'created_at':
return 'eav/entity_attribute_backend_time_created';
case 'updated_at':
return 'eav/entity_attribute_backend_time_updated';
case 'store_id':
return 'eav/entity_attribute_backend_store';
case 'increment_id':
return 'eav/entity_attribute_backend_increment';
}
return parent::_getDefaultBackendModel();
}
?>
If the method falls through to the last line Mage_Eav_Model_Entity_Attribute_Backend_Default is used.
The default source model is set in Mage_Eav_Model_Entity_Attribute_Source_Table. This is set in the catalog modules attribute model. The default config source model specified in the eav module is never used.
Add Attribute
To add EAV attributes, use Mage_Eav_Model_Entity_Setup by extending in the setup class.
addAttribute() Creates the attributes, add it to groups and sets (including default) , or updates if it already exists updateAttribute() Updates the attribute data only. Custom setup classes can be used to extend these methods, adding additional data or simplifying the arguments needed.
Flat Tables
Flat catalog attributes are managed by indexers:
Mage_Catalog_Model_Resource_Product_Flat_Indexer::updateAttribute() Mage_Catalog_Model_Resource_Category_Flat::synchronise() Product attributes get added to the flat table if they are (see Mage_Catalog_Model_Resource_Product_Flat_Indexer::getAttributeCodes()):
Static (backend type) Filterable Used in product listing Used for promo rules Used for sort by System Attributes There is a different flat table for each store, each one contains a different store-scoped entity attribute value. Multi-lingual values are managed by having different stores for each language.
Customising Core Functionality with Themes
Themes have layout files which, amongst other things, can be used to change which blocks appear on the page. The block template can also be changed and different methods called.
Store-level designs
Magento’s hierarchical structured themes means that a base theme can be extended and assigned on a store level.
Registering Custom Themes
Themes can be configured in three ways:
Package versus Theme
A package has multiple themes. Each of the themes in a package inherits from the default theme within a package.
Design Fallback
The theme fallback procedure for locating templates files is:
To add further directories to the theme fallback mechanism Mage_Core_Model_Design_Package::getFilename method need to be rewritten
For the admin area the fallback is default/default.
Template and Layout Paths
Blocks
Blocks are used for output. The root block is the parent of all blocks and is of type Mage_Page_Block_Html.
Mage_Core_Block_Template blocks use template files to render content. The template file name are set within setTemplate() or addData('template') with relative paths.
Templates are just pieces of PHP included in Mage_Core_Block_Template. Therefore $this in a template refers to the block.
Mage_Core_Block_Template uses a buffer before including a template to prevent premature output.
The Mage_Core_Model_Layout::createBlock method creates instances of blocks.
The Mage_Core_Model_Layout_Update class considers which blocks need to be created for each page by looking at the layout handles.
All output blocks are rendered, e.g. by calling toHtml(), which in turn can choose to render their children.
Text and Text_List blocks automatically render their content.
There are two events that are fired around block rendering that can be used to modify the block before and after rendering the HTML:
core_block_abstract_to_html_before core_block_abstract_to_html_after A child block will only be rendered automatically if it is of class Mage_Core_Block_Textlist otherwise the getChildHtml method needs to be called.
Block instances can be accessed through the layout, e.g. Mage::app()->getLayout() and $controller->getLayout(). Block output is controlled by the _toHtml() function.
Templates are rendered by the renderView()/fetchView() methods inside a template block. Output buffering can be disabled with $layout->setDirectOutput.
It is possible to add a block to the current layout but it needs to be done before the renderLayout() method is called.
Layout XML
<reference>
-edit a block
<block>
- define a block
<action>
- call method on a block
<update>
- include nodes from another handle.
Layout files can be registered in config.xml:
<config>
<{area}>
<layout>
<updates>
<{name}>
<file>{filepath}</file>
</{name}>
</updates>
</layout>
</{area}>
</config>
Page output can be customised in the following ways:
Head Block Assets
JavaScript and CSS assets are handled in the Mage_Page_Block_Html_head block. This block handles the merging of assets into a single file to minimise HTTP requests. The merged file is based on the edit time of the source files.
When merging CSS, a callback function on Mage_Core_Model_Design_Package is called to update any @import or url() directives with the correct URLs
There are six different product types built-in to Magento.
A single stock unit
First of the composite products. Allow customers to configure their product and add a single simple product to basket.
The second composite product, a grouped product relates simple products and provides customers with the ability to choose quantities of each item.
The third composite product type , a bundle relates simple products together to purchase as a single item.
No physical item required for delivery, e.g. services
A digital rather than physical product. Most product types are implemented as part of the Mage_Catalog module, apart from Mage_Bundle and Mage_Downloadable.
Grouped, Bundle and Configurable products implement a parent-child relationship where a number of other (by default, simple, virtual or downloadable) products get assigned to a main product. This then handles the product data for the whole collection (e.g. group, bundle, or configurable product name, price and status).
Downloadable and Bundle products have extra tables in the database, meanwhile the rest are shared amongst all other product types. Configurable products have an extra table to link to child products, catalog_product_super_link.
Custom Product Type
To create a product type that extends one of the built-in product types, the corresponding product type model should be extended. Otherwise the new product type should extend the Mage_Catalog_Model_Product_Type_Abstract class.
An entry in the module’s config.xml is also required:
More complicated products may require other customised areas such as price model and index data retriever.Price Calculation
When dealing with a single product, the price is always calculated on the fly. The price EAV attribute is loaded with the product and final price is calculated by the price model, Mage_Catalog_Model_Product_Type_Price.
Some product types deal with it differently. In which case they extend this class and implement their own logic. For example, the configurable product overwrites getFinalPrice() and adds additional logic. This custom model can then be specified in config.xml with a <price_model> tag.
Product collections, however, use the price index to retrieve pre-calculated prices, eliminating the need to calculate it for each product.
Final price can be adjusted by the observers of the catalog_product_get_final_price event. By default, only the Mage_CatalogRule module observes this event.
Another method to override produce price is to simply set it on the product. If the price is set, the product will not recalculate it.
Product tier price is separate from normal price (although taken into account when calculating price). It’s implemented as a list with a customer group and minimum quantity qualifiers for each tier. Tier prices are displayed in a table, using the catalog/product/view/tierprices.phtml template.
Custom product options get processed when calculating final price. Each option has its own price defined, which gets added to the final price.
Group, tier and special prices all get considered at the same time ($priceModel->getBasePrice())
and the smallest one of the three (or four if you include the regular price) is chosen as the base product price.
Tax
The Mage_Tax module uses a product’s tax class and whether or not the product price is inclusive or exclusive of tax in order to identify the correct rate to apply.
The following factors are used to calculate tax on products:
Layered Navigation
The classes responsible for rendering the layered navigation are:
Mage_Catalog_Block_Layer_View
-Handles the filters and options
Mage_Catalog_Block_Layer_State
-Controls what is currently being filtered by
To implement layered navigation on attributes with custom source models the Mage_Catalog_Model_Layer_Filter_Abstract::apply() method would need to be overwritten to dictate how the product collection should be filtered.
Layered navigation is rendered by the Mage_Catalog_Block_Layer_View and Mage_Catalog_Block_Layer_State blocks, which use filter blocks for individual filters.
Layered Navigation uses index table for most filters, e.g. price, product attribute index, decimal product index.
Categories
Categories in the Database
Category hierarchy is managed by storing a category’s parent id. The full hierarchy is shown in the path column (slash separated IDs). There is a special category with parent_id of 0. This is the true root category and each of the other root categories as defined in Magento use this as a shared parent.
To read and manage a category tree from the database two different classes are used depending if flat catalog is enabled, Mage_Catalog_Model_Resource_Category_Tree and Mage_Catalog_Model_Resource_Category_Flat.
The advantage of flat categories is that it is quicker to query. However, it needs to be rebuilt from the EAV tables each time there is a change.
getChildren()
returns a comma separated string of immediate children IDs
getAllChildren()
returns a string or array of all children IDs
getChildrenCategories()
returns a collection of immediate children categories N.B. If flat catalog is enabled, the only child categories returned will be ones with include_in_menu = 1. In both cases, only active categories are returned.
Catalog Price Rules
Catalog price rules apply discounts to products based on the date, product, website and customer group.
When getFinalPrice()
is called on a product, the event catalog_product_get_final_price is fired. This is observed by Mage_CatalogRule_Model_Observer which will then look for any catalog price rule that applies to the product. If applicable, it then looks at the database price table and writes the price back to the product model as a Varien data field final_price.
Within the database, the catalogrule table describes rules, their conditions and their actions. catalogrule_product contains the matched products and some rule information. Meanwhile catalogrule_product_price contains the price after the rule has been applied.
Indexing and Flat Tables
Flat catalog tables are managed by catalog indexers. If automatic rebuilding of the indexes is enabled, the catalog indexers get rebuilt every time a product, category or any related entities are updated. The _afterSave() method calls the indexer process. Otherwise they have to be manually re-indexed through admin.
Product type affects price index and stock index where products can define their own custom indexers (in config.xml) to handle their data for these indexes.
The Mage_Index module provides the framework with which custom indexes can be created to help optimise the performance of the site. The Mage_Index_Model_Indexer_Abstract class should be extended to create a new index, implementing the _registerEvent() and _processEvent() methods. Not forgetting to register it in config.xml:
<global>
<index>
<indexer>
<{name}>{model}</{name}>
</indexer>
</index>
</global>
MVC stands for Model-View-Controller. Any application that separates it’s data access, business logicand user interface is called MVC. There can be two types of MVC: convention-based and configuration-based. Example, cakePHP is convention-based, i.e. you just need to follow the instructions of the core system to get your module ready in just few lines. Magento is configuration-based, i.e. you need to specify each and every thing to your module’s config file in order to get it work. Magento has Controller (for Routing), Block, Model and Template file. How Magento’s MVC works: