A year with Magento

Hello everyone. Less than a year has passed since I’ve started working with Magento. It was a long path, I’ve learned a lot and now I have much to share. This article is not dedicated to all cool things I’ve found for myself, and it does not share my joy or frustration that I felt during this year. Actually, it is a small guide, or even a set of advices, for developers who decided to work with Magento. Moreover, it is not a typical “My first Magento extension” article, but quick tips which will make your progress easier and learning the Magento sides slighter.

The first thing that we require for making a development process easier is a toolkit. The most powerful solution is “PHP Storm” by JetBrains. So, buy and use it regardless of your OS. Also, built-in console and version control functionality will be often used during the development process. After integrating the XDebug you will spend hours with the Magento debugging, but it can spare you days of searching errors in Magento. Some of developers are using the Magicento plugin but I prefer not to. Writing extension elements manually will help you to train memory and evolve your understanding of Magento structure (especially in naming fallback and conventions).

The other useful tool is the n98 magerun CLI tools – you will use its functionality from simple cache flushing to extension check up and manipulation. For example, it will help you to find rewrites and rewrite conflicts with these commands respectively (run in Magento root):

n98-magerun.phar dev:module:rewrite:list

n98-magerun.phar dev:module:rewrite:conflicts

The main advice for the newbies in Magento: “Having problem – Google it”. Really. Magento community is impressively big, so there is no need to reinvent the wheel. Here is the list of useful links which will help you with various tasks:

  1. http://www.magentocommerce.com/wiki/1_-_installation_and_configuration/using_collections_in_magento – a really great article about the collection manipulations;
  2. https://inchoo.net/ecommerce/magento/overriding-magento-blocks-models-helpers-and-controllers/ – brief and sufficient article about Magento components rewriting;
  3. http://freegento.com/ddl-magento-extension.php – download extension by extension key;
  4. http://www.nicksays.co.uk/magento-events-cheat-sheet-1-7/ – the list of events which you can use to set up the observer. Try to use it, or debug your own way in attempt to find the proper event name right in Mage_Core_Controller_Varien_Action:
    /**
    *app/code/core/Mage/Core/Controller/Varien/Action.php
    */
    
    /**
         * Dispatch event before action
         *
         * @return void
         */
        public function preDispatch()
        {
            if (!$this->getFlag('', self::FLAG_NO_CHECK_INSTALLATION)) {
                if (!Mage::isInstalled()) {
                    $this->setFlag('', self::FLAG_NO_DISPATCH, true);
                    $this->_redirect('install');
                    return;
                }
            }
    
            // Prohibit disabled store actions
            if (Mage::isInstalled() && !Mage::app()->getStore()->getIsActive()) {
                Mage::app()->throwStoreException();
            }
    
            if ($this->_rewrite()) {
                return;
            }
    
            if (!$this->getFlag('', self::FLAG_NO_START_SESSION)) {
                $checkCookie = in_array($this->getRequest()->getActionName(), $this->_cookieCheckActions)
                    && !$this->getRequest()->getParam('nocookie', false);
                $cookies = Mage::getSingleton('core/cookie')->get();
                /** @var $session Mage_Core_Model_Session */
                $session = Mage::getSingleton('core/session', array('name' => $this->_sessionNamespace))->start();
    
                if (empty($cookies)) {
                    if ($session->getCookieShouldBeReceived()) {
                        $this->setFlag('', self::FLAG_NO_COOKIES_REDIRECT, true);
                        $session->unsCookieShouldBeReceived();
                        $session->setSkipSessionIdFlag(true);
                    } elseif ($checkCookie) {
                        if (isset($_GET[$session->getSessionIdQueryParam()]) && Mage::app()->getUseSessionInUrl()
                            && $this->_sessionNamespace != Mage_Adminhtml_Controller_Action::SESSION_NAMESPACE
                        ) {
                            $session->setCookieShouldBeReceived(true);
                        } else {
                            $this->setFlag('', self::FLAG_NO_COOKIES_REDIRECT, true);
                        }
                    }
                }
            }
    
            Mage::app()->loadArea($this->getLayout()->getArea());
    
            if ($this->getFlag('', self::FLAG_NO_COOKIES_REDIRECT)
                && Mage::getStoreConfig('web/browser_capabilities/cookies')
            ) {
                $this->_forward('noCookies', 'index', 'core');
                return;
            }
    
            if ($this->getFlag('', self::FLAG_NO_PRE_DISPATCH)) {
                return;
            }
    
            Varien_Autoload::registerScope($this->getRequest()->getRouteName());
    
            Mage::dispatchEvent('controller_action_predispatch', array('controller_action' => $this));
            Mage::dispatchEvent('controller_action_predispatch_' . $this->getRequest()->getRouteName(),
                array('controller_action' => $this));
            Mage::dispatchEvent('controller_action_predispatch_' . $this->getFullActionName(),
                array('controller_action' => $this));
        }
    
        /**
         * Dispatches event after action
         */
        public function postDispatch()
        {
            if ($this->getFlag('', self::FLAG_NO_POST_DISPATCH)) {
                return;
            }
    
            Mage::dispatchEvent(
                'controller_action_postdispatch_'.$this->getFullActionName(),
                array('controller_action'=>$this)
            );
            Mage::dispatchEvent(
                'controller_action_postdispatch_'.$this->getRequest()->getRouteName(),
                array('controller_action'=>$this)
            );
            Mage::dispatchEvent('controller_action_postdispatch', array('controller_action'=>$this));
        }
  5. http://fishpig.co.uk/magento/tutorials/javascript-prototype-form-validation/ – nice article about form validation and input validation types;
  6. http://www.magentocommerce.com/wiki/5_-_modules_and_development/admin/xml_structure_for_admin_configurations – examples of admin configuration settings;
  7. https://www.atwix.com/magento/reset-admin-password-mysql/ – short tip for reseting an admin password or creating a new admin user in Magento;
  8. https://www.atwix.com/magento/php-unit-testing/ – unit testing methodology guide.

With further progress, you will realise that the best examples of solutions can be found in Magento itself. You can find how to build the entity with model, resource model and collection or everything you need to make a backend representation of this entity with all the grids, forms and exports right in the most of core modules. Although, the core can be a really good example to almost everything, and you should remember that if you want to extend any core functionality it is important and even critical not to modify core files manually. Copying core files to the local pool and modifying them there also should be only the temporal measure – use rewrites, it is one of the core principles and features of Magento.

Continue our topic, one of the most frustrating things in Magento is Prototype. However, I prefer not to feed that dinosaur with my time and plug in jQuery if it was not done before. The only exception is Magento one page checkout and form validation. Simply, check if scripts-from-the-box working as they should after adding modern fancy JavaScript libraries.

And the last thing here: remember, you are a part of the community. If you have not found a solution for your problem in the web and made it by yourself, do not hesitate to share it with the community.

Thank you for reading.