A talk about some of the most relevant features of the Magento 2 architecture and how they relate to PHP development best-practices, with a focus on do's and dont's for those who are looking to get a jump-start on Magento2 development.
2. Get up to speed with some of the jargon around M2 development 3. Share 8 quick tips about how to build an open-source M2 component Goals for This Talk
Your M2 Component Your Generic Domain or Web API Library Output Input XSDs APIs Events Provide APIs Events Consume 3rd Party Components Core Components Preferences Extend
/ Access Modifiers Photo by Dale Gillard / CC BY public $bar; protected $foo; private $baz; public function foo() {} protected function bar() {} private function baz() {}
data and sends email * @return void */ public function process(CartInterface $cart) {} // Returns the email transport public function getEmailTransport(): EmailTransportInterface {} // Sets the email transport public function setEmailTransport( EmailTransportInterface $transport ) {} protected function calculateCartPriceForEmail(CartInterface $cart) {} } Photo by Dale Gillard / CC BY EVIL Private Access Modifiers Example
interface Api/AbandonedCartEmailSenderInterface { /** * Gathers data and sends email * @return void */ public function process(CartInterface $cart); } Photo by Dale Gillard / CC BY Private Access Modifiers ✓ Tip for OSS: abstract to a meaningful interface
interface Api/AbandonedCartEmailSenderInterface { /** * Gathers data and sends email * @return void */ public function process(CartInterface $cart); } Photo by Dale Gillard / CC BY Private Access Modifiers ✓ Convention: public component interfaces go in an “Api” folder
data and sends email * @return void */ public function process(CartInterface $cart); } Photo by Dale Gillard / CC BY Private Access Modifiers ✓ We also got rid of getters / setters with little meaning or value
data and sends email * @return void */ public function process(CartInterface $cart); } Photo by Dale Gillard / CC BY Private Access Modifiers ✓ Rename public methods to something meaningful
BY Private Access Modifiers interface AbandonedCartEmailSenderInterface { /** * Gathers data and sends email * @return void */ public function sendForCart(CartInterface $cart); } ✓ Rename public methods to something meaningful
data and sends email * @return void */ public function sendForCart(CartInterface $cart); } Photo by Dale Gillard / CC BY ✓ Suggestion: rename interfaces so they reflect their value, meaning or role to their users Private Access Modifiers
data and sends email * @return void */ public function sendForCart(CartInterface $cart); } Photo by Dale Gillard / CC BY ✓ Suggestion: rename interfaces so they reflect their value, meaning or role to their users Private Access Modifiers
$transport; public function __construct( EmailTransportInterface $transport ) { $this->transport = $transport; } public function sendForCart(CartInterface $cart) { // ... $this->transport->send(/* ... */); } private function calculateCartPriceForEmail( CartInterface $cart ) { // ... } } Photo by Dale Gillard / CC BY ✓ Dependencies injected during construction Private Access Modifiers ✓ Interface in “Api” folder ✓ Default to private visibility
$transport; public function __construct( EmailTransportInterface $transport ) { $this->transport = $transport; } public function sendForCart(CartInterface $cart) { // ... $this->transport->send(/* ... */); } private function calculateCartPriceForEmail( CartInterface $cart ) { // ... } } Photo by Dale Gillard / CC BY ✓ Public API now is meaningful and concise Private Access Modifiers ✓ Interface in “Api” folder ✓ Default to private visibility ✓ Dependencies injected during construction
$transport; public function __construct( EmailTransportInterface $transport ) { $this->transport = $transport; } public function sendForCart(CartInterface $cart) { // ... $this->transport->send(/* ... */); } private function calculateCartPriceForEmail( CartInterface $cart ) { // ... } } Photo by Dale Gillard / CC BY ✓ We don’t yet know if this would be useful publicly Private Access Modifiers ✓ Interface in “Api” folder ✓ Default to private visibility ✓ Dependencies injected during construction ✓ Public API now is meaningful and concise
BY ✓ Prevent unnecessary BC breaks ✓ Encourage more expressive APIs ✓ Design better abstractions ✓ More simple tests Some benefits: Private Access Modifiers
BY ๏ Will not play nice with several OM features like Proxies / Plugins ๏ Might not be compatible with some Magento-specific debugging / profiling tools WARNING: “final” classes and functions The OM uses inheritance for many of its features. Private Access Modifiers
TDD 2. Integration test: interactions (where unit tests are not enough) and data flows 3. Functional / UI test: only “happy” / critical paths 4. Follow core testing standards Unit Functional UI by Mike Cohn
๏ ContinuousPHP ๏ Jenkins ๏ A few other Builds ๏ Scrutinizer ๏ Code Climate ๏ Codacy ๏ Your own Code Quality ๏ GrumPHP ๏ CodeSniffer ๏ Mage EQP ๏ PHP MD ๏ Many more Standards Next up - Automatically deploying magento2 without losing sleep (Ike Devolder)
something } else { throw new \InvalidArgumentException(sprintf( 'Value "%s" is not allowed.', $value )); } Assert::oneOf($inputParam, $allowedValues); // do something here ≈