<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SpinOneSolutions &#187; Models</title>
	<atom:link href="http://www.spinonesolutions.com/tag/models/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.spinonesolutions.com</link>
	<description>I waste my time so that you don't have to...</description>
	<lastBuildDate>Fri, 16 Apr 2010 21:39:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Magento &#8211; Part IV : Extending Models</title>
		<link>http://www.spinonesolutions.com/2009/10/magento-part-iv-extending-models/</link>
		<comments>http://www.spinonesolutions.com/2009/10/magento-part-iv-extending-models/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 15:09:55 +0000</pubDate>
		<dc:creator>Will Wright</dc:creator>
				<category><![CDATA[Magento]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Models]]></category>

		<guid isPermaLink="false">http://www.spinonesolutions.com/?p=413</guid>
		<description><![CDATA[The Problem: You want to expand upon or change some functionality within Magento. The Solution: Extend a Model!  I’m going to use a real world example here because I believe that examples are the best tools for teaching. I was faced with a request for additional functionality in regards to the Authorize.net payment method.  Basically, [...]]]></description>
			<content:encoded><![CDATA[<h2>The Problem:</h2>
<p>You want to expand upon or change some functionality within Magento.</p>
<h2>The Solution:</h2>
<p>Extend a Model!  I’m going to use a real world example here because I believe that examples are the best tools for teaching.</p>
<p>I was faced with a request for additional functionality in regards to the Authorize.net payment method.  Basically, the customer wanted an email to be sent to an administrator if the gateway experienced an error while trying to processes a payment; a very reasonable request.</p>
<p>To accomplish this I extended <strong>Mage_Paygate_Model_Authorizenet</strong>, the model responsible for Authorize.net.  There are two very important reasons why I went about it the way I did.</p>
<p>First, as I mentioned earlier, all custom code should go in the /local/ directory.  If I had made my changes directly to <strong>Mage_Paygate_Model_Authorizenet</strong> (/core/Mage/Paygate/Model/Authorizenet) then the modifications would be in serious danger if the core were ever updated, essentially breaking the upgrade path.</p>
<p>Secondly, by extending the core class I can make reference to anything contained in the parent class.  This is good OOP architecture; I’m just adorning the parent class with additional functionality, leveraging all the work that has come before and maintaining good compartmentalization.</p>
<p>There are two basic steps to extending a core class.  Firstly, you need to create your new (custom) class in a custom Module living in /local/.  I’ll continue expanding upon my previous examples and make a new Model within Spinonesolutions/Helloworld.  I’m going to put the new Model in its own folder, mirroring the structure of the core.</p>
<p>Parent Class Path:<br />
/Mage/Paygate/Model/Authorizenet.php</p>
<p>Custom Class Path:<br />
/Spinonesolutions/Helloworld/Model/Paygate/Authorizenet.php</p>
<p>Naming conventions dictate that my custom Class’s name be:<br />
<strong>Spinonesolutions_Helloworld_Model_Paygate_Authorizenet</strong></p>
<p>Let’s jump right into the source and dissect what’s going on.</p>
<pre class="php" name="code">&lt;?php
class Spinonesolutions_Helloworld_Model_Paygate_Authorizenet extends Mage_Paygate_Model_Authorizenet {

  private $_order;

  function __construct() {
    parent::__construct();     
  }

  public function capture(Varien_Object $payment, $amount) {
    $this-&gt;_order = $payment-&gt;getOrder();
    try {
      parent::capture($payment,$amount);
    } catch (Exception $error) {
      $this-&gt;_sendEmail($error);
      throw $error;
    }           
    return $this;
  }
}</pre>
<p>The declaration is import to note because this is where we do the actual extending.  Although it’s not necessary for this example I’ve included a call to the constructor, and placed a call to the parent constructor within it.  This way, both the custom and parent model are instantiated correctly.</p>
<p>OK, onto the meat, the <strong>capture()</strong> function.  To fully understand this we need to understand what we’re trying to extend.  Looking at <strong>Mage_Paygate_Model_Authorizenet</strong> (/Mage/Paygate/Model/Authorizenet.php) will yield the answer.</p>
<p>As you can see <strong>Mage_Paygate_Model_Authorizenet</strong> contains a capture method with the exact same signature: <strong>public function capture(Varien_Object $payment, $amount)</strong>.  What I’m doing is overriding this method with my method.  I add my additional functionality and then call the parent method at the appropriate time to drop the system back into its default workflow.</p>
<p>Notice that all I’m doing is wrapping the parent method call in a try catch block so that if an Exception is thrown I can catch it and send an email.  I’ve successfully extended the core functionality without touching a line of the core code!</p>
<p>I’ve left out one small, but hugely important bit of information.  In order to get this to work we have to let Magento know that there’s a custom Model which overrides this particular Model.  To accomplish this we turn to the <strong>config.xml</strong>.</p>
<pre class="xml" name="code">&lt;?xml version=<em>"1.0"</em> encoding=<em>"UTF-8"</em> ?&gt;
&lt;config&gt;
      &lt;modules&gt;
            &lt;Spinonesolutions_Helloworld&gt;
                  &lt;version&gt;0.1.0&lt;/version&gt;
            &lt;/Spinonesolutions_Helloworld&gt;
      &lt;/modules&gt;
    &lt;frontend&gt;
        &lt;routers&gt;
            &lt;spinonesolutions&gt;      &lt;!-- I make this match my front name but I'm not sure it matters --&gt;
                &lt;use&gt;standard&lt;/use&gt; &lt;!-- Use standard routing as opposed to admin.  IE: frontend vs admin --&gt;
                &lt;args&gt;
                    &lt;module&gt;Spinonesolutions_Helloworld&lt;/module&gt;  &lt;!-- The module to search for controllers --&gt;
                    &lt;frontName&gt;spinonesolutions&lt;/frontName&gt; &lt;!-- The first descriminator in the path.  "spinonesolutions" in http://localhost/spinonesolutions/ --&gt;
                &lt;/args&gt;
            &lt;/spinonesolutions&gt;
        &lt;/routers&gt;
    &lt;/frontend&gt;
      &lt;global&gt;
            &lt;models&gt;
                  &lt;spinonesolutions_helloworld&gt; &lt;!-- This is used when istanting your Model EG: Mage::getModel("spinonesolutions_helloworld/hellworld") --&gt;
                        &lt;class&gt;Spinonesolutions_Helloworld_Model&lt;/class&gt;      &lt;!-- That class to use when isntanting objects of type above. --&gt;
                  &lt;/spinonesolutions_helloworld&gt;
              &lt;paygate&gt;
                  &lt;rewrite&gt;
                        &lt;authorizenet&gt;Spinonesolutions_Helloworld_Model_Paygate_Authorizenet&lt;/authorizenet&gt;
                  &lt;/rewrite&gt;
              &lt;/paygate&gt;
            &lt;/models&gt;
      &lt;/global&gt;
&lt;/config&gt;</pre>
<p>Notice line:24 and the <strong>paygate</strong> element.  This is the element that is telling Magento to now look in our custom class for the Model, and not the core.</p>
<p>That’s all there is to it!  You can now extend Magento’s core functionality to your heart’s content.</p>
<p>I bet you astute readers out there noticed that ALL of the models thus far have extended a core class.  My first Model <strong>Spinonesolutions_Helloworld_Model_Helloworld</strong> extends <strong>Varien_Object</strong>.  Even the controllers extend <strong>Mage_Core_Controller_Front_Action</strong>.</p>
<p>Oh Snap!</p>
<p>Download the source &#8211; <a href="http://www.spinonesolutions.com/wp-content/uploads/2009/10/Helloworld_v3.rar">Helloworld_v3</a></p>
<ol>
<li><a title="Part I : Custom Module" href="http://www.spinonesolutions.com/2009/09/magento-custom-module-part-i/">Part I : Custom Module</a></li>
<li><a title="Part II : Models" href="http://www.spinonesolutions.com/2009/10/magento-part-ii-models/">Part II : Models</a></li>
<li><a title="Part III : Controllers" href="http://www.spinonesolutions.com/2009/10/magento-part-iii-controllers/">Part III : Controllers</a></li>
<li><a title="Part IV : Extending Models" href="http://www.spinonesolutions.com/2009/10/magento-part-iv-extending-models/">Part IV : Extending Models</a></li>
<li><a title="Part V: Data Layer" href="http://www.spinonesolutions.com/2009/10/magento-part-v-data-layer/">Part V : Data Layer</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.spinonesolutions.com/2009/10/magento-part-iv-extending-models/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
