My name is
Magento Developer @
March 2007
Core
Community
Local
"Lazy" programmers copying whole modules
from core/ to local/ to change single methods.
Models instantiation?
Mage::getModel('core/url_rewrite')
... and helpers.
Mage::helper('customer')
Event logging?
Mage::log('Customer cannot be saved.')
Store information?
Mage::app()->getStore()
Events Publishing
Mage::dispatchEvent('my_own_event')
Registry handling
Mage::register('my_variable', 'and value')
Mage::registry('my_variable')
... new lightweight model?
class MyCompany_Module_Model_Customer extends Mage_Core_Model_Abstract
Lightweight helper?
class MyCompany_Module_Helper_Data extends Mage_Core_Helper_Abstract
Add extra method to the model?
class MyCompany_Module_Model_Customer extends Mage_Customer_Model_Customer
... overused by programmers even when they do not write Magento-related code.
... argh! One more thing to remember!
require_once Mage::getModuleDir('controllers', 'Mage_Customer').DS.'AccountController.php'
New Action in existing Controller?
class MyCompany_Module_AccountController extends Mage_Customer_AccountController
... as Magento is unable to autoload original, extended Controller.
Let's create new Controller
class MyCompany_Module_CustomController extends Mage_Core_Controller_Front_Action
Each and every value from XML configuration...
<global>
<models>
<customer>
<rewrite>
<customer>MyCompany_Customer_Model_Customer</customer>
</rewrite>
</customer>
</models>
</global>
Is parsed to one huge configuration PHP array.
... the latest loaded module "wins" the configuration.
Both in Core and external modules...
class Mage_CurrencySymbol_Model_Observer
{
public function currencyDisplayOptions(Varien_Event_Observer $observer)
{
$baseCode = $observer->getEvent()->getBaseCode();
$currencyOptions = $observer->getEvent()->getCurrencyOptions();
$currencyOptions->setData(Mage::helper('currencysymbol')
->getCurrencyOptions($baseCode));
return $this;
}
}
Observers are modyfying received data!
November 2015
... 8 years after Magento 1 release
Developers should understand that Magento 2 way of doing something is actually OOP way of doing something. We did not invent a wheel.
We just try to follow good OOP/OOD practices.
IGOR MINIAILO Magento 2 architect, part of Community Engineering Team
namespace MyCompany\MyModule\Model;
class MyModel implements IdentityInterface
{
...
}
Clearly defined in documentation "Programming Best Practices"
https://devdocs.magento.com/guides/v2.2/ext-best-practices/extension-coding/common-programming-bp.html
namespace MyCompany\MyModule\Setup;
use Magento\Framework\Setup\UpgradeDataInterface;
class UpgradeData implements UpgradeDataInterface
{
...
public function __construct(
BlockRepositoryInterface $blockRepository,
BlockInterfaceFactory $blockFactory
) {
$this->blockRepository = $blockRepository;
$this->blockFactory = $blockFactory;
}
...
}
You need? You inject!
Abstract classes
Interfejsy
Conversation with another module is based on Interfaces, defined in API
public function __construct(ProductInterface $product) {
...
}
<preference for="Magento\Catalog\Api\Data\ProductInterface"
type="Magento\Catalog\Model\Product" />
Declaration of prefered implementation
<type name="MyCompany\Module\Controller\ProductController">
<arguments>
<argument name="product" xsi:type="object">MyCompany\Module\Model\Product</argument>
</arguments>
</type>
Injection of specific Interface implementation
Extensibility of public methods by composition.
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
public function setUp()
{
$objectManager = new ObjectManager($this);
$this->urlBuilderMock = $this->getMockBuilder(
\Magento\Framework\UrlInterface::class
)->disableOriginalConstructor()->getMock();
$this->testedObject = $this->objectManager->getObject(
\Some\Fancy\Object::class,
['urlBuilder' => $urlBuilderMock]
);
}
- Administration (adminhtml)
- Store front (frontend)
- Global (base)
- Web API REST (webapi_rest)
- Web API SOAP (webapi_soap)
Data modification in observers is now a bad practice
https://devdocs.magento.com/guides/v2.2/coding-standards/technical-guidelines.html#14-events
class SampleEventObserverThatModifiesInputs
{
/**
* @param \Magento\Framework\Event\Observer $observer
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
/** @var \Magento\Framework\App\DataObject $transport */
$transport = $observer->getData('transport');
if ($transport->getData('some_value') === true) {
$transport->setData('output_return_value', true);
}
}
}
Extended version of Use / Implement diagram is available on Vinai Kopp's Twitter account.
223 open
5337 closed
2017 / 2018
A
C
I
D
tomicity
onsistency
solation
urability