Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Magento best practices

5,925 views

Published on

These are the slides of my presentation at Meet Magento Italy 2015.

Download the presentation to have full access to all linked references.

Published in: Technology
  • Be the first to comment

Magento best practices

  1. 1. Magento Best Practices - 1/53 Meet Magento IT – March 5th-6th, 2015 Magento Best Practices “there are at least two ways of developing things in Magento the best of which is usually the third” - Alessandro Ronchi -
  2. 2. Magento Best Practices - 2/53 Meet Magento IT – March 5th-6th, 2015 Magento Best Practices “there are at least two ways of developing things in Magento the best of which is usually the third”
  3. 3. Magento Best Practices - 3/53 Meet Magento IT – March 5th-6th, 2015 About me ● Long term Magento Developer – 6+ years full-time work on Magento – 2+ years MCD ● Active Community member – 10+ free extensions – PUG MoRe main founder and coordinator – Organizer of Mageday 2013 and 2014
  4. 4. Magento Best Practices - 4/53 Meet Magento IT – March 5th-6th, 2015 About this talk It's a dense technical talk: ● mainly focused on Magento 1 ● some concepts are also valid for Magento 2 ● development experience required
  5. 5. Magento Best Practices - 5/53 Meet Magento IT – March 5th-6th, 2015 About you ● Developers? ● Programmers? ● Coders? ● What else?
  6. 6. Magento Best Practices - 6/53 Meet Magento IT – March 5th-6th, 2015 Who we should aim to be Software craftsmen “Bad code can function but can bring an organization to its knees.” “Craftsmanship comes from values that drive disciplines.” - R. Martin “I’m just a good programmer with great habits.” - K. Beck “Try to refactor code so that comment becomes superfluous.” - M. Fowler
  7. 7. Magento Best Practices - 7/53 Meet Magento IT – March 5th-6th, 2015 Tools There are a lot of tools which support and improve the development process “9. Do you use the best tools money can buy?” - The Joel Test
  8. 8. Magento Best Practices - 8/53 Meet Magento IT – March 5th-6th, 2015 Tools ● Effective IDEs (PhpStorm, Zend Studio) ● Magicento (for PhpStorm) by Enrique Piatti ● Commerce Bug by Alan Storm ● n98-magerun by Christian Münch ● Modman by Colin Mollenhour ● Composer by Jordi Boggiano ● Ultimate Module Creator by Marius Strajeru ● Magento Code Sniffer Coding Standard by Magento ECG ● Magento Project Mess Detector by Fabrizio Branca ● Judge by Netresearch App Factory ● Triplecheck.io by Allan MacGregor
  9. 9. Magento Best Practices - 9/53 Meet Magento IT – March 5th-6th, 2015 Tools: n98-magerun ● De facto standard command line toolkit to work with Magento ● Is also very useful to automate deployment tasks ● Extensible via plugins ● Available reference book by Alan Storm https://leanpub.com/command-line-magento
  10. 10. Magento Best Practices - 10/53 Meet Magento IT – March 5th-6th, 2015 Magento Runtime Why ● to check code inside a full initialized Magento application How ● Write a Module (slow) ● Write a Shell Script (faster) ● Use bash snippet (fastest)
  11. 11. Magento Best Practices - 11/53 Meet Magento IT – March 5th-6th, 2015 Magento Runtime: Shell Script ● Extend Mage_Shell_Abstract ● Set proper store scope protected $_appCode = 'admin'; ● Override _applyPhpVariables() ● Load app area in _construct() – Mage_Core_Model_App_Area::AREA_FRONTEND – Mage_Core_Model_App_Area::AREA_ADMINHTML
  12. 12. Magento Best Practices - 12/53 Meet Magento IT – March 5th-6th, 2015 Magento Runtime: bash snippet <?php if (isset($_SERVER['REQUEST_METHOD'])) {   die('Permission denied.'); // Prevent HTTP access }  set_time_limit(0); // Avoid any time limit ini_set('memory_limit', ­1); // Avoid any memory limit require_once 'app/Mage.php'; // Include base class Mage::setIsDeveloperMode(true); // Enable developer mode umask(0); // Set the default file creation mask Mage::app(); // Init application with default store
  13. 13. Magento Best Practices - 13/53 Meet Magento IT – March 5th-6th, 2015 Magento Runtime: ready snippets Customer https://gist.github.com/aleron75/190b25ea621c14a21d6b Administrator https://gist.github.com/aleron75/9d6609e99153d19461f3
  14. 14. Magento Best Practices - 14/53 Meet Magento IT – March 5th-6th, 2015 Logging Don't use static Mage::log() A static method is a dependency: a hidden relation which increases coupling between classes
  15. 15. Magento Best Practices - 15/53 Meet Magento IT – March 5th-6th, 2015 Logging: Log Adapter /** @var Mage_Core_Model_Log_Adapter $logger */ $logger = Mage::getModel(   'core/log_adapter',    'my_log_file_name.log'); $logger­>log("Hello World");
  16. 16. Magento Best Practices - 16/53 Meet Magento IT – March 5th-6th, 2015 Logging: Log Adapter Pros ● No more Mage::log() dependency ● Log file name specified once Cons ● Fixed severity for debug messages ● Logs always - regardless of config
  17. 17. Magento Best Practices - 17/53 Meet Magento IT – March 5th-6th, 2015 Logging: Logger Model /** @since Version 1.8.x */ /** @var Mage_Core_Model_Logger $logger */ $logger = Mage::getModel('core/logger'); $logger­>log("Hello World"); $logger­>logException(new Exception('Error'));
  18. 18. Magento Best Practices - 18/53 Meet Magento IT – March 5th-6th, 2015 Logging: Logger Model Pros ● No more Mage::log() dependency ● No limitations on severity ● Doesn't always force logs Cons ● Log file name specified always
  19. 19. Magento Best Practices - 19/53 Meet Magento IT – March 5th-6th, 2015 Logging: custom Implement only pros: ● No more Mage::log() dependency ● No limitations on severity ● Doesn't always force logs ● Log file name specified once
  20. 20. Magento Best Practices - 20/53 Meet Magento IT – March 5th-6th, 2015 Logging: custom Custom log wrapper https://github.com/aleron75/magelog Monolog wrapper https://github.com/aleron75/magemonolog
  21. 21. Magento Best Practices - 21/53 Meet Magento IT – March 5th-6th, 2015 Autoloading Magento’s autoloader is registered at the very beginning of framework's bootstrap: it is difficult (not impossible) to extend It's not natively PSR−0 compliant (PHP-FIG's birth follows Magento's)
  22. 22. Magento Best Practices - 22/53 Meet Magento IT – March 5th-6th, 2015 The Magento-PSR-0-Autoloader extension registers an additional autoloader which gives the ability to include libraries adhering to PSR−0 Autoloading Standard (i.e.: Monolog) Autoloading: enable PSR-0
  23. 23. Magento Best Practices - 23/53 Meet Magento IT – March 5th-6th, 2015 Effective MVC MVC is a good example of separation of concerns principle That doesn't mean we don't have to pay attention to avoid messing up things anyway
  24. 24. Magento Best Practices - 24/53 Meet Magento IT – March 5th-6th, 2015 Effective MVC: Models A Model is the entity which describes the problem we want to solve in terms of states and business logic
  25. 25. Magento Best Practices - 25/53 Meet Magento IT – March 5th-6th, 2015 Effective MVC: Models ● Keep Models simple and focused on a single concern ● Choose the least visibility scope for methods and declare classes final ● Prefer composition over inheritance (as far as possible)
  26. 26. Magento Best Practices - 26/53 Meet Magento IT – March 5th-6th, 2015 Effective MVC: Models Benefits of keeping Models simple: ● fewer reasons to change ● easier to upgrade ● easier to test ● clean interface ● smaller method signatures
  27. 27. Magento Best Practices - 27/53 Meet Magento IT – March 5th-6th, 2015 Effective MVC: Blocks & Templates Blocks are responsible for presentation data logic Templates are responsible for presentation logic
  28. 28. Magento Best Practices - 28/53 Meet Magento IT – March 5th-6th, 2015 Effective MVC: Blocks & Templates Prefer single points of definition: ● No direct data/config access in Blocks; use Models and Helpers instead ● Delegate to children Blocks whenever possible (i.e.: Mage_Catalog_Block_Product_Price) ● Templates should only interact with their Blocks ● Enable cache on custom Blocks
  29. 29. Magento Best Practices - 29/53 Meet Magento IT – March 5th-6th, 2015 Effective MVC: Controllers “a Controller accepts input and converts it to commands for the Model or View” - Wikipedia Controllers manage application flow
  30. 30. Magento Best Practices - 30/53 Meet Magento IT – March 5th-6th, 2015 Effective MVC: Controllers ● Check user input is well-formed i.e.: 16 digits required for a MasterCard number ● Don't perform business domain checks i.e.: whether a MasterCard number is authorized
  31. 31. Magento Best Practices - 31/53 Meet Magento IT – March 5th-6th, 2015 Effective MVC: Helpers They are not waste baskets :) ● utility methods containers (Core Helpers represent a very good example) ● shouldn't implement logic. For complex logic use service Models @see Mage_Sales_Model_Service_Quote
  32. 32. Magento Best Practices - 32/53 Meet Magento IT – March 5th-6th, 2015 Working with Data Adopting best practices can avoid unexpected performance downgrade or behaviour. Simply put: write scalable code
  33. 33. Magento Best Practices - 33/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: EAV and Flat ● Flat is never used for EAV entities in Admin Panel ● load() method always performs joins on EAV tables ● Flat for EAV entities is only used for Collections (unless filtering on non- flat attributes)
  34. 34. Magento Best Practices - 34/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: Products Don't try this at home: $products = Mage::getModel('catalog/product')   ­>getCollection(); foreach ($products as $prod) {   $prod­>load($prod­>getId()); # doesn't scale!   echo $prod­>getDescription(); }
  35. 35. Magento Best Practices - 35/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: Products The following code is better for scalability: $products = Mage::getModel('catalog/product')   ­>getCollection()   ­>addAttributeToSelect(array('description')); foreach ($products as $prod) {   echo $prod­>getDescription(); }
  36. 36. Magento Best Practices - 36/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: Products Comparison table*: Load type # queries # joins Time Memory In loop 875 1072 ~4 sec ~7 MB Outside loop 8 1 ~0.4 sec ~2.5 MB * on a development machine with official sample data
  37. 37. Magento Best Practices - 37/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: Collection size Comparison table*: Count type Time Memory count() ~0.966 sec ~25 MB getSize() ~0.081 sec ~1.8 MB * on a development machine with ~8000 products
  38. 38. Magento Best Practices - 38/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: iterate Collection Iterating: non-scalable approach $products = Mage::getModel('catalog/product')   ­>getCollection(); /** @var Mage_Catalog_Model_Product $product */ foreach ($products as $product) {   // do something ­ lazy loading is triggered }
  39. 39. Magento Best Practices - 39/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: iterate Collection Iterating: scalable approach $products = Mage::getModel('catalog/product')   ­>getCollection(); /** @var array $productData */ foreach ($products­>getData() as $productData) {   // do something }
  40. 40. Magento Best Practices - 40/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: iterate Collection Iterating: alternative scalable approach $products = Mage::getModel('catalog/product')   ­>getCollection(); /** @var Varien_Object $object */ while ($object = $products­>fetchItem()) {   // do something }
  41. 41. Magento Best Practices - 41/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: iterate Collection Comparison table*: Fetch collection items Time Memory standard ~1.913 sec ~25 MB getData() ~0.017 sec ~1.3 MB fetchItem() ~0.026 sec ~1.1 MB * on a development machine with official sample data
  42. 42. Magento Best Practices - 42/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: save attribute value The following code takes ~1.5 seconds to be executed on a development machine: $product = Mage::getModel('catalog/product')   ­>load(<existing_product_id>); $product   ­>setDataChanges(true) // force save   ­>save();
  43. 43. Magento Best Practices - 43/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: save attribute value To save only some values a better approach is:   $product = Mage::getModel('catalog/product')   ­>load(<existing_product_id>)   ­>setName('New name')   ­>setDescription('New description')   ­>getResource()   ­>saveAttribute($product, 'name')   ­>saveAttribute($product, 'description');
  44. 44. Magento Best Practices - 44/53 Meet Magento IT – March 5th-6th, 2015 Working with Data: save attribute value Comparison table*: Save method Time Memory save() ~1.5 sec ~5 MB saveAttribute() ~0.02 sec a few KB * on a development machine with official sample data
  45. 45. Magento Best Practices - 45/53 Meet Magento IT – March 5th-6th, 2015 Extending Magento Never touch the core files!
  46. 46. Magento Best Practices - 46/53 Meet Magento IT – March 5th-6th, 2015 Extending Magento: monkey patch Monkey patches are a (non upgrade safe) way to change a core class without touching the original file by copying it from the core code pool to the local one. Possible use cases: ● patching the core ● rapid prototyping
  47. 47. Magento Best Practices - 47/53 Meet Magento IT – March 5th-6th, 2015 Extending Magento: rewrites Rewrites are the first step towards extending Magento according to best practices. Pros ● upgrade safe Cons ● only one rewrite of same class → potential conflicts ● not compliant with the open/closed principle
  48. 48. Magento Best Practices - 48/53 Meet Magento IT – March 5th-6th, 2015 Extending Magento: events Events represent the standard best way to extend other classes behaviour. Pros ● upgrade safe ● no conflicts: multiple observers on same event Cons ● no event → no observer
  49. 49. Magento Best Practices - 49/53 Meet Magento IT – March 5th-6th, 2015 Extending Magento: interceptors Interceptors are a way to change the behavior of any public or protected method, by either executing code before or after that method. They are native on Magento 2 but can be also added to Magento 1 thanks to: https://github.com/danslo/Danslo_Aop
  50. 50. Magento Best Practices - 50/53 Meet Magento IT – March 5th-6th, 2015 Extending Magento: interceptors Pros ● Upgrade safe ● No conflicts ● Any public/protected method can be intercepted, no need of events Cons ● Logic can be injected only at the beginning or at the end, not in the middle of a method
  51. 51. Magento Best Practices - 51/53 Meet Magento IT – March 5th-6th, 2015 Conclusions ● Use the best available tools ● Use runtime outside Magento modules ● Don't use Mage::log() ● Extending autoloading is possible and useful ● Write effective and solid MVC components ● Data: write scalable code ● Never touch the core, prefer events to rewrites, familiarize with interceptors
  52. 52. Magento Best Practices - 52/53 Meet Magento IT – March 5th-6th, 2015 The Handbook https://leanpub.com/magebp ● If you liked this talk you'll love the e-book :) ● Special 25% discount code for you: mm15it ● Release date: ~June 2015
  53. 53. Magento Best Practices - 53/53 Meet Magento IT – March 5th-6th, 2015 Thank you! QUESTIONS? https://twitter.com/aleron75 https://github.com/aleron75

×