<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: David Lambauer</title>
    <description>The latest articles on Forem by David Lambauer (@dlmbr).</description>
    <link>https://forem.com/dlmbr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1100847%2F1f02142b-1a04-49ed-a148-9061b7d44718.jpg</url>
      <title>Forem: David Lambauer</title>
      <link>https://forem.com/dlmbr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dlmbr"/>
    <language>en</language>
    <item>
      <title>Navigating Magento 2 Architecture: Discovering Plugin Architecture for Newcomers</title>
      <dc:creator>David Lambauer</dc:creator>
      <pubDate>Mon, 17 Jul 2023 18:15:13 +0000</pubDate>
      <link>https://forem.com/run_as_root/navigating-magento-2-architecture-discovering-plugin-architecture-for-newcomers-312i</link>
      <guid>https://forem.com/run_as_root/navigating-magento-2-architecture-discovering-plugin-architecture-for-newcomers-312i</guid>
      <description>&lt;p&gt;Hello again, and welcome back to our series on Magento 2 Architecture for newcomers! We're glad to see you return for the second part of our journey, a clear indicator of your dedication to understanding and mastering this powerful platform. In our first post, we delved into the fascinating world of Magento 2's Observer Architecture. We explored its unique functionality and got our hands dirty with practical examples to bolster our knowledge.&lt;/p&gt;

&lt;p&gt;Today, we will be unraveling the intricacies of Magento 2's Plugin Architecture. Our aim is to ensure you not only understand the concept theoretically but also gain the practical skills necessary to apply them efficiently. So buckle up, as we gear up for another exciting ride through the world of Magento!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Role of Plugins in Magento 2
&lt;/h2&gt;

&lt;p&gt;In Magento 2, plugins, also referred to as Interceptors, play a critical role in extending the functionality of existing public methods within a class. They provide a mechanism that allows us to alter or extend the behavior of public methods without modifying the actual class.&lt;/p&gt;

&lt;p&gt;The charm of plugins lies in their ability to interact with a method at three different points: before, after, and around. This allows developers to modify the input or output data or even change the flow of processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Registering a Plugin
&lt;/h2&gt;

&lt;p&gt;To leverage the power of plugins, we need to register them first. This is done in the &lt;code&gt;di.xml&lt;/code&gt; file of your module. Here's a basic example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;config&lt;/span&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt; &lt;span class="na"&gt;xsi:noNamespaceSchemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"urn:magento:framework:ObjectManager/etc/config.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;type&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Magento\Framework\App\Action\Action"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugin&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"vendor_module_slack_notifier"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"Vendor\Module\Plugin\SlackNotifier"&lt;/span&gt; &lt;span class="na"&gt;sortOrder=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/config&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we've registered a plugin named &lt;code&gt;vendor_module_slack_notifier&lt;/code&gt; for the class &lt;code&gt;Magento\Framework\App\Action\Action&lt;/code&gt;. The plugin's class is &lt;code&gt;Vendor\Module\Plugin\SlackNotifier&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing a Plugin
&lt;/h2&gt;

&lt;p&gt;Now, let's get down to the nitty-gritty of writing our plugin. Remember our goal here is to send a Slack message at a clever place. A good idea could be to notify a Slack channel whenever a new order is placed on the website. In this case, let's consider we are writing a plugin for the &lt;code&gt;placeOrder&lt;/code&gt; method in the &lt;code&gt;Magento\Sales\Model\Service\OrderService&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Vendor\Module\Plugin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SlackNotifier&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$slack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Vendor\Module\Model\Slack&lt;/span&gt; &lt;span class="nv"&gt;$slack&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$slack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;afterPlaceOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Magento\Sales\Model\Service\OrderService&lt;/span&gt; &lt;span class="nv"&gt;$subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;$result&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"New order placed with ID: "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this plugin, we are using the &lt;code&gt;after&lt;/code&gt; plugin to send a Slack message after an order has been placed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unit Testing a Plugin
&lt;/h2&gt;

&lt;p&gt;After we've written our plugin, it's important to test it to ensure it behaves as expected. Here's how you can use PHPUnit to test your plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Vendor\Module\Test\Unit\Plugin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SlackNotifierTest&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;PHPUnit\Framework\TestCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$slackNotifier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slackNotifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMockBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Vendor\Module\Plugin\SlackNotifier&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                                    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;disableOriginalConstructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                                    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMock&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testAfterPlaceOrder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$orderServiceMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Magento\Sales\Model\Service\OrderService&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"100001"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slackNotifier&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;expects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;once&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'afterPlaceOrder'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$orderServiceMock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slackNotifier&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;afterPlaceOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$orderServiceMock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Observers vs Plugins
&lt;/h2&gt;

&lt;p&gt;While observers and plugins might seem similar, they serve different purposes and their usage depends on your requirements. Plugins are great for modifying the behavior of existing public methods. However, if you're interested in reacting to specific events in the application, observers would be a more suitable choice.&lt;/p&gt;

&lt;p&gt;The observer pattern can be seen as a more global approach, as it enables a certain type of code (observers) to react to system-wide events without coupling the observers to the code that emits those events. Plugins, on the other hand, are more targeted, allowing us to interact with a method at specific points in its execution.&lt;/p&gt;

&lt;p&gt;With the knowledge you've gained from this post and the previous one, you are now well-equipped to start implementing these concepts into your projects. Next in this series, we will dive deeper into the world of Magento 2 architecture. Stay tuned and happy coding!&lt;/p&gt;

</description>
      <category>php</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>magento2</category>
    </item>
    <item>
      <title>Kickstarting Magento 2 Architecture Journey: Mastering Observer Architecture for Newcomers</title>
      <dc:creator>David Lambauer</dc:creator>
      <pubDate>Mon, 19 Jun 2023 21:36:09 +0000</pubDate>
      <link>https://forem.com/run_as_root/kickstarting-magento-2-architecture-journey-mastering-observer-architecture-for-newcomers-47h4</link>
      <guid>https://forem.com/run_as_root/kickstarting-magento-2-architecture-journey-mastering-observer-architecture-for-newcomers-47h4</guid>
      <description>&lt;p&gt;Hello and welcome to the first post in our blog series dedicated to the architectural nuances of Magento 2. Aimed specifically at those taking their initial steps into the Magento ecosystem, this series will illuminate key architectural elements and concepts of the platform. Our inaugural topic is a vital part of Magento's Event-Driven Architecture - the Observer Pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Magento 2 Observer Architecture: An Overview
&lt;/h2&gt;

&lt;p&gt;The Observer Architecture, an event-driven design pattern in Magento, paves the way for effective communication between various sections of code. It adopts the principle of 'Loose Coupling,' promoting interactions without rigid dependencies. Essentially, it lets you extend and customize Magento's functionality without modifying the core system files significantly.&lt;/p&gt;

&lt;p&gt;Various events, such as adding a product to the cart or placing an order, initiate specific sequences of actions within Magento 2. The Dispatcher identifies these events and calls the corresponding observers - class methods assigned to carry out actions related to the event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identifying Event Names
&lt;/h2&gt;

&lt;p&gt;Magento 2 has predefined event names for numerous actions. To identify the correct event name, you need to understand the functionality you wish to extend or modify. Often, you can find these event names within Magento's core code files, specifically inside the dispatch function calls. A pro tip: For a more comprehensive list, refer to the &lt;a href="https://github.com/alaa-almaliki/magento2-events-log"&gt;Magento 2 Event Cheat Sheet&lt;/a&gt; available online.&lt;/p&gt;

&lt;h2&gt;
  
  
  Registering an Observer with &lt;code&gt;events.xml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To declare an observer in Magento 2, you will utilize the events.xml file. You'll need to specify the event name you're observing and the class that will handle it. Here's a quick walkthrough on registering an observer:&lt;/p&gt;

&lt;p&gt;Create an &lt;code&gt;events.xml&lt;/code&gt; file in the etc directory of your module.&lt;/p&gt;

&lt;p&gt;Register your observer in the &lt;code&gt;events.xml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;config&lt;/span&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt; &lt;span class="na"&gt;xsi:noNamespaceSchemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"urn:magento:framework:Event/etc/events.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;event&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"checkout_cart_product_add_after"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;observer&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"slack_message_observer"&lt;/span&gt; &lt;span class="na"&gt;instance=&lt;/span&gt;&lt;span class="s"&gt;"Vendor\Module\Observer\SlackMessageObserver"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/event&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/config&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Crafting an Observer: Sending a Slack Message on Cart Addition
&lt;/h2&gt;

&lt;p&gt;Let's put this into practice by creating an observer that sends a Slack message whenever a product is added to the cart.&lt;/p&gt;

&lt;p&gt;First, define your Observer class, &lt;code&gt;SlackMessageObserver.php&lt;/code&gt;, within your module's Observer directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Vendor\Module\Observer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Magento\Framework\Event\ObserverInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Vendor\Module\Model\SlackMessageSender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SlackMessageObserver&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ObserverInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;SlackMessageSender&lt;/span&gt; &lt;span class="nv"&gt;$slackMessageSender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SlackMessageSender&lt;/span&gt; &lt;span class="nv"&gt;$slackMessageSender&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slackMessageSender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$slackMessageSender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Magento\Framework\Event\Observer&lt;/span&gt; &lt;span class="nv"&gt;$observer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$observer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getDataUsingMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'product'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'A product has been added to the cart: '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slackMessageSender&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code, we've implemented the execute method, which gets invoked when the &lt;code&gt;checkout_cart_product_add_after&lt;/code&gt; event is dispatched. The execute method gathers the product data and sends a message to a Slack channel using the &lt;code&gt;SlackMessageSender&lt;/code&gt; service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Your Observer
&lt;/h2&gt;

&lt;p&gt;Testing in Magento 2 typically involves two levels - Unit Testing and Integration Testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unit Testing&lt;/strong&gt; aims at the smallest testable parts of an application, in isolation. In our observer's case, we can create a mock of &lt;code&gt;SlackMessageSender&lt;/code&gt; and confirm if the send method is called with the expected argument.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integration Testing&lt;/strong&gt;, conversely, examines the interaction between different application components. It could involve testing the entire process, from adding a product to the cart to sending the Slack message. Here's how an integration test for our observer might look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Vendor\Module\Observer\Test\Integration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Magento\TestFramework\Helper\Bootstrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Magento\Framework\Event\ManagerInterface&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;EventManager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Magento\Catalog\Api\ProductRepositoryInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Magento\Checkout\Model\Cart&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Vendor\Module\Observer\SlackMessageObserver&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Vendor\Module\Model\SlackMessageSender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SlackMessageObserverTest&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;PHPUnit\Framework\TestCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$objectManager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$cart&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$slackMessageSenderMock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;objectManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Bootstrap&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getObjectManager&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;objectManager&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Cart&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slackMessageSenderMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SlackMessageSender&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;objectManager&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addSharedInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slackMessageSenderMock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SlackMessageSender&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;objectManager&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addSharedInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;objectManager&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SlackMessageObserver&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;SlackMessageObserver&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testObserverIsTriggeredOnAddToCart&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$productRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;objectManager&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProductRepositoryInterface&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$productRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'simple'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'simple' should be a SKU of a product in your test database&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slackMessageSenderMock&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;expects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;once&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'send'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;stringContains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;tearDown&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;objectManager&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;removeSharedInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SlackMessageSender&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;objectManager&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;removeSharedInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SlackMessageObserver&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition, a basic unit test might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Vendor\Module\Test\Unit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;PHPUnit\Framework\TestCase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Vendor\Module\Observer\SlackMessageObserver&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Vendor\Module\Model\SlackMessageSender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Magento\Catalog\Model\Product&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Magento\Framework\Event\Observer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Magento\Framework\Event&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SlackMessageObserverTest&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;TestCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testExecute&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$productName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Test Product'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Mock product&lt;/span&gt;
        &lt;span class="nv"&gt;$productMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$productMock&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'getName'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;willReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$productName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Mock event&lt;/span&gt;
        &lt;span class="nv"&gt;$eventMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$eventMock&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'getData'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'product'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;willReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$productMock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Mock observer&lt;/span&gt;
        &lt;span class="nv"&gt;$observerMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Observer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$observerMock&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'getEvent'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;willReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$eventMock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Mock SlackMessageSender&lt;/span&gt;
        &lt;span class="nv"&gt;$slackMessageSenderMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SlackMessageSender&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$slackMessageSenderMock&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;expects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;once&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'send'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;stringContains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$productName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="c1"&gt;// Instantiate the SlackMessageObserver with the mocked SlackMessageSender&lt;/span&gt;
        &lt;span class="nv"&gt;$observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SlackMessageObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$slackMessageSenderMock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$observer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$observerMock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Testing is as critical as writing code itself. Tests ensure your modules' stability and reliability, and mitigate future issues arising from updates or changes in other parts of the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Declare the Observer in the Appropriate Scope
&lt;/h3&gt;

&lt;p&gt;The first step in using Magento 2 observers effectively is to ensure you declare them in the right scope: &lt;code&gt;global&lt;/code&gt;, &lt;code&gt;frontend&lt;/code&gt;, or &lt;code&gt;adminhtml&lt;/code&gt;. The scope of your observer depends on where you need it to operate. A &lt;code&gt;global&lt;/code&gt; scope means the observer operates universally, both in the admin area and the frontend. If your observer is only needed in the backend, use the &lt;code&gt;adminhtml&lt;/code&gt; scope. Meanwhile, if it's strictly for the user-facing part of your site, then &lt;code&gt;frontend&lt;/code&gt; is the appropriate scope.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make the Observer as Efficient as Possible
&lt;/h3&gt;

&lt;p&gt;Efficiency is key when it comes to coding, particularly with observers in Magento 2. To increase the efficiency of your observer, streamline your code. Try to reduce unnecessary loops and calculations as these can slow down your web pages. Remember, a lean observer is a fast observer. For instance, if there's an SQL query within your observer code that's not essential or could be optimized, it might be worth revisiting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Avoid Cyclical Event Loops
&lt;/h3&gt;

&lt;p&gt;Avoiding cyclical event loops is another crucial best practice. In a cyclical event loop, an event triggers an observer which then dispatches another event, which then triggers the initial event, and so on. This can lead to significant performance issues. To prevent this, ensure that your observers are mindful of the events they're triggering and avoid creating unnecessary dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do Not Rely on Invocation Order
&lt;/h3&gt;

&lt;p&gt;Finally, when dealing with multiple observers in Magento 2, do not rely on their invocation order. The order in which observers are invoked in Magento 2 is not specified, so building dependencies based on order can lead to unpredictable results. Each observer should be designed to operate independently, regardless of when it's invoked in the sequence.&lt;/p&gt;

&lt;p&gt;In conclusion, using Magento 2 observers effectively involves careful scope placement, lean and efficient coding, avoidance of cyclical event loops, and independent design to prevent reliance on invocation order. Following these best practices will help you optimize your Magento 2 observer use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Come to an end
&lt;/h2&gt;

&lt;p&gt;And there we have it - the &lt;strong&gt;first&lt;/strong&gt; steps into Magento 2's intriguing observer architecture. Don't worry if it seems a bit overwhelming now; with each post in this series, the fog will clear, and the road will become more navigable. Remember, all great journeys start with a single step.&lt;/p&gt;

&lt;p&gt;As we journey together, I'd love to connect with you on other platforms as well. You can follow me on &lt;a href="https://twitter.com/DavidLambauer"&gt;Twitter&lt;/a&gt; for regular insights, quick tips, and all things Magento. Or join me on &lt;a href="https://github.com/DavidLambauer"&gt;Github&lt;/a&gt; to explore my projects, learn from the code and maybe even contribute to some open source initiatives!&lt;/p&gt;

&lt;p&gt;Stay tuned for the next post in this series, and don't forget, the world of Magento 2 is expansive and full of opportunities for those willing to explore. As always, happy Magento coding!&lt;/p&gt;

</description>
      <category>magento2</category>
      <category>php</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Understanding Magento 2 Modules: A Comprehensive Look into Key Class Types</title>
      <dc:creator>David Lambauer</dc:creator>
      <pubDate>Thu, 15 Jun 2023 18:28:46 +0000</pubDate>
      <link>https://forem.com/run_as_root/understanding-magento-2-modules-a-comprehensive-look-into-key-class-types-2cm2</link>
      <guid>https://forem.com/run_as_root/understanding-magento-2-modules-a-comprehensive-look-into-key-class-types-2cm2</guid>
      <description>&lt;p&gt;Greetings, Magento 2 enthusiasts. The life of a developer is laden with challenges, one of the most prominent being structuring and naming modules effectively. This task, albeit complex, is crucial in creating software that is easy to read, modify, and debug. Let's embark on an exploration of five pivotal class types that are instrumental in structuring Magento 2 modules efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Mapper Classes
&lt;/h2&gt;

&lt;p&gt;The first class on our list is the Mapper Class. Mapper classes are invaluable tools that mediate and translate between different data types and structures. They provide an efficient way to convert data from one format to another, hence increasing the interoperability of your modules.&lt;/p&gt;

&lt;p&gt;In a Magento context, Mapper classes can be utilized to translate data from a CSV file to a more structured format like RSS or even a product DTO (Data Transfer Object). The Mapper class ensures this conversion process is streamlined and efficient, reducing code redundancy and increasing maintainability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CsvToRssMapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$csvData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Conversion logic from CSV data to RSS format&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By encapsulating the mapping logic within its domain, a Mapper class promotes single responsibility and enhances code readability.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Validator Classes
&lt;/h2&gt;

&lt;p&gt;Validator Classes play a crucial role in maintaining the integrity and consistency of data within the application. They enforce rules and constraints to ensure the incoming data adheres to the specified format and conditions.&lt;/p&gt;

&lt;p&gt;For example, in an e-commerce store, a ProductValidator class might scrutinize whether the product data entered by the admin meets all requirements, such as non-empty product name and valid SKU, before it gets saved into the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductValidator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$productData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Validate if the productData meets the requirements&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validator classes not only safeguard the application from invalid data but also encapsulate validation logic, keeping the code clean and organized.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Command Classes (CQRS)
&lt;/h2&gt;

&lt;p&gt;Command classes form a critical part of the Command Query Responsibility Segregation (CQRS) pattern, which segregates operations that mutate state (Commands) from operations that return data (Queries).&lt;/p&gt;

&lt;p&gt;In a Magento store, you might have a command like "UpdateProductStockCommand" that takes a product SKU and the new stock quantity, updating the inventory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UpdateProductStockCommand&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sku&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$newQuantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Logic to update the stock quantity of the product&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Command classes, by focusing solely on state mutation, bring clarity to your code and reduce the likelihood of side effects in data manipulation operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Query Classes (CQRS)
&lt;/h2&gt;

&lt;p&gt;Complementing Command classes in the CQRS pattern are Query classes. They are solely responsible for data retrieval and do not alter the state of the application.&lt;/p&gt;

&lt;p&gt;For instance, a Query class in Magento could be "GetProductBySkuQuery," which fetches a product's data based on its SKU without affecting the underlying data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GetProductBySkuQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sku&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Fetch and return the product data using SKU&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By decoupling data retrieval from data mutation, Query classes enable safer and more efficient data handling, enhancing the performance and reliability of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Service Classes
&lt;/h2&gt;

&lt;p&gt;Service classes are the workhorses of any Magento application. They encapsulate business logic and serve as a bridge between the presentation and data access layers.&lt;/p&gt;

&lt;p&gt;In a typical e-commerce scenario, a ProductService might orchestrate the process of creating a product, which could involve validating input data, mapping it to a product entity, and saving it to the database using a repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;createProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$productData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Business logic to create a new product&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Service classes bring structure and order to the application, encapsulating complex operations, and promoting code reusability and maintenance.&lt;/p&gt;

&lt;p&gt;To sum up, understanding these five class types – Mapper, Validator, Command, Query, and Service – is essential to structure and name Magento 2 modules effectively. These classes, when utilized properly, can make your code more readable, maintainable, and scalable. Here's to writing cleaner and more efficient Magento 2 code!&lt;/p&gt;

</description>
      <category>magento</category>
      <category>magento2</category>
      <category>softwareengineering</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Software Quality Metrics: No Sorcery, Just Simple Math!</title>
      <dc:creator>David Lambauer</dc:creator>
      <pubDate>Tue, 13 Jun 2023 19:02:42 +0000</pubDate>
      <link>https://forem.com/run_as_root/software-quality-metrics-no-sorcery-just-simple-math-3peo</link>
      <guid>https://forem.com/run_as_root/software-quality-metrics-no-sorcery-just-simple-math-3peo</guid>
      <description>&lt;p&gt;Greetings, PHP Padawans and Code Craftsmen!&lt;/p&gt;

&lt;p&gt;You've arrived at the right place if you're in search of the One Ring to rule your PHP code! The magical journey we're embarking on today involves a fantastical beast with a forbidding name - Software Quality Metrics.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dramatic gasp&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Relax, they're not as scary as they sound. In fact, they're your loyal allies, ready to add a Midas touch to your code. They're as easy to measure as counting the stripes on your tabby. So let's dive in, shall we?&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Code Maintainability Index: Is your code a Marathon Runner or a Couch Potato?
&lt;/h2&gt;

&lt;p&gt;The Code Maintainability Index is like a fitness check-up for your code. It provides a score from 0 to 100, where 100 implies your code is ready to run a marathon (with no panting), and 0... well, let's say it's in love with the couch.&lt;/p&gt;

&lt;p&gt;Maintainability Index calculates scores using three primary ingredients:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Halstead Volume – It's like the manual of your code. If you've got more operators and operands than you can shake a stick at, your volume is high.&lt;/li&gt;
&lt;li&gt;Cyclomatic Complexity – More on this spicy ingredient later, promise.&lt;/li&gt;
&lt;li&gt;Lines of Code – Aka, your code's not-so-secret diary. More isn't always merrier here.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Consider this PHP snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;findMedian&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's lean, mean, and ready for the screen. It does one thing, and does it well - finds the median of an array. The complexity and volume are low. It would score pretty high on the Maintainability Index.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Cyclomatic Complexity: The Tangled Web We Weave
&lt;/h2&gt;

&lt;p&gt;Next up, we have the Cyclomatic Complexity metric - which, despite its ominous name, is not a new Transformer villain. Instead, it measures the complexity of your code based on the number of independent paths through it. It’s like counting the possible routes you can take in your city. The more paths there are, the more complex the city... or in our case, the code.&lt;/p&gt;

&lt;p&gt;Check this PHP example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sortArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ouch! That's a double "for" loop sorting an array. With each "if" and "for," our Cyclomatic Complexity shoots up. It's like a city where every street corner has a dozen alleys leading off. Too many options can make the city - or your code - hard to navigate.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Code Duplication: Deja vu, or Copy-Paste Catastrophe?
&lt;/h2&gt;

&lt;p&gt;Lastly, we have Code Duplication. Remember that cringe moment when you arrived at a party, and someone was wearing the same dress? Code doesn't like that, either. Code Duplication means how many times we've got the same or very similar blocks of code in different places.&lt;/p&gt;

&lt;p&gt;Here's a guilty snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calculateDiscountA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$price&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calculateDiscountB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$price&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yikes! Same dress at the party! This is a classic example of unnecessary code duplication, where calculateDiscountA and calculateDiscountB are doing the same thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  To Sum It Up
&lt;/h2&gt;

&lt;p&gt;If you treat these three metrics like your trusty ol' Marauder's Map, they will reveal your PHP code's secrets, quirks, and areas for improvement. Remember, understanding these metrics isn't about nitpicking your code. It's about making it healthier, sturdier, and more flexible.&lt;/p&gt;

&lt;p&gt;Because at the end of the day, we want our code to be like that perfect piece of software - eloquent, efficient, and easier than Sunday morning!&lt;/p&gt;

&lt;p&gt;Happy Coding! May your bugs be minimal, and your coffee cup be always full!&lt;/p&gt;

&lt;p&gt;Until next time,&lt;br&gt;
Your Friendly Code Whisperer&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>php</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
