Magento Development

From Crowfly

Jump to: navigation, search

The following are summary notes of Magento for Developers: Part 1—Introduction to Magento by Alan Storm, updated for Magento 1.12

Contents

Part 1

Code Area

Magento is MVC. The code contains Controllers, Models, Helpers, Blocks, and Routers

app/code/core
app/code/community
app/code/local

Package / Modules

Package is like a namespace for your company

app/code/local/<package>/<module>

Add modules to system

app/etc/modules/<package>_<module>.xml
    <models>
         <packagename>
              <class>Packagename_Modulename_Model</class>
        </packagename>
    </models>

Modules config.xml becomes part of systems large config tree

index.php

On does not edit index.php

index.php does the following

  1. Parse URL
  2. Routes - maps package/module/action to Controller method
  3. Dispatches

Routing

Zend Framework Like

http://example/catalog/category/view/id/25

module: catalog
front-controller: category
action: view
params: id=15

Routing methods:

  1. Routes in Config
  2. Routes in Admin (?)
  3. Mage_Cms_IndexController

Controllers

/apps/code/core/Mage/Catalog/controllers/CatalegoryController.php

All controllers extend Mage_Core_Controller_Front_Action Class. Note the term 'core' in that controller means there are two cores in the complete path: /app/code/core/Mage/Core/...

class Mage_Catalog_CategoryController extends Mage_Core_Controller_Front_Action
{
    public function viewAction()
    {
        //main entry point
    }
}

Add controllers to your module's config.xml

<frontend>
    <routers>
        <catalog>
            <use>standard</use>
            <args>
                <module>Mage_Catalog</module>
                <frontName>catalog</frontName>
            </args>
        </catalog>
    </routers>
</frontend>


Context-Based URI Model Loading

Mage::getModel('catalog/product');
Mage::helper('catalog/product');

Grouped Class Name, Aka. URI: 'catalog/product' Module: catalog Class: product

Models

ORM

$model = Mage::getModel('catalog/product')->load(27);
$price = $model->getPrice();
$price += 5;
$model->setPrice($price)->setSku('SK83293432');
$model->save();

Collections:

$products_collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter('price','5.00');

foreach($products_collection as $product)
{
    echo $product->getName();
}

addAttributeToSelect brings in EAV values.

Using Varien_Object's __call method:

$product->getPrice() and -->setPrice() methods gets and sets product.price column data.

$product->getData() returns array of all attributres.

Helpers

$helper = Mage::helper('catalog');  # same as ...
$helper = Mage::helper('catalog/data');

Most Helpers inherit form Mage_Core_Helper_Abstract, which gives you several useful methods by default.

$translated_output =  $helper->__('Magento is Great'); //gettext style translations
if($helper->isModuleOutputEnabled()): //is output for this module on or off?

Layouts

The "V" in MVC

Layout = nested/tree collections of "Block" objects. Block objects render bits fo HTML. They are *.phtml files. Block objects call Model methods.

Controller has to call

$this->loadLayout();
$this->renderLayout();

Think of Blocks as either Structure (ie. Head, body, multiple columns layout, etc), or as Content.

You can add blocks programmatically

public function indexAction()
{
    $this->loadLayout();
    $block = $this->getLayout()->createBlock('adminhtml/system_account_edit')
    $this->getLayout()->getBlock('content')->append($block);
    $this->renderLayout();
}

But more commonly, in layout.xml

<catalog_category_default>
    <reference name="left">
        <block type="catalog/navigation" name="catalog.leftnav" after="currency" template="catalog/navigation/left.phtml"/>
    </reference>
</catalog_category_default>

Module: catalog
Controller: category
Action: default

Nested Blocks

<catalog_category_default>
    <reference name="left">
        <block type="catalog/navigation" name="catalog.leftnav" after="currency" template="catalog/navigation/left.phtml">
            <block type="core/template" name="foobar" template="foo/baz/bar.phtml"/>
        </block>
    </reference>
</catalog_category_default>

You'd be able to call $this->getchildHtml('foobar'); from the Block object.

Observers

Observers listen to events

<events>
    <customer_login>
        <observers>
            <unique_name>
                <type>singleton</type>
                <class>mymodule/observer</class>
                <method>iSpyWithMyLittleEye</method>
            </unique_name>
        </observers>
    </customer_login>
</events>
class Packagename_Mymodule_Model_Observer
{
    public function iSpyWithMyLittleEye($observer)
    {
        $data = $observer->getData();
        //code to check observer data for our user,
        //and take some action goes here
    }
}

Class Overrides

Monkey Patching Core

Clone and add functionality to Mage/Catalog Product Model. One does not clone an entire module, only individual classes, as needed.

class Packagename_Modulename_Model_Foobazproduct extends Mage_Catalog_Model_Product
{
    public function validate()
    {
        //add custom validation functionality here
        return $this;
    }

}

In the config.xml:

<models>
    <!-- does the override for catalog/product-->
    <catalog>
        <rewrite>
            <product>Packagename_Modulename_Model_Foobazproduct</product>
        </rewrite>
    </catalog>
</models>

Part 2

Config

Config describes modules, models, classes, templates, etc.

Claims to provide great flexibility - however I find it way overly abstracted and unnecessary. Compare it to Rails, or Django

New Module

/app/code/local/Tommiecopper/Configviewer/Block
/app/code/local/Tommiecopper/Configviewer/controllers
/app/code/local/Tommiecopper/Configviewer/etc
/app/code/local/Tommiecopper/Configviewer/Helper
/app/code/local/Tommiecopper/Configviewer/Model
/app/code/local/Tommiecopper/Configviewer/sql

Package: Tommiecopper
Module: Configviewer

Need to add these two files, too:

app/code/local/Tommiecopper/Configviewer/etc/config.xml
<config>
    <modules>
        <Tommiecopper_Configviewer>
            <version>0.1.0</version>
        </Tommiecopper_Configviewer>
    </modules>
</config>

And

app/etc/modules/Tommiecopper_Configviewer.xml
<config>
    <modules>
        <Tommiecopper_Configviewer>
            <active>true</active>
            <codePool>local</codePool>
        </Tommiecopper_Configviewer>
    </modules>
</config>

Clear cache

System > Configuration > Advanced > Disable modules output: verify you see the new module.

Create Module Config

<config>
    <modules>...</modules>
    <global>
        <events>
            <controller_front_init_routers>
                <observers>
                    <Tommiecopper_configviewer_model_observer>
                        <type>singleton</type>
                        <class>Tommiecopper_Configviewer_Model_Observer</class>
                        <method>checkForConfigRequest</method>
                    </Tommiecopper_configviewer_model_observer>
                </observers>
            </controller_front_init_routers>
        </events>
    </global>

</config>

Part 3

Magento Controllers

Part 4

According to : Divante

The view layer in magento itself implements the MVC pattern

M - Blocks    - /app/code/local/Tommiecopper/Configviewer/Block/product.php
V - Templates - /app/design/frontent/enterprise/tctwo/templates/product.phtml
C - Layouts   - /app/design/frontent/enterprise/tctwo/layouts/product.xml


According to Alan Storm:


Layouts, Blocks, and Templates

Magento View components = Blocks and Templates

Controller does NOT pass variables to the View - The View components call module methods directly.

Blocks = PHP objects
Templates = HTML + PHP

$this refers to the Template's Block object.

Nested Blocks

app/design/frontend/base/default/template/page/1column.phtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $this->getLang() ?>" lang="<?php echo $this->getLang() ?>">
<head>
<?php echo $this->getChildHtml('head') ?>
</head>
<body class="page-popup <?php echo $this->getBodyClass()?$this->getBodyClass():'' ?>">
    <?php echo $this->getChildHtml('content') ?>
    <?php echo $this->getChildHtml('before_body_end') ?>
    <?php echo $this->getAbsoluteFooter() ?>
</body>

Layout

app/design/frontend/base/default/layout/local.xml
<layout version="0.1.0">
    <default>
        <block type="page/html" name="root" output="toHtml" template="magentotutorial/helloworld/simple_page.phtml" />
    </default>
</layout>

Personal tools