mm09.2 Magento Programming Introduction
Vortrag für mm09.2 am 02.11.2009 in ffm. Einführung in die Magento Modulprogrammierung
»
catalog_product_load_after
customer_save_before
sales_order_save_after
controller_action_predispatch_checkout_cart_index
Modulprogrammierung
mm09.2 in ffm
02.11.2009
von Vinai Kopp
Grundstruktur
Setup Scripte
Attribut hinzufügen:
Event Observer
Adminhtml Grid
Blocks & Layout XML
Dies & Das
Namespace
Modul Name
Zwei Dateien
app/etc/modules/Mm09_ViewCount.xml
app/code/local/Mm09/ViewCount/etc/config.xml
(Hallo Magento, ich bin ein Modul und will mitspielen!)
(...und auf diese Weise möchte ich mitspielen...)
<?xml version="1.0"?>
<config>
<modules>
<Mm09_ViewCount>
<version>0.1.0</version>
</Mm09_ViewCount>
</modules>
<global>
</global>
</config>
<?xml version="1.0"?>
<config>
<modules>
<Mm09_ViewCount>
<active>true</active>
<codePool>local</codePool>
<depends>
</depends>
</Mm09_ViewCount>
</modules>
</config>
Wegen app/code/local
Grundgerüst einer config.xml
Code Pool
Eine Setup Resource in die
config.xml eintragen
Namen für Setup Scripte
Das Setup Script
Version erhöhen
Reload zum Ausführen
<?xml version="1.0"?>
<config>
<modules>
<Mm09_ViewCount>
<version>0.1.0</version>
</Mm09_ViewCount>
</modules>
<global>
<resources>
<ViewCount_setup>
<setup>
<module>Mm09_ViewCount</module>
<class>Mage_Customer_Model_Entity_Setup</class>
</setup>
</ViewCount_setup>
</resources>
</global>
</config>
Name des Setup Verzeichnisses
Name des Moduls
Verzeichnis:
Modul Version
Mm09/ViewCount/sql/ViewCount_setup/
Install-Script:
Upgrade Script:
.../sql/ViewCount_setup/mysql4-install-0.1.0.php
.../sql/ViewCount_setup/mysql4-upgrade-0.1.0-0.1.1.php
-------------------------------------------------------- (siehe config.xml) --------------------------------------------------------
<?php
$this->startSetup();
$this->addAttribute('customer', 'product_view_count', array(
'label' => 'Product View Count',
'type' => 'int',
'visible' => 1,
'visible_on_front' => 0,
'required' => 0,
'user_defined' => 0, // or: 'group' => 'General',
'default' => 0
));
// $this->run("CREATE TABLE {$this->getTable('my_table')}") (...;
// $this->setConfigData('catalog/frontend/grid_per_page_values', '9,15,30'
$this->endSetup();
$this = <class>Mage_Eav_Model_Entity_Setup</class>
$installer = $this;
Konvention... aber der Sinn?
varchar, int, decimal, text, datetime
<version>0.1.0</version>
...
<version>0.1.1</version>
...
<version>0.1.2</version>
Nur bei Updates!
Die aktuelle Version eines Moduls
findet man in der Tabelle "core_resource"
Eintrag löschen = Install Script ausführen
Version herntersetzen = Upgrade Script(e) nochmal ausführen
Gotchas:
Cache
Cron-Jobs
Mage::log() broken
Liste mit Events: http://www.magentocommerce.com/wiki/customizing_magento_using_event-observer_method#Events
Die meistbenutzten Events
[model]_load_after
[model]_save_before
[model]_save_after
controller_action_predispatch_[module]_[controller]_[action]
Abstrakt
Beispiele
Observer Model
Config Eintrag
Gotchas
Konvention: .../Mm09/MostViewed/Model/Observer.php
app/
code/
local/
Mm09/
ViewCount/
<?xml version="1.0"?>
<config>
<modules>
<Mm09_ViewCount>
<version>0.1.0</version>
</Mm09_ViewCount>
</modules>
<global>
<models>
<ViewCount>
<class>Mm09_ViewCount_Model</class>
</ViewCount>
</models>
<resources>
<ViewCount_setup>
<setup>
<module>Mm09_ViewCount</module>
<class>Mage_Eav_Model_Entity_Setup</class>
</setup>
</ViewCount_setup>
</resources>
</global>
<frontend>
<events>
<controller_action_layout_render_before_catalog_product_view>
<observers>
<ViewCount>
<type>singleton</type>
<class>ViewCount/observer</class>
<method>controllerActionLayoutRenderBeforeCatalogProductView</method>
</ViewCount>
</observers>
</controller_action_layout_render_before_catalog_product_view>
</events>
</frontend>
</config>
Kurzbezeichnung
Check: ist das der längste Event Name?
Der Name für die Methode kann frei vergeben werden...
Kann frei vergeben werden...
muss für den jeweiligen Event unique sein
Wird gemapped auf
app/code/local/Mm09/ViewCount/Model/
<?php
class Mm09_ViewCount_Model_Observer
{
public function controllerActionLayoutRenderBeforeCatalogProductView($observer)
{
if (Mage::getSingleton('customer/session')->isLoggedIn())
{
$customer = Mage::getSingleton('customer/session')->getCustomer();
$counter = (int) $customer->getProductViewCount();
$customer->setProductViewCount($counter +1)->save();
}
}
}
(Was ist das?)
public function catalogProductLoadAfter($observer)
{
$product = $observer->getEvent()->getProduct();
// Process product data
}
public function checkoutCartProductAddAfter($observer)
{
$product = $observer->getEvent()->getProduct();
$quoteItem = $observer->getEvent()->getQuoteItem();
if ($product->getIsEpic())
{
Mage::getSingleton('customer/session')->getCustomer()
->setAura(self::AURA_TYPE_IMBA);
}
}
Bsp: Parameter für Event Observer
Oft mit mehreren Parametern
Webdeveloper-Dream of being a real Programmer
Nicht alle Events in <frontend> und <adminhtml> verfügbar, manche gibt es nur in <global>
Unser neues Attribut!
Product View Count in der Liste mit anzeigen
<?xml version="1.0"?>
<config>
<modules>
<Mm09_ViewCount>
<version>0.1.0</version>
</Mm09_ViewCount>
</modules>
<global>
<models>
<ViewCount>
<class>Mm09_ViewCount_Model</class>
</ViewCount>
</models>
<blocks>
<adminhtml>
<rewrite>
<customer_grid>Mm09_ViewCount_Block_Adminhtml_Customer_Grid</customer_grid>
</rewrite>
</adminhtml>
</blocks>
<resources>
<ViewCount_setup>
<setup>
<module>Mm09_ViewCount</module>
<class>Mage_Eav_Model_Entity_Setup</class>
</setup>
</ViewCount_setup>
</resources>
</global>
<frontend>
<events>
<controller_action_layout_render_before_catalog_product_view>
<observers>
<ViewCount>
<type>singleton</type>
<class>ViewCount/observer</class>
<method>controllerActionLayoutRenderBeforeCatalogProductView</method>
</ViewCount>
</observers>
</controller_action_layout_render_before_catalog_product_view>
</events>
</frontend>
</config>
Mage_Adminhtml_Block_Customer_Grid
Mage/Adminhtml/Block/Customer/Grid.php
Mm09/ViewCount/Block/Adminhtml/Customer/Grid.php
<?php
class Mm09_ViewCount_Block_Adminhtml_Customer_Grid
extends Mage_Adminhtml_Block_Customer_Grid
{
protected function _preparePage()
{
$this->getCollection()->addAttributeToSelect('product_view_count');
return parent::_preparePage();
}
protected function _prepareColumns()
{
parent::_prepareColumns();
$actionColum = $this->getColumn('action');
unset($this->_columns['action']);
$this->addColumn('product_view_count', array(
'header' => Mage::helper('customer')->__('Product View Count'),
'width' => '90',
'index' => 'product_view_count',
));
$this->_columns['action'] = $actionColum;
return $this;
}
}
EAV - nicht alle Attribute werden automatisch geladen!
Letzte Spalte entfernen...
(weil es hübscher ist)
Neue Spalte einfügen
Action Spalte an letzter
Stelle wieder einfügen
1.
2.
3.
Product View Count hier einfügen
Kurzbezeichnung aus
app/code/core/Mage/Adminhtml/etc/config.xml
Anzeige im Frontend
<?xml version="1.0"?>
<config>
<modules>
<Mm09_ViewCount>
<version>0.1.0</version>
</Mm09_ViewCount>
</modules>
<global>
<models>
<ViewCount>
<class>Mm09_ViewCount_Model</class>
</ViewCount>
</models>
<blocks>
<ViewCount>
<class>Mm09_ViewCount_Block</class>
</ViewCount>
<adminhtml>
<rewrite>
<customer_grid>Mm09_ViewCount_Block_Adminhtml_Customer_Grid</customer_grid>
</rewrite>
</adminhtml>
</blocks>
<resources>
<ViewCount_setup>
<setup>
<module>Mm09_ViewCount</module>
<class>Mage_Eav_Model_Entity_Setup</class>
</setup>
</ViewCount_setup>
</resources>
</global>
<frontend>
<events>
<controller_action_layout_render_before_catalog_product_view>
<observers>
<ViewCount>
<type>singleton</type>
<class>ViewCount/observer</class>
<method>controllerActionLayoutRenderBeforeCatalogProductView</method>
</ViewCount>
</observers>
</controller_action_layout_render_before_catalog_product_view>
</events>
<layout>
<updates>
<ViewCount>
<file>viewcount.xml</file>
</ViewCount>
</updates>
</layout>
</frontend>
</config>
ViewCount wird gemapped auf
app/code/local/Mm09/ViewCount/Block/
Frei zu vergeben aber einmalig
innerhalb <frontend> oder <adminhtml>
Konvention: lower-case für Layout und Template Dateien
<?php
class Mm09_ViewCount_Block_Viewcount extends Mage_Core_Block_Template
{
protected function _toHtml()
{
if (! Mage::getSingleton('customer/session')->isLoggedIn()) return '';
return parent::_toHtml();
}
public function getProductsViewedText()
{
$count = (int) Mage::getSingleton('customer/session')->getCustomer()->getProductViewCount();
if ($count == 1)
{
$text = 'You have viewed %d product page.';
}
else
{
$text = 'You have viewed %d product pages.';
}
return $this->__($text, $count);
}
}
Yay! sprintf() Formatierungen in der Übersetzungs Methode!
.../Mm09/ViewCount/Block/Viewcount.php
.../Mm09/ViewCount/Block/Adminhtml/Customer/Grid.php
Config Eintrag
Block Klasse Erweitern
Config Eintrag
Block Klasse
Layout XML
Template
.../Mm09/ViewCount/sql/ViewCount_setup/mysql4-install-0.1.0.php
app/design/frontend/default/default/layout/viewcount.xml
<?xml version="1.0"?>
<layout version="0.1.0">
<default>
<reference name="right">
<block
type="ViewCount/viewcount"
name="viewcount"
as="viewcount"
template="mm09/viewcount/sidebar.phtml"/>
</reference>
</default>
</layout>
Mm09_ViewCount_Block_Viewcount
app/code/local/Mm09/ViewCount/Block/Viewcount.php
Definiert in der layout/page.xml
"Layout Update Handle"
Innerhalb Layout XML
"name"
(Einmaling im zu Rendernden Layout)
Innerhalb PHP Block
Klassen und Templates
"as"
(Einmaling innerhalb des Parent Blocks)
app/design/frontend/default/default/template/mm09/viewcount/sidebar.phtml
<div class="box base-mini viewcount">
<div class="head">
<h4><?php echo $this->__('Products Viewed') ?></h4>
</div>
<div class="content">
<p><?php echo $this->getProductsViewedText() ?></p>
</div>
</div>
Layout Update Handles
<catalog_product_view/>
<checkout_cart_index/>
<checkout_onepage_index/>
<checkout_onepage_review/>
und viele mehr...
[modul]_[controller]_[action]
spezialfälle
<default/>
<customer_account/>
<customer_logged_in/>
<customer_logged_out/>
<PRODUCT_TYPE_configurable>
und viele mehr...
ein paar Beispiele...
Vinai Kopp
Freier Programmierer
vinai@netzarbeiter.de
+49 173 - 31 33 444
Support
Deutsches offizielles Magento Forum: http://www.magentocommerce.com/boards/viewforum/25/
IRC irc.freenode.net Channel #magento-de (deutsch) oder #magento (english)
Dokumentation?
t3n Magazin: regelmäßig Magento Artikel von mir und anderen
Liste mit Magento-Development Blogs http://blog.velite.de/essential-magento-developer-blogs/
... Zeitlos und immer Richtig: use the Source...!
Bücher:
Online-Shops mit Magento (Roman Zenner)
Magento - Das Handbuch für Entwickler (Visions new Media Entwickler)
Kontakt
Debugging
Nicht brauchbar: print_r($object); var_dump($object);
Logging Einschalten: System > Konfiguration > Entwickler
Besser $object->getData() oder $object->toArray();
Mage::log($object->getData());
Mage::log(__METHOD__);
Mage::log(get_class($object));
$product->getFoo()
Magic Getter & Magic Setter:
$customer->getProductViewCount();
Varien_Object::__get()
Varien_Object::getData('product_view_count')
$customer->setProductViewCount($count +1)
Varien_Object::__set()
Varien_Object::setData('product_view_count', 2)
Fragen ?
KurzbezeichnungMore presentations by Vinai Kopp
Realtime Soap API EN
Vinai Kopp on
Implementing a (near) realtime SOAP interface between an ERP system and Magento doesn't sound too difficult – Magento already features a SOAP API out of ...
Magento Layout XML
Vinai Kopp on
Eine Einführung in die Basics des Magento Layout XML. Layout XML ist ein recht einzigartiges Werkzeug zum modularen Aufbau von Magento Themes.
Popular presentations
Resumen explicativo del Proyecto de Ley de Resguardo del Orden Público (Ley Hinzpeter) en el marco de la protesta social
Sebastián Aylwin on
Resumen explicativo del Proyecto de Ley de Resguardo del Orden Público
More popular prezis in Explore>