magento

Topics related to magento:

Getting started with magento

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:

  • expandability
  • scalability
  • flexibility
  • customizability
  • open-source

Get Products from Database

Orders

Get store name and other details from system configuration

Specific urls

Getting Magento URLs

Get formatted images url and avoid theme dependences.

Current url

Get current User

Logging to file

The Logging is turned off by default unless developer mode is active.

All exceptions are logged in exceptions.log no matter if logging is enabled in configuration.

Logging can be enabled by logging into Magento Admin and proceeding to:

  • System > Configuration (top bar)
  • Developer (left menu)
  • Log Settings section
  • Select Yes from Enabled dropdown list.
  • Save Configuration in the right top corner.

Message variable type

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);
}

Log level

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.

Magento error handling, messages and reports

Error Log Locations

/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 to System > Configuration > System > Developer > Log Settings.

log settings area in Magento 1.x admin dashboard


/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.

example of Magento error page

Create Enterprise Gift Cards Programmatically

Module structure

Magento Caching

Shell, CLI

Basics

  • You need to have a Linux command line or connect using SSH to your server in order to use shell scripts.
  • Go to your MAGENTO_ROOT/shell
  • Script can be run by typing i.e.
php -f indexer.php help

Core shell methods by files

  1. abstract.php

  2. indexer.php

  3. compiler.php

  4. log.php

Custom php shell scripts

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.

How to Filter Collections

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));
ComparisonArgument ArrayResulting SQL Snippet
Equalsarray("eq"=>$var)WHERE (`my_field` = $var)
Not Equalarray("neq"=>$var)WHERE (`my_field` != $var)
Likearray("like"=>$var)WHERE (`my_field` LIKE $var)
Not Likearray("nlike"=>$var)WHERE (`my_field` NOT LIKE $var)
Isarray("is"=>$var)WHERE (`my_field` IS $var)
Inarray("in"=>$var)WHERE (`my_field` IN($var))
Not Inarray("nin"=>$var)WHERE (`my_field` NOT IN($var))
Nullarray("null"=>true)WHERE (`my_field` IS NULL)
Not Nullarray("notnull"=>true)WHERE (`my_field` IS NOT NULL)
Greater Thanarray("gt"=>$var)WHERE (`my_field` > $var)
Less Thanarray("lt"=>$var)WHERE (`my_field` < $var)
Greater Than or Equalarray("gteq"=>$var)WHERE (`my_field` >= $var)
Less Than or Equalarray("lteq"=>$var)WHERE (`my_field` <= $var)
Find in Setarray("finset"=>array($var))WHERE (find_in_set($var,`my_field`)
From and Toarray("from"=>$var1, "to"=>$var2)WHERE (`my_field` >= $var1 AND `my_field` <= $var2)

Helpers

Collections

Get category name from product page

Collections

Quick Task Cheat Sheet

https://gist.github.com/arosenhagen/2397824

Many many snippets very helpful

EAV (Entity Attribute Value)

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

  • Inefficient

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.

  • No mechanism for relationships between subtypes
  • No grouping of entity subtypes

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.

  • If the attribute exist originally and its new value is not empty; it updates.
  • If the attribute exist originally but its new value is set to empty; it deletes. - If the attribute doesn’t exist originally and its new value is not empty; it inserts.

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.

Rendering

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:

  1. Per store under System > Configuration > Design.
  2. Design change with time limits System > Design.
  3. Theme exceptions can also be set on a category and product level.

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:

  1. {package}/{theme}
  2. {package}/default
  3. base/default

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:

  • Template changes
  • Layout changes
  • Overriding blocks
  • Observers Variables on blocks can be set in the following ways:
  • Layout -Through actions or attributes
  • Controller -$this-getLayout()->getBlock()
  • Child blocks -$this->getChild()
  • Other -Mage::app()->getLayout()

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

Understanding product types

There are six different product types built-in to Magento.

  • Simple

A single stock unit

  • Configurable

First of the composite products. Allow customers to configure their product and add a single simple product to basket.

  • Grouped

The second composite product, a grouped product relates simple products and provides customers with the ability to choose quantities of each item.

  • Bundle

The third composite product type , a bundle relates simple products together to purchase as a single item.

  • Virtual

No physical item required for delivery, e.g. services

  • Downloadable

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:

  • Product tax class
  • The amount of tax already included
  • Billing and Shipping addresses
  • Customer tax class
  • Store settings

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 Structure

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:

  1. When you enter the URL (something like http://mysite.com/frontname/controller/method/param1/value1/param2/value2), this URL is intercepted by one PHP file called index.php which instantiates Magento application
  2. Magento application instantiates Front Controller object
  3. Further, front controller instantiates Router objects (specified in module’s config.xml, global tag)
  4. Now, Router is responsible to “match” the frontname which is in our URL
  5. If “match” is found, it sees controller name and method name in the URL, which is finally called.
  6. Now depending on what is written in action name (method name), it is executed. If any models are called in it, the controller method will instantiate that model and call the method in it which is requested.
  7. Then the controller action (method) instantiate the Layout object, which calls Block specified for this action (method) name (Each controller action name have block and template file associated with it, which can be found at app/design/frontend or adminhtml/namespace/module/layout/module.xml file, name of layout file (module.xml) can be found in config.xml of that module, in layout updates tag).
  8. Template file (.phtml) now calls the corresponding block for any method request. So, if you write $this->methodName in .phtml file, it will check “methodName” in the block file which is associated in module.xml file.
  9. Block contains PHP logic. It references Models for any data from DB.
  10. If either Block, Template file or Controller need to get/set some data from/to database, they can call Model directly like Mage::getModel(‘modulename/modelname’).

Collections

Add different price for multiple store using Magento SOAP API

Model

Optimizing Magento For Speed

Complete Product Collection

Product Image Urls

Sql script to delete test data

Store and Website Data

Custom Attributes