<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://www.modernmerchant.org" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>Modern Merchant - Plugin Tutorial - Comments</title>
 <link>http://www.modernmerchant.org/documentation/plugin-guide</link>
 <description>Comments for &quot;Plugin Tutorial&quot;</description>
 <language>en</language>
<item>
 <title>Plugin Tutorial</title>
 <link>http://www.modernmerchant.org/documentation/plugin-guide</link>
 <description>&lt;h3&gt;Table of Contents&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;/crss/node/30#overview&quot;&gt;Overview&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/crss/node/30#stub&quot;&gt;Installing the Stub Plugin&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/crss/node/30#action&quot;&gt;Linking a URL to an Action&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/crss/node/30#view&quot;&gt;Separate out HTML to a template&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/crss/node/30#menu&quot;&gt;Adding to the Admin Menu&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/crss/node/30#override-actions&quot;&gt;Overriding Actions&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/crss/node/30#override-templates&quot;&gt;Overriding Templates&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
function setPluginNames(name)
{
  var ucname = name.toUpperCase()[0] + name.substring(1);
  var spans = document.getElementsByTagName(&quot;span&quot;);
  for (var i=0; i &lt; spans.length; i++) {
    if (spans[i].className == &quot;pluginname&quot;) {
      var text = spans[i].innerHTML;
      if (text[0] == ucname[0]) {
        spans[i].innerHTML = ucname;
      }
      else {
        spans[i].innerHTML = name;
      }
    }
  }
}
&lt;/script&gt;

&lt;a name=&quot;overview&quot;&gt;&lt;/a&gt;
&lt;h3&gt;Overview&lt;/h3&gt;

&lt;p&gt;This tutorial will show you how to create a plugin. The plugin will do the following:&lt;/p&gt;
&lt;ul style=&quot;margin-bottom: 20px&quot;&gt;
  &lt;li&gt;Install itself by creating a database table and adding three records&lt;/li&gt;
  &lt;li&gt;Display a page&lt;/li&gt;
  &lt;li&gt;Set the page&#039;s title&lt;/li&gt;
  &lt;li&gt;Set the window&#039;s title&lt;/li&gt;
  &lt;li&gt;Pass some text to the page&lt;/li&gt;
  &lt;li&gt;Pass objects from the database to the page&lt;/li&gt;
  &lt;li&gt;Pass a notification message to the user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The page will look like this:&lt;/p&gt;
&lt;div style=&quot;border: 1px solid #aaa; margin-bottom: 20px&quot;&gt;
	&lt;img src=&quot;/images/show-action.png&quot; width=&quot;464&quot; height=&quot;258&quot; /&gt;
&lt;/div&gt;

&lt;a name=&quot;stub&quot;&gt;&lt;/a&gt;
&lt;h3&gt;Installing the Stub Plugin&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    Decide on a name for your plugin. The current naming convention for plugin
    names is all lower-case, letters and numbers only. The recommendation may
    change to include upper-case letters in the future. Do not
    include non-alphanumeric characters.

&lt;p&gt;Enter your plugin name below to make the rest of the tutorial clearer:
&lt;form method=&quot;GET&quot; action=&quot;javascript:;&quot; onclick=&quot;return false&quot;&gt;
&lt;input type=&quot;text&quot; id=&quot;pluginname&quot; onchange=&quot;setPluginNames(this.value)&quot; /&gt;
&lt;input type=&quot;submit&quot; value=&quot;Set&quot; /&gt;
&lt;/form&gt;

  &lt;/li&gt;
  &lt;li&gt;
    Create a folder in &lt;code&gt;mm/plugins&lt;/code&gt; of your Modern Merchant
    installation. Give it the name of your plugin. This will be your plugin&#039;s folder.
  &lt;/li&gt;
  &lt;li&gt;
    Create a new file in your plugin&#039;s folder called &lt;/code&gt;Plugin.php&lt;/code&gt;.
    Paste this PHP code into the file:
    &lt;pre&gt;&lt;/code&gt;&amp;lt;?php
/**
 * &lt;span class=&quot;pluginname&quot;&gt;Sample&lt;/span&gt; plugin.
 */
class &lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Plugin extends plugin_Base
{
    function info()
    {
        return array(
            &#039;title&#039;   =&gt; &#039;&lt;span class=&quot;pluginname&quot;&gt;Sample&lt;/span&gt; Plugin&#039;,
            &#039;version&#039; =&gt; &#039;0.1&#039;,
            &#039;author&#039;  =&gt; &#039;Your Name&#039;,
            &#039;url&#039;     =&gt; &#039;http://www.example.com/&#039;,
            &#039;depends&#039; =&gt; array(&#039;mm&#039;));
    }

    /**
     * Called automatically for each request if the plugin is active.
     */
    function init()
    {
    }

    /**
     * Called automatically when Modern Merchant is installed, and when user
     * requests that the plugin be installed.
     */
    function install()
    {
        $db = mm_getDatabase();
        $db-&gt;execute(&quot;DROP TABLE IF EXISTS mm_comment&quot;);
        $db-&gt;execute(&quot;
        CREATE TABLE mm_comment (
            id int not null auto_increment,
            subject varchar(255) not null,
            comment text,
            PRIMARY KEY (id)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8
        &quot;);
        $db-&gt;execute(&quot;INSERT INTO mm_comment (subject, comment) VALUES (?,?)&quot;, array(&quot;morning&quot;, &quot;It&#039;s too early&quot;));
        $db-&gt;execute(&quot;INSERT INTO mm_comment (subject, comment) VALUES (?,?)&quot;, array(&quot;coffee&quot;, &quot;Double Soy Latte&quot;));
        $db-&gt;execute(&quot;INSERT INTO mm_comment (subject, comment) VALUES (?,?)&quot;, array(&quot;wifi&quot;, &quot;WiFi Required&quot;));
        return true;
    }

    /**
     * Called automatically when user requests that the plugin to be uninstalled.
     */
    function uninstall()
    {
        $db = mm_getDatabase();
        $db-&gt;execute(&quot;DROP TABLE IF EXISTS mm_comment&quot;);
        return true;
    }
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Change the class name: replace &quot;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;&quot; with your plugin&#039;s name.
  &lt;/li&gt;
  &lt;li&gt;
    Change the &#039;title&#039; element returned from the &lt;code&gt;info()&lt;/code&gt; method.
  &lt;/li&gt;
  &lt;li&gt;
    With a browser, visit the Modern Merchant administrative interface.
    Navigate to &lt;code&gt;Configuration -&amp;gt; Plugins&lt;/code&gt;. You should
    see your plugin listed there.
  &lt;/li&gt;
  &lt;li&gt;Click &lt;u&gt;install&lt;/u&gt; next to your plugin. This installs and activates your plugin.&lt;/li&gt;
&lt;/ol&gt;

&lt;a name=&quot;action&quot;&gt;&lt;/a&gt;
&lt;h3&gt;Linking a URL to an Action&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    Copy this skeleton code and paste into a file called &lt;code&gt;Controller.php&lt;/code&gt;, saved to your plugin&#039;s folder:
    &lt;pre&gt;&lt;code&gt;&amp;lt;php
class &lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Controller extends mvc_PublicController
{
    function runShowAction()
    {
        echo &quot;Hello, world!&quot;;
        return $this-&gt;goToView();
    }
}
&lt;/pre&gt;&lt;/code&gt;
  &lt;/li&gt;
  &lt;li&gt;
    With a web browser, go to the web site&#039;s home page, for instance, 
    http://www.example.com/, then change the address so that it ends with
    &lt;code&gt;?a=&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;.show&lt;/code&gt;, replacing
    &#039;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;&#039; with your
    plugin&#039;s name.
  &lt;/li&gt;
  &lt;li&gt;
    If your plugin is going to have a public facing interface and an admin interface, you should have two
    separate controllers. The admin controller should go inside a folder called
    &lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/admin&lt;/code&gt;.
    The file should also be called &lt;code&gt;Controller.php&lt;/code&gt;, and the class should be called
	&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_admin_Controller&lt;/code&gt;.
    Requests that have &lt;code&gt;a=&lt;span class=&quot;pluginname&quot;&gt;sample_admin&lt;/span&gt;&lt;/code&gt; in them will go to
    the &lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_admin_Controller&lt;/code&gt;.
  &lt;/li&gt;
&lt;/ol&gt;

&lt;a name=&quot;view&quot;&gt;&lt;/a&gt;
&lt;h3&gt;Putting the HTML in a separate template&lt;/h3&gt;

&lt;p&gt;To separate out your View from the Controller, create a folder inside your plugin directory called
&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/templates&lt;/code&gt;. Then, add a file called
&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/templates/show.php&lt;/code&gt;
to the templates folder.&lt;/p&gt;

&lt;p&gt;Paste the following code into the file:&lt;/p&gt;

&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/templates/show.php&lt;/code&gt;:
&lt;code&gt;&lt;pre&gt;&amp;lt;p&amp;gt;Greeting: &amp;lt;?php ph($this-&amp;gt;greeting) ?&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;?php foreach($this-&amp;gt;comments as $comment): ?&amp;gt;
&amp;lt;fieldset&amp;gt;
	&amp;lt;legend&amp;gt;&amp;lt;?php ph($comment-&amp;gt;subject) ?&amp;gt;&amp;lt;/legend&amp;gt;
	&amp;lt;?php ph($comment-&amp;gt;comment) ?&amp;gt;
&amp;lt;/fieldset&amp;gt;
&amp;lt;?php endforeach ?&amp;gt;&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Next, you&#039;ll create your plugin&#039;s primary business model. Copy and paste this
code into a file called &lt;code&gt;Comment.php&lt;/code&gt;:&lt;/p&gt;
&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/Comment.php&lt;/code&gt;:
&lt;code&gt;&lt;pre&gt;&amp;lt;?php
class &lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Comment extends mvc_Model {
    public $id;
    public $subject;
    public $comment;
}
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Copy and paste this code into a file called &lt;code&gt;CommentDAO.php&lt;/code&gt;:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;&amp;lt;?php
class &lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_CommentDAO extends mvc_DataAccess {
}
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Back in the controller, change the &lt;code&gt;runShowAction()&lt;/code&gt; method so that it 
looks like this:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;&amp;lt;php
class &lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Controller extends mvc_PublicController
{
    function runShowAction() {
        // Fetch data from database and pass it to the template
        $dao = new sample_CommentDAO;
        $this-&gt;comments = $dao-&gt;find();              // Get all comments

        $this-&gt;title = &quot;&#039;Show&#039; Action&quot;;             // Set the page (&amp;lt;h1&amp;gt;) title
        $this-&gt;addNotice(&quot;Something happened.&quot;);    // Send a notice to the user
        $this-&gt;greeting = &quot;Hello, world!&quot;;          // Send some data to the template
    }
}&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;The first two lines within &lt;code&gt;rowShowAction()&lt;/code&gt; will fetch all the records from the
    &lt;code&gt;mm_&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;&lt;/code&gt; database table, return them
    as objects, and assign them to a template variable called &lt;code&gt;$samples&lt;/codes&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;$this-&gt;title&lt;/code&gt; is a special template variable that sets the page&#039;s &amp;lt;h1&amp;gt; title.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;$this-&gt;addNotice()&lt;/code&gt; is called, the theme will display the message on the page
  when it is displayed, even if the next page occurs after a redirect.&lt;/p&gt;

&lt;p&gt;In addition to &lt;code&gt;$this-&gt;addNotice()&lt;/code&gt;, there is a method called
    &lt;code&gt;$this-&gt;addWarning()&lt;/code&gt; that is for
  sending an error message to the user. The site&#039;s theme should display the warning message differently
  that a notice.&lt;/p&gt;

&lt;p&gt;The last line in the function assigns a string to a new template variable called
    &lt;code&gt;$this-&gt;greeting&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is the resulting page again, annotated with the code that assigns the page&#039;s content:&lt;/p&gt;

&lt;div style=&quot;border: 1px solid #aaa&quot;&gt;
    &lt;img src=&quot;/images/show-action-annotated.png&quot; width=&quot;516&quot; height=&quot;258&quot; /&gt;
&lt;/div&gt;
    
&lt;a name=&quot;menu&quot;&gt;&lt;/a&gt;
&lt;h3&gt;Adding a menu item to the Administrator Menu&lt;/h3&gt;

&lt;p&gt;To add a menu item to the Adminstrator menu, just add a line of code to your plugin&#039;s &lt;code&gt;init()&lt;/code&gt; method:&lt;/p&gt;

&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/Plugin.php&lt;/code&gt;
&lt;code&gt;&lt;pre&gt;&amp;lt;?php
class &lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Plugin
{
    //...

    function init()
    {
        mvc_Hooks::registerMenuItem(array(
            &#039;path&#039;  =&gt; &#039;admin/website/&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;&#039;,
            &#039;action&#039;=&gt;&#039;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;.transactions&#039;,
            &#039;label&#039; =&gt; &#039;&lt;span class=&quot;pluginname&quot;&gt;Authnet&lt;/span&gt; Transactions&#039;));
    }
}&lt;/pre&gt;&lt;/code&gt;

&lt;a name=&quot;override-actions&quot;&gt;&lt;/a&gt;
&lt;h3&gt;Overriding Actions&lt;/h3&gt;

&lt;p&gt;Sometimes, plugins need to override actions that are normally executed by
  other plugins. Modern Merchant&#039;s hook system makes
  this possible. For instance, if you want your plugin to override the cart.cart
  action (that&#039;s the action that displays the cart), you would use the
  hook system to map you own action to the
  cart.cart address.&lt;/p&gt;

&lt;p&gt;While the hook system doesn&#039;t allow you to override individual actions
  directly, it does allow you to override entire controllers. With a bit of
  work, it is possible to override only specific actions of the controller,
  while passing control to the original controller for the remaining
  actions.&lt;/p&gt;

&lt;p&gt;In the future, Modern Merchant will allow plugins to override individual
  actions without overriding the entire controller.&lt;/p&gt;

&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/Plugin.php&lt;/code&gt;:
&lt;code&gt;&lt;pre&gt;&amp;lt;?php
class &lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Plugin
{
    //...

    function init()
    {
        $plugin_name = &#039;cart&#039;;
        $object_or_classname = &#039;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Controller&#039;;

        mvc_Hooks::registerController($plugin_name, $object_or_classname);
    }
}&lt;/pre&gt;&lt;/code&gt;

&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/Controller.php&lt;/code&gt;:
&lt;code&gt;&lt;pre&gt;&amp;lt;?php
class &lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Controller extends cart_Controller
{
    function runCartAction() {
        // Copy the code from cart_Controller::runShowAction(),
        // then customize it here
    }
}&lt;/pre&gt;&lt;/code&gt;

Now, when the cart.cart action is executed, the code in
&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Controller::runCartAction()&lt;/code&gt;
is executed instead of the code in
&lt;code&gt;cart_Controller::runCartAction()&lt;/code&gt;.


&lt;a name=&quot;override-templates&quot;&gt;&lt;/a&gt;
&lt;h3&gt;Overriding Templates&lt;/h3&gt;

&lt;p&gt;Sometimes, you want to override templates from other plugins. Using the
  technique for overriding actions, described above, it is possible to accomplish
  this.&lt;/p&gt;

&lt;p&gt;In the future, Modern Merchant will allow you to override templates
  directly, without overriding controllers and actions first.&lt;/p&gt;

&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/Plugin.php&lt;/code&gt;:
&lt;code&gt;&lt;pre&gt;&amp;lt;?php
class &lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Plugin
{
    //...

    function init()
    {
        $plugin_name = &#039;cart&#039;;
        $object_or_classname = &#039;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Controller&#039;;

        mvc_Hooks::registerController($plugin_name, $object_or_classname);
    }
}&lt;/pre&gt;&lt;/code&gt;

&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/Controller.php&lt;/code&gt;:
&lt;code&gt;&lt;pre&gt;&amp;lt;?php
class &lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;_Controller extends cart_Controller
{
    function runCartAction() {
        $result = parent::runShowAction();
        return $this-&gt;goToView(&#039;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;.cart&#039;);
    }
}&lt;/pre&gt;&lt;/code&gt;

&lt;code&gt;&lt;span class=&quot;pluginname&quot;&gt;sample&lt;/span&gt;/templates/cart.php&lt;/code&gt;:
&lt;code&gt;&lt;pre&gt;&amp;lt;?php
/* Copy mm/plugins/cart/templates/cart.php to this file, then
customize it here. */
&lt;/pre&gt;&lt;/code&gt;
</description>
 <comments>http://www.modernmerchant.org/documentation/plugin-guide#comment</comments>
 <pubDate>Sun, 29 Oct 2006 21:15:35 -0700</pubDate>
 <dc:creator>moxley</dc:creator>
 <guid isPermaLink="false">30 at http://www.modernmerchant.org</guid>
</item>
</channel>
</rss>
