Magento IMP


https://makandracards.com/magento?switch_to=pane


Widget Parameter ID Weirdness

I’ve not yet found out why, but this will not work:
<widgets> <some_widget type="some_module/block" translate="name description" module="some_module"> <name>Widget</name> <description>Foo</description> <parameters> <script_tag_id translate="label description"> <visible>1</visible> <required>1</required> <label>Script Tag ID</label> <description>The ID for the script tag, this looks like DoubleClickFloodlightTag1064319</description> <type>text</type> </script_tag_id> </parameters> </some_widget> </widgets>
But this will:
<widgets> <some_widget type="some_module/block" translate="name description" module="some_module"> <name>Widget</name> <description>Foo</description> <parameters> <script_tag_id_attrib translate="label description"> <visible>1</visible> <required>1</required> <label>Script Tag ID</label> <description>The ID for the script tag, this looks like DoubleClickFloodlightTag1064319</description> <type>text</type> </script_tag_id_attrib> </parameters> </some_widget> </widgets>
See the difference? The parameter that ends in _idnever gets set on the block, but the one that ends in_attrib does.

EAV Tables

A list of EAV tables and their purpose.
TableContains
eav_attributeAttributes and their global config values
catalog_eav_attributeCatalog-specific config values for attributes
eav_attribute_setAttribute sets, which are the top level containers for attributes against an entity
eav_attribute_groupAttribute groups, which belong to sets
eav_entity_attributeAttribute to group membership (also seems to contain set, which is duplication)
eav_attribute_labelPer-store attribute labels
eav_attribute_optionMulti-select and dropdown options
eav_attribute_option_valueMulti-select and dropdown option labels

Import Gotchas

Magento’s import can catch you out in a few places:
  • If you are updating an existing product:
    • If you don’t include stock attributes (what attributes?) then the stock for that product will be set to 0 and out of stock
    • If you don’t include the visibility attribute, the visibility will be set to the default of “Catalog, Search”

Custom Admin Grid Column Renderer

When you need to display an image in a column, or format a value in a particular way, you can use a custom renderer to present the data differently.

Custom EAV Frontend Input Renderer

Handy for adding an attribute to a product or category which needs a custom frontend input type.

Image Resize Helper Composition

The product image resizing goes through a few layers of abstraction, so I thought I’d add a quick UML diagram showing composition through the layers. The resizing ultimately gets done by the gd PHP extension.

startSetup() and endSetup()

Ever wondered what they do? Basically they disable and then enable foreign key checks, and set the SQL mode to NO_AUTO_VALUE_ON_ZERO, then back to the old SQL mode. Below is the code taken fromVarien_Db_Adapter_Pdo_Mysql:
/** * Run additional environment before setup * * @return Varien_Db_Adapter_Pdo_Mysql */ public function startSetup() { $this->raw_query("SET SQL_MODE=''"); $this->raw_query("SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0"); $this->raw_query("SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO'"); return $this; } /** * Run additional environment after setup * * @return Varien_Db_Adapter_Pdo_Mysql */ public function endSetup() { $this->raw_query("SET SQL_MODE=IFNULL(@OLD_SQL_MODE,'')"); $this->raw_query("SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS=0, 0, 1)"); return $this; }

Attribute Source Model

Used when you want to use a multiselect or select dropdown box on an EAV entity, such as products or categories.
class Namespace_Module_Model_Select extends Mage_Eav_Model_Entity_Attribute_Source_Abstract { /** * Retrieve Full Option values array * * @param bool $withEmpty Add empty option to array * @param bool $defaultValues * * @return array */ public function getAllOptions($withEmpty = true) { if (!$this->_options) { $options = array(); $options[] = array( 'value' => '0', 'label' => 'Option 1', ); $options[] = array( 'value' => '1', 'label' => 'Option 2', ); $this->_options = $options; } $options = $this->_options; if ($withEmpty) { array_unshift($options, array( 'value' => '', 'label' => '-- Please Select --', )); } return $options; } }

Javascript Cookie Functions

This doesn’t really go here, but hey ho. Magento’s functions injs/Mage/cookies.js are not very good.
/** * Get a cookie value * * @param String name The cookie name * * @return String The cookie value */ getCookie: function(name) { var val = ''; var cookies = document.cookie.split('; '); for (i = 0; i < cookies.length; i++) { nameVal = cookies[i].split('='); if (nameVal[0] == name) { val = unescape(nameVal[1]); } } return val; } /** * Set a cookie, or unset it by passing -1 as the expires param * * It is very important to pass *exactly* what was used to set the cookie in * the first place - this means same name, path, domain and secure. If the * cookie is host-only (had no domain passed in when set) then pass null as * the domain parameter, however if a domain was used when the cookie was * set then it will need a peiod prefix (.www.whatever.com) as the domain * * @param String name The cookie name * @param String value What to set to, use '' to unset * @param Int expires Expiry in seconds, -1 to unset * @param String path The path, when unsetting must be exactly as when set * @param String domain The domain, when unsetting must be exactly as when set * @param Bool secure Secure or not, when unsetting must be exactly as when set * * @return void */ setCookie: function(name, value, expires, path, domain, secure) { var cookieStr = name + "=" + escape(value) + "; "; if (expires) { var expiresDate = new Date(new Date().getTime() + expires * 24 * 60 * 60 * 1000); cookieStr += "expires=" + expiresDate.toGMTString() + "; "; } if (path) { cookieStr += "path=" + path + "; "; } if (domain) { cookieStr += "domain=" + domain + "; "; } if (secure) { cookieStr += "secure; "; } document.cookie = cookieStr; }

Changing The Admin Theme

Put this in your local.xml:
<config> <stores> <admin> <design> <theme> <default>yourtheme</default> </theme> </design> </admin> </stores> </config>

Validating System Configuration Values

Fetching Store Contact E-Mail Addresses

// General Contact $name = Mage::getStoreConfig('trans_email/ident_general/name'); $email = Mage::getStoreConfig('trans_email/ident_general/email'); // Sales Representative $name = Mage::getStoreConfig('trans_email/ident_sales/name'); $email = Mage::getStoreConfig('trans_email/ident_sales/email'); // Customer Support $name = Mage::getStoreConfig('trans_email/ident_support/name'); $email = Mage::getStoreConfig('trans_email/ident_support/email'); // Custom Email 1 $name = Mage::getStoreConfig('trans_email/ident_custom1/name'); $email = Mage::getStoreConfig('trans_email/ident_custom1/email'); // Custom Email 2 $name = Mage::getStoreConfig('trans_email/ident_custom2/name'); $email = Mage::getStoreConfig('trans_email/ident_custom2/email');

Order States

  • new
  • pending_payment
  • payment_review
  • processing
  • complete
  • closed
  • canceled
  • holded

Boilerplate Controller

<?php /** * Yourcompany.com * * PHP Version 5 * * @category Namespace * @package Namespace_Module * @author Your Name <your.name@yourcompany.com> * @copyright 2012 yourcompany.com * @license http://www.yourcompany.com/license.txt Your license * @link N/A */ /** * A description of the controller * * @category Namespace * @package Namespace_Module * @author Your Name <your.name@yourcompany.com> * @license http://www.yourcompany.com/license.txt Your license * @link N/A */ class Namespace_Module_SomeController extends Mage_Core_Controller_Front_Action { /** * Index action * * @return void */ public function indexAction() { $this->loadLayout(); $this->renderLayout(); } }

Paypal Express Flow

The PayPal Express Checkout Integration Guide is a great source of well-written information for anything relating to the Express checkout, including information regarding all of the API calls. Also, the PayPal Express Checkout flow diagram illustrates the process well:
The same information as contained in the diagram above is also in the table below:
Step / URLPayPal API CallNotes
https://www.domain.com/checkout/onepage/saveOrderSaves order, 302’s to next step
https://www.domain.com/paypal/express/startSetExpressCheckout302’s with PayPal token to next step
https://www.paypal.com/webscr?cmd=_express-checkout&token=(token)
(paypal)
https://www.sandbox.paypal.com/uk/cgi-bin/merchantpaymentwebHTML redirect to next step
https://www.domain.com/paypal/express/return?token=(token)GetExpressCheckoutDetailsDetails saved to payment, 302’s to next step
https://www.domain.com/paypal/express/reviewReview, user submits to next step
https://www.domain.com/paypal/express/placeOrderDoExpressCheckoutPaymentPlaces the order, 302’s to next step
https://www.domain.com/checkout/onepage/successConfirmation is shown

API Calls

I enabled the debug mode in PayPal Express on Magento to illustrate the data that is moved between Magento and PayPal during a successful checkout.

SetExpressCheckout

The SetExpressCheckout API operation initiates an Express Checkout transaction.
Array ( [url] => https://api-3t.sandbox.paypal.com/nvp [SetExpressCheckout] => Array ( [PAYMENTACTION] => Sale [AMT] => 433.90 [CURRENCYCODE] => GBP [RETURNURL] => http://www.domain.com/paypal/express/return [CANCELURL] => http://www.domain.com/paypal/express/cancel [INVNUM] => 100000001 [SOLUTIONTYPE] => Mark [GIROPAYCANCELURL] => http://www.domain.com/paypal/express/cancel [GIROPAYSUCCESSURL] => http://www.domain.com/checkout/onepage/success [BANKTXNPENDINGURL] => http://www.domain.com/checkout/onepage/success [LOCALECODE] => en_GB [ITEMAMT] => 389.00 [TAXAMT] => 0.00 [SHIPPINGAMT] => 44.90 [L_NUMBER0] => PRODUCT-SKU [L_NAME0] => Product Name [L_QTY0] => 1 [L_AMT0] => 389.00 [BUSINESS] => [NOTETEXT] => [EMAIL] => customeremail@example.com [FIRSTNAME] => Firstname [LASTNAME] => Lastname [MIDDLENAME] => [SALUTATION] => Mr [SUFFIX] => [COUNTRYCODE] => GB [STATE] => [CITY] => Test City [STREET] => 1 Test Road [ZIP] => AA1 1AA [PHONENUM] => 01234 456 7890 [SHIPTOCOUNTRYCODE] => GB [SHIPTOSTATE] => [SHIPTOCITY] => Test City [SHIPTOSTREET] => 1 Test Road [SHIPTOZIP] => AA1 1AA [SHIPTOPHONENUM] => 01234 456 7890 [SHIPTOSTREET2] => [STREET2] => [SHIPTONAME] => Mr Firstname Lastname [ADDROVERRIDE] => 1 [METHOD] => SetExpressCheckout [VERSION] => 72.0 [USER] => **** [PWD] => **** [SIGNATURE] => **** [BUTTONSOURCE] => Varien_Cart_EC_UK ) [response] => Array ( [TOKEN] => EC-4V9331241Q039141P [TIMESTAMP] => 2012-05-17T10:59:36Z [CORRELATIONID] => 81353f5487156 [ACK] => Success [VERSION] => 72.0 [BUILD] => 2860716 ) [__pid] => 1547 )

GetExpressCheckoutDetails

TheGetExpressCheckoutDetailsAPI operation obtains information about an Express Checkout transaction.
Array ( [url] => https://api-3t.sandbox.paypal.com/nvp [GetExpressCheckoutDetails] => Array ( [TOKEN] => EC-4V9331241Q039141P [METHOD] => GetExpressCheckoutDetails [VERSION] => 72.0 [USER] => **** [PWD] => **** [SIGNATURE] => **** [BUTTONSOURCE] => Varien_Cart_EC_UK ) [response] => Array ( [TOKEN] => EC-4V9331241Q039141P [CHECKOUTSTATUS] => PaymentActionNotInitiated [TIMESTAMP] => 2012-05-17T11:00:09Z [CORRELATIONID] => 61520b9f76d59 [ACK] => Success [VERSION] => 72.0 [BUILD] => 2860716 [EMAIL] => customerpaypalemail@example.com [PAYERID] => 7BKBHWEHTQCLB [PAYERSTATUS] => verified [FIRSTNAME] => Test [LASTNAME] => User [COUNTRYCODE] => GB [SHIPTONAME] => Mr Firstname Lastname [SHIPTOSTREET] => 1 Test Road [SHIPTOCITY] => Test City [SHIPTOZIP] => AA1 1AA [SHIPTOCOUNTRYCODE] => GB [SHIPTOPHONENUM] => 01234 456 7890 [SHIPTOCOUNTRYNAME] => United Kingdom [ADDRESSSTATUS] => Confirmed [CURRENCYCODE] => GBP [AMT] => 433.90 [ITEMAMT] => 389.00 [SHIPPINGAMT] => 44.90 [HANDLINGAMT] => 0.00 [TAXAMT] => 0.00 [INVNUM] => 100000001 [INSURANCEAMT] => 0.00 [SHIPDISCAMT] => 0.00 [L_NAME0] => Product Name [L_NUMBER0] => PRODUCT-SKU [L_QTY0] => 1 [L_TAXAMT0] => 0.00 [L_AMT0] => 389.00 [L_ITEMWEIGHTVALUE0] => 0.00000 [L_ITEMLENGTHVALUE0] => 0.00000 [L_ITEMWIDTHVALUE0] => 0.00000 [L_ITEMHEIGHTVALUE0] => 0.00000 [PAYMENTREQUEST_0_CURRENCYCODE] => GBP [PAYMENTREQUEST_0_AMT] => 433.90 [PAYMENTREQUEST_0_ITEMAMT] => 389.00 [PAYMENTREQUEST_0_SHIPPINGAMT] => 44.90 [PAYMENTREQUEST_0_HANDLINGAMT] => 0.00 [PAYMENTREQUEST_0_TAXAMT] => 0.00 [PAYMENTREQUEST_0_INVNUM] => 100000001 [PAYMENTREQUEST_0_INSURANCEAMT] => 0.00 [PAYMENTREQUEST_0_SHIPDISCAMT] => 0.00 [PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED] => false [PAYMENTREQUEST_0_SHIPTONAME] => Mr Firstname Lastname [PAYMENTREQUEST_0_SHIPTOSTREET] => 1 Test Road [PAYMENTREQUEST_0_SHIPTOCITY] => Test City [PAYMENTREQUEST_0_SHIPTOZIP] => AA1 1AA [PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE] => GB [PAYMENTREQUEST_0_SHIPTOPHONENUM] => 01234 456 7890 [PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME] => United Kingdom [L_PAYMENTREQUEST_0_NAME0] => Product Name [L_PAYMENTREQUEST_0_NUMBER0] => PRODUCT-SKU [L_PAYMENTREQUEST_0_QTY0] => 1 [L_PAYMENTREQUEST_0_TAXAMT0] => 0.00 [L_PAYMENTREQUEST_0_AMT0] => 389.00 [L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE0] => 0.00000 [L_PAYMENTREQUEST_0_ITEMLENGTHVALUE0] => 0.00000 [L_PAYMENTREQUEST_0_ITEMWIDTHVALUE0] => 0.00000 [L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE0] => 0.00000 [PAYMENTREQUESTINFO_0_ERRORCODE] => 0 ) [__pid] => 1545 )

DoExpressCheckoutPayment

TheDoExpressCheckoutPaymentAPI operation completes an Express Checkout transaction.
Array ( [url] => https://api-3t.sandbox.paypal.com/nvp [DoExpressCheckoutPayment] => Array ( [TOKEN] => EC-4V9331241Q039141P [PAYERID] => 7BKBHWEHTQCLB [PAYMENTACTION] => Sale [AMT] => 433.90 [CURRENCYCODE] => GBP [BUTTONSOURCE] => Varien_Cart_EC_UK [NOTIFYURL] => http://www.domain.com/paypal/ipn [RETURNFMFDETAILS] => 1 [ITEMAMT] => 389.00 [TAXAMT] => 0.00 [SHIPPINGAMT] => 44.90 [L_NUMBER0] => PRODUCT-SKU [L_NAME0] => Product Name [L_QTY0] => 1 [L_AMT0] => 389.00 [METHOD] => DoExpressCheckoutPayment [VERSION] => 72.0 [USER] => **** [PWD] => **** [SIGNATURE] => **** ) [response] => Array ( [TOKEN] => EC-4V9331241Q039141P [SUCCESSPAGEREDIRECTREQUESTED] => false [TIMESTAMP] => 2012-05-17T11:00:19Z [CORRELATIONID] => 4c11e936298ff [ACK] => Success [VERSION] => 72.0 [BUILD] => 2860716 [TRANSACTIONID] => 8WC11589LR800322T [TRANSACTIONTYPE] => cart [PAYMENTTYPE] => instant [ORDERTIME] => 2012-05-17T11:00:17Z [AMT] => 433.90 [FEEAMT] => 17.12 [TAXAMT] => 0.00 [CURRENCYCODE] => GBP [PAYMENTSTATUS] => Completed [PENDINGREASON] => None [REASONCODE] => None [PROTECTIONELIGIBILITY] => Eligible [INSURANCEOPTIONSELECTED] => false [SHIPPINGOPTIONISDEFAULT] => false [PAYMENTINFO_0_TRANSACTIONID] => 8WC11589LR800322T [PAYMENTINFO_0_TRANSACTIONTYPE] => cart [PAYMENTINFO_0_PAYMENTTYPE] => instant [PAYMENTINFO_0_ORDERTIME] => 2012-05-17T11:00:17Z [PAYMENTINFO_0_AMT] => 433.90 [PAYMENTINFO_0_FEEAMT] => 17.12 [PAYMENTINFO_0_TAXAMT] => 0.00 [PAYMENTINFO_0_CURRENCYCODE] => GBP [PAYMENTINFO_0_PAYMENTSTATUS] => Completed [PAYMENTINFO_0_PENDINGREASON] => None [PAYMENTINFO_0_REASONCODE] => None [PAYMENTINFO_0_PROTECTIONELIGIBILITY] => Eligible [PAYMENTINFO_0_PROTECTIONELIGIBILITYTYPE] => ItemNotReceivedEligible,UnauthorizedPaymentEligible [PAYMENTINFO_0_SECUREMERCHANTACCOUNTID] => NSPADE4W7XVER [PAYMENTINFO_0_ERRORCODE] => 0 [PAYMENTINFO_0_ACK] => Success ) [__pid] => 1548 )

Important Classes

ClassPurpose
Mage_Paypal_Controller_Express_AbstractProvides much of the base functionality for the two controllers
Mage_Paypal_ExpressControllerStandard (US?) express controller
Mage_PaypalUk_ExpressControllerUK express controller
Mage_Paypal_Model_ExpressExpress payment method
Mage_Paypal_Model_Express_Checkout?
Mage_Paypal_Model_Api_NvpPayPal Name-Value Pair API Wrapper

Allowing Import Of Invisible Attributes

By setting a Product Attributeto be invisible via thevisible property, you stop the ability to import that attribute unless you alter the_forcedAttributesCodesproperty of the relevant product type. The class names are:
  • Mage_ImportExport_Model_Import_Entity_Product_Type_Simple
  • Mage_ImportExport_Model_Import_Entity_Product_Type_Grouped
  • Mage_ImportExport_Model_Import_Entity_Product_Type_Configurable
The best method is probably to subclass the relevant product import class, then overwrite the property. It would be far better to use the constructor to append to the property rather than just overwrite it to make future upgrades as smooth as possible, but Magento, in all their wisdom, have marked the constructor as final so you cannot do this, and we have no events to take advantage of.

Adding A CSS Class To The Body Tag

To add a class via layout XML:
<reference name="root"> <action method="addBodyClass"><classname>whatever</classname></action> </reference>
Or to add via code, from a controller or block
if ($root = $this->getLayout()->getBlock('root')) { $root->addBodyClass('whatever'); }


For some reason this does not work:
$category->setIsActive(false);

Get A Products Stock Quantity

$product->getStockItem()->getQty();

URL Route Parameters

Mage_Core_Model_Url::getUrl()

These are the core set of route parameters, you can be fairly sure that any call togetUrl() which accepts route parameters will come through this method, so any of these parameters should work.
ParamTypeDoes
_storestring, intUse a stores config, numeric or string code
_typestringUsing the relevant types URL, either link, direct_link, js. media or skin
_secureboolUse the secure URL if allowed
_forced_secureboolForce using the secure URL
_use_rewriteboolResolves the link to a rewritten SEO URL
_nosidboolPrevents the SID query param from being added
_absoluteboolNo effect as URLs are always generated as absolute.
_currentboolUses the current module, controller, action and parameters
_directstringAppended to the base URL, apparently (really?)
_fragmentstringSets the fragment (#whatever) component
_escapeboolUses &amp; instead of & for querystring parameters
_querystring, arraySets the query parameters
_store_to_urlboolAdds ___store to the query parameters

Mage_Catalog_Model_Product_Url::getUrl()

These are extra parameters only noticed by the product URL method.
ParamTypeDoes
_ignore_categoryboolStops the category from appearing in the path. SeeGetting A Products URL for more info

Stop Controller Dispatch

In an action controllers preDispatch() method you can stop dispatch by calling the following:
$this->setFlag('', self::FLAG_NO_DISPATCH, true);
If you were listening via an observer, your code would look like this:
public function someObserver(Varien_Event_Observer $observer) { $action = $observer->getEvent()->getControllerAction(); $action->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH, true); }

Getting The Last Order ID From The Session

Mage::getSingleton('checkout/session')->getLastOrderId();


No comments:

Post a Comment