[ Index ]

PHP Cross Reference of Nucleus CMS 3.32

title

Body

[close]

/nucleus/documentation/devdocs/ -> plugins.html (source)

   1  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
   2  <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
   3  <head>
   4      <!-- $Id: plugins.html 1177 2007-06-22 12:37:32Z kaigreve $ -->
   5      <title>Nucleus - Plugin API</title>
   6      <link rel="stylesheet" type="text/css" href="styles/manual.css" />
   7      <style type="text/css">
   8          /* refence parameters (greenish) */
   9          .ref {
  10              background-color: #afa;
  11              color: #000;
  12          }
  13  
  14          /* object parameters */
  15          .obj {
  16              color: #00f;
  17          }
  18          .obj:after {
  19              content: " (object)";
  20          }
  21  
  22          /* read-only parameters (non-ref; reddish) */
  23          .ro {
  24              background-color: #faa;
  25              color: #000;
  26          }
  27      </style>
  28  </head>
  29  <body>
  30  
  31  <div class="heading">
  32  Plugin API
  33  <i>June 16, 2007</i>
  34  </div>
  35  
  36  <div class="note"><strong>Notes:</strong>
  37      <ul>
  38          <li>This document should contain enough information to write basic plugins. If you have more questions, see the <a href="http://forum.nucleuscms.org/viewforum.php?f=10">Plugin Development Forum</a></li>
  39          <li>Methods and events introduced after Nucleus v1.5 was released have the Nucleus version in which they were introduced listed. If you use any of those functions, don't forget to adapt <code>getMinNucleusVersion</code> appropriately.
  40          </li>
  41    </ul>
  42  </div>
  43  
  44  <h1>Introduction</h1>
  45  
  46  <p>
  47  <a href="index.html">Back to the developer docs index</a>
  48  </p>
  49  
  50  <p>
  51  This document contains information on how you can write your own Nucleus plugins
  52  </p>
  53  
  54  <h1><a name="toc"></a><a name="top"></a>Table Of Contents</h1>
  55  
  56  <ul>
  57      <li><a href="#introduction">Introduction</a></li>
  58      <li><a href="#firstplug">Writing your first plugin</a></li>
  59      <li><a href="#nucleusplugin">Overview of the <code>NucleusPlugin</code> class</a></li>
  60      <li><a href="#skinvars">The <code>&lt;%plugin(...)%&gt;</code> skinvar</a></li>
  61      <li><a href="#templatevars">The <code>&lt;%plugin(...)%&gt;</code> templatevar</a></li>
  62      <li><a href="#actions">Actions using <code>action.php</code></a></li>
  63      <li><a href="#events">Events, and subscribing to them</a></li>
  64      <li><a href="#options">Saving options</a></li>
  65      <li><a href="#tables">Database tables</a></li>
  66      <li><a href="#admin">Providing an admin area</a></li>
  67      <li><a href="#help">Providing a helppage</a></li>
  68      <li><a href="#dependency">Plugin Dependency Check</a></li>
  69  <!--    <li><a href="#parser">Using the <code>PARSER</code> class</a></li>
  70      <li><a href="#"></a></li>
  71      <li><a href="#"></a></li>
  72      <li><a href="#"></a></li>
  73      <li><a href="#"></a></li>-->
  74  </ul>
  75  
  76  <h1>Introduction <a name="introduction" href="#top" class="toplink"><img src="../icon-up.gif" width="15" height="15" alt="back to top" /></a></h1>
  77  
  78  <p>
  79  Nucleus plugins allow just about anyone to extend the functionality that Nucleus offers, without having to alter the PHP code itself. Plugins are simple php scripts that must implement certain methods, and can easily be exchanged between Nucleus users. Installing goes as easy as adding the plugin file to the plugin directory and letting Nucleus know it's there.
  80  </p>
  81  
  82  <p>
  83  Some advantages of plugins are listed below:
  84  </p>
  85  
  86  <ul>
  87      <li>Extra functionality can easily be added to the Nucleus framework, without having to know much details about the implementation.</li>
  88      <li>You can install only the plugins you need, saving on the time needed to generate a page</li>
  89  </ul>
  90  
  91  <p>
  92  All plugin files should be placed in the directory that is listed in <code>config.php</code>. Commonly, this will be <code>/your/path/nucleus/plugins/</code>. Plugin files can be recognized by their form: <code>NP_<i>name</i>.php</code>. Some plugins require a subdirectory with the same <i>name</i> to store extra files or their admin area.
  93  </p>
  94  
  95  <div class="note">
  96  <b>Note:</b> the names are case-sensitive, so they should start with <code>NP_</code>, not <code>Np_</code> or <code>np_</code>. Also note that when the plugin uses a subdirectory, the name of that directory should be <em>all lowercase</em>.
  97  </div>
  98  
  99  
 100  
 101  
 102  <h1>Writing your first plugin <a name="firstplug" href="#top" class="toplink"><img src="../icon-up.gif" width="15" height="15" alt="back to top" /></a></h1>
 103  
 104  <p>
 105  Ok, lets start by writing a simple plugin. Basically, each plugin is a PHP class that inherits from the predefined class <code>NucleusPlugin</code>. Below is an example of a <code>HelloWorld</code>-plugin:
 106  </p>
 107  
 108  <pre class="example"><code>&lt;?php
 109  
 110  class NP_HelloWorld extends NucleusPlugin
 111  {
 112      // name of plugin
 113  	function getName()
 114      {
 115          return 'Hello World';
 116      }
 117  
 118      // author of plugin
 119  	function getAuthor()
 120      {
 121          return 'Wouter Demuynck';
 122      }
 123  
 124      // an URL to the plugin website
 125      // can also be of the form mailto:foo@bar.com
 126  	function getURL()
 127      {
 128          return 'http://nucleuscms.org/';
 129      }
 130  
 131      // version of the plugin
 132  	function getVersion()
 133      {
 134          return '1.0';
 135      }
 136  
 137      // a description to be shown on the installed plugins listing
 138  	function getDescription()
 139      {
 140          return 'Just a sample plugin.';
 141      }
 142  
 143  	function doSkinVar($skinType)
 144      {
 145          echo 'Hello World!';
 146      }
 147  
 148  	function supportsFeature ($what)
 149      {
 150          switch ($what)
 151          {
 152              case 'SqlTablePrefix':
 153                  return 1;
 154              default:
 155                  return 0;
 156          }
 157      }
 158  
 159  }
 160  ?&gt;</code></pre>
 161  
 162  <ol>
 163      <li>
 164          Copy this code in a file called <code>NP_HelloWorld.php</code>, and put it in your plugins directory. <em>Make sure that there are no spaces after the last <code>?&gt;</code> or before the first <code>&lt;?php</code>.</em>. NP stands for "Nucleus Plugin", if you were wondering about that.
 165      </li>
 166      <li>Open the Nucleus Administration area and go into <em>Nucleus Management/Manage Plugins</em></li>
 167      <li>You'll find out that there's a <em>HelloWorld</em> plugin you can install. Do this. If everything worked out correctly, you'll see that your plugin is now listed in the list of installed plugins.</li>
 168      <li>
 169          Now edit one of your skins and insert the following statement at a place of which you know where it will show up on the actual page.
 170  <pre class="example"><code>&lt;%HelloWorld%&gt;</code></pre>
 171          Note that the name (<code>HelloWorld</code>) is case sensitive!
 172      </li>
 173      <li>Now visit a page that uses the skin you edited: notice the "Hello World" at the location where you've added the <code>plugin</code>-skinvar.</li>
 174  </ol>
 175  
 176  <p>
 177  So, that wasn't so hard after all. Read on to find out more.
 178  </p>
 179  
 180  
 181  
 182  
 183  
 184  
 185  
 186  <h1>The class NucleusPlugin <a name="nucleusplugin" href="#top" class="toplink"><img src="../icon-up.gif" width="15" height="15" alt="back to top" /></a></h1>
 187  
 188  <p>All Nucleus plugins must inherit from the PHP class <code>NucleusPlugin</code>. If this sounds complicated, don't worry, it isn't. It even makes your life easier, allowing you to only implement the methods that your plugin needs, and giving access to some auxiliary functions.</p>
 189  
 190  <p>Below is an overview of the methods that the <code>NucleusPlugin</code> offers, and that you can re-implement in your own plugin. If you want to see the source of the class itsself, it's located at <code>nucleus/libs/PLUGIN.php</code></p>
 191  
 192  <table summary="An overview of the redefinable methods in the class NucleusPlugin">
 193      <caption>Overview of the class <code>NucleusPlugin</code> (redefinable methods)</caption>
 194      <tr>
 195          <th>Method&nbsp;Signature</th><th>Explanation</th>
 196      </tr>
 197      <tr>
 198          <td><code>getName()</code></td>
 199          <td>Returns the name of the plugin. This will be the name that will show up on the list of installed plugins. You should definately redefine this method, since the default implementation returns <q>Undefined</q></td>
 200      </tr>
 201      <tr>
 202          <td><code>getAuthor()</code></td>
 203          <td>Returns the name of author of the plugin. This name will show up on the list of installed plugins. You should definately redefine this method, since the default implementation returns <q>Undefined</q></td>
 204      </tr>
 205      <tr>
 206          <td><code>getURL()</code></td>
 207          <td>Returns the URL of the site where the plugin can be downloaded, or where additional information about the plugin can be found. If no such site exists, a <code>mailto:</code>-link with the authors email address is appropriate. You should definately redefine this method, since the default implementation returns <q>Undefined</q></td>
 208      </tr>
 209      <tr>
 210          <td><code>getDescription()</code></td>
 211          <td>Returns a longer description of the plugin. This will show up on the list of installed plugins. The default implementation returns <q>Undefined</q></td>
 212      </tr>
 213      <tr>
 214          <td><code>getVersion()</code></td>
 215          <td>Returns the current version of the plugin. Returns <q>0.0</q> by default</td>
 216      </tr>
 217      <tr>
 218          <td><code>getMinNucleusVersion()</code></td>
 219          <td>(v2.0b) Returns the minimum required Nucleus version. By default, this returns <code>155</code> (v1.55). If you are using plugin features that were introduced later, please implement this function (e.g. v2.0 => 200). Please note that Nucleus v1.55 does not use this function at all, so it remains possible to install newer plugins there, even if they use newer features.</td>
 220      </tr>
 221      <tr>
 222          <td><code>getMinNucleusPatchLevel()</code></td>
 223          <td>(v3.1) Returns the minimum required Nucleus patch level that needs to be present when running the minimal required Nucleus version (<code>getMinNucleusVersion</code>). By default, this returns <code>0</code>. This function is generally used when new plugin features are available only as patches to the latest released Nucleus version.</td>
 224      </tr>
 225      <tr>
 226          <td><code>init()</code></td>
 227          <td>Initializes the plugin. This method gets called immediately after the plugin object is created and the <code>plugid</code>-attribute has been set. By default, this method does nothing.</td>
 228      </tr>
 229      <tr>
 230          <td><code>doSkinVar($skinType)</code></td>
 231          <td>When plugins are called using the <code>&lt;%plugin(...)%&gt;</code>-skinvar, this method will be called. the <code>$skinType</code> parameter contains the type of skin (<code>item</code>, <code>archive</code>, ...) from where the plugin is called. Don't get confused by the fact that there's only one parameter. Multiple parameters <strong>can</strong> still be passed. <a href="#skinvars">More info on implementing the <code>doSkinVar</code> method.</a> By default, this method does no output at all.</td>
 232      </tr>
 233      <tr>
 234          <td><code>doTemplateVar(&amp;$item)</code></td>
 235          <td>Basically the same as <code>doSkinVar</code>, but this time for calls of the &lt;%plugin(...)%&gt;-var in <i>templates</i> (item header/body/footer and dateheader/footer). By default, this method forwards the handling to the <code>doSkinVar</code>-method, using <code>template</code> as skintype. <a href="#templatevars">More information on implementing the <code>doTemplateVar</code> method</a></td>
 236      </tr>
 237      <tr>
 238          <td><code>doTemplateCommentsVar(&amp;$item, &amp;$comment)</code></td>
 239          <td>(v2.0b) Basically the same as <code>doSkinVar</code>, but this time for calls of the &lt;%plugin(...)%&gt;-var in <i>templates</i> (comments-related parts). By default, this method forwards the handling to the <code>doSkinVar</code>-method, using <code>template</code> as skintype. <a href="#templatevars">More information on implementing the <code>doTemplateCommentsVar</code> method</a></td>
 240      </tr>
 241      <tr>
 242          <td><code>doAction($type)</code></td>
 243          <td>When a plugin wants to allow user interaction, it can allow actions through <code>action.php</code>. This is the script that Nucleus uses itself to handle new comments and karma votes. Called with the correct parameters, the <code>doAction</code>-method from a plugin can be called. The <code>$type</code> contains an optional message type. Extra variables from the request can be accessed from within the <code>doAction</code> method. By default, this method returns a string <q>No Such Action</q> which will trigger an error message. <a href="#actions">More info on <code>doAction</code>.</a></td>
 244      </tr>
 245      <tr>
 246          <td><code>install()</code></td>
 247          <td>This method gets called on the moment the plugin is installed. It can perform initializing actions, such as the creation of database tables, the creation of plugin options, etc... By default, this method does nothing.</td>
 248      </tr>
 249      <tr>
 250          <td><code>unInstall()</code></td>
 251          <td>Called when the plugin is uninstalled. It's a good thing to clean up information your plugin created in the database at this point. By default, this method does nothing.</td>
 252      </tr>
 253      <tr>
 254          <td><code>getEventList()</code></td>
 255          <td>Plugins can subscribe to events. Events get generated whenever Nucleus performs a certain action. An <code>AddItem</code> event for example, will call all plugins that subscribed to this event. The called method will be <code>event_AddItem($params)</code>. The <code>$params</code>-parameter is an associative array containing several fields of information, like the itemid for <code>AddItem</code>. Returns an empty array by default, indicating that the plugin does not subscribe to any event at all. <a href="#events">More information about events.</a></td>
 256      </tr>
 257      <tr>
 258          <td><code>getTableList()</code></td>
 259          <td>This method should return an array of database tables that the plugin has created. It's used in the backup feature that Nucleus offers, so plugin tables are also included in the backup. By default, returns an empty array.</td>
 260      </tr>
 261      <tr>
 262          <td><code>hasAdminArea()</code></td>
 263          <td>Should return <code>1</code> if the plugin has an admin area of its own, and <code>0</code> if it doesn't. By default, <code>0</code> is returned.</td>
 264      </tr>
 265      <tr>
 266          <td><code>getPluginDep()</code></td>
 267          <td>(v3.2) Returns an array of plugin names. Nucleus refuses to install the plugin if any of these plugins is not installed. By default, an empty array is returned. <a href="#dependency">More information on plugin dependencies.</a></td>
 268      </tr>
 269  </table>
 270  
 271  <p>Next to the methods that can be implemented, the class <code>NucleusPlugin</code> offers some extra methods which you <em>should not</em> implement yourself. They can be called from within your plugin using the <code>$this-&gt;functionName()</code> syntax.</p>
 272  
 273  <table summary="An overview of the auxiliary methods in the class NucleusPlugin. You should NOT redefine these">
 274      <caption>Overview of the class <code>NucleusPlugin</code> (non-redefinable methods)</caption>
 275      <tr>
 276          <th>Method&nbsp;Signature</th><th>Explanation</th>
 277      </tr>
 278      <tr>
 279          <td>
 280                    <code>createOption(...)</code>
 281              <br /><code>createBlogOption(...)</code>(v2.2)
 282              <br /><code>createCategoryOption(...)</code>(v2.2)
 283              <br /><code>createMemberOption(...)</code>(v2.2)
 284        <br /><code>createItemOption(...)</code>(v3.2)
 285          </td>
 286          <td><a href="#options" title="More info on options">Creates a new option</a></td>
 287      </tr>
 288      <tr>
 289          <td>
 290                    <code>deleteOption(...)</code>
 291              <br /><code>deleteBlogOption(...)</code>(v2.2)
 292              <br /><code>deleteCategoryOption(...)</code>(v2.2)
 293              <br /><code>deleteMemberOption(...)</code>(v2.2)
 294        <br /><code>deleteItemOption(...)</code>(v3.2)
 295          </td>
 296          <td><a href="#options" title="More info on options">Deletes an option</a></td>
 297      </tr>
 298      <tr>
 299          <td>
 300                    <code>setOption(...)</code>
 301              <br /><code>setBlogOption(...)</code>(v2.2)
 302              <br /><code>setCategoryOption(...)</code>(v2.2)
 303              <br /><code>setMemberOption(...)</code>(v2.2)
 304        <br /><code>setItemOption(...)</code>(v3.2)
 305          </td>
 306          <td><a href="#options" title="More info on options">Sets the value of an option</a></td>
 307      </tr>
 308      <tr>
 309          <td>
 310                    <code>getOption(...)</code>
 311              <br /><code>getBlogOption(...)</code>(v2.2)
 312              <br /><code>getCategoryOption(...)</code>(v2.2)
 313              <br /><code>getMemberOption(...)</code>(v2.2)
 314        <br /><code>getItemOption(...)</code>(v3.2)
 315          </td>
 316          <td><a href="#options" title="More info on options">Retrieves the value of an option</a></td>
 317      </tr>
 318      <tr>
 319          <td>
 320              <code>getAllBlogOptions(...)</code>(v2.2)
 321              <br /><code>getAllCategoryOptions(...)</code>(v2.2)
 322              <br /><code>getAllMemberOptions(...)</code>(v2.2)
 323        <br /><code>getAllItemOptions(...)</code>(v3.2)
 324          </td>
 325          <td><a href="#options" title="More info on options">For a given option, returns an associative of all values (one value per context)</a></td>
 326      </tr>
 327  
 328    <tr>
 329          <td>
 330              <code>getBlogOptionTop(...)</code>(v3.2)
 331              <br /><code>getMemberOptionTop(...)</code>(v3.2)
 332              <br /><code>getCategoryOptionTop(...)</code>(v3.2)
 333        <br /><code>getItemOptionTop(...)</code>(v3.2)
 334          </td>
 335          <td><a href="#options" title="More info on options">For a given option, returns the top of all values</a></td>
 336      </tr>
 337      <tr>
 338          <td><code>getID()</code></td>
 339          <td>Returns the ID for this plugin (this is the ID internally used inside Nucleus)</td>
 340      </tr>
 341      <tr>
 342          <td><code>getAdminURL()</code></td>
 343          <td>Returns the URL of where the admin area of the plugin is located (if there is no such admin area, this information is invalid)</td>
 344      </tr>
 345      <tr>
 346          <td><code>getDirectory()</code></td>
 347          <td>Returns the path in the servers filesystem where the extra files for the plugin are stored (if there are no such files, this information makes no sense). The result is something like "<code>.../nucleus/plugins/<i>plugname</i>/</code>"</td>
 348      </tr>
 349      <tr>
 350          <td><code>getShortName()</code></td>
 351          <td>Returns the part of the plugin classname without the "<code>NP_</code>"-part, and in all-lowercase. This information is used in the functions <code>getAdminURL</code> and <code>getDirectory</code></td>
 352      </tr>
 353  
 354  </table>
 355  
 356  <h1>Skinvars <a name="skinvars" href="#top" class="toplink"><img src="../icon-up.gif" width="15" height="15" alt="back to top" /></a></h1>
 357  
 358  <h2>Description</h2>
 359  
 360  <p>
 361  You can create your own skinvars, and call them using <code>&lt;%plugin(<i>PlugName</i>,<i>parameters</i>)%&gt; </code> or <code>&lt;%PlugName(parameters)%&gt;</code> (when this does not conflict with an existing skinvar). Parameters are comma-separated.
 362  </p>
 363  
 364  <p>
 365  To handle skinvars, you'll need to implement the <code>doSkinVar</code> method. Some samples of signatures are given below:
 366  </p>
 367  
 368  <pre class="example"><code>function doSkinVar($skinType)
 369  function doSkinVar($skinType, $param1, $param2)
 370  function doSkinVar($skinType, $skinVar, $param1, $param2)
 371  function doSkinVar($skinType, $skinVar, $param1 = 'default value')</code></pre>
 372  
 373  <ul>
 374      <li>The <code>$skinType</code> parameter will be one of 'index', 'item', 'archive', 'archivelist', 'member', 'error', 'search', 'imagepopup' or <a href="#templatevars" title="Information on templatevars">'template'</a></li>
 375      <li>The <code>$skinVar</code> is actually the first parameter that's being interpreted as a type of skinvar (e.g. <code>&lt;%plugin(PlugName,VarType)%&gt;</code>)</li>
 376      <li>You can use <code>doSkinVar()</code> (no parameters) and retrieve the parameters using the PHP function <code>func_get_args()</code>. Could be handy if you have different types of skinvars with different numbers of arguments</li>
 377  </ul>
 378  
 379  <h2>Notes</h2>
 380  
 381  <ul>
 382      <li>(v2.0b) You can find the name of the skin that's currently being parsed in the global variable <code>$currentSkinName</code></li>
 383  </ul>
 384  
 385  
 386  
 387  
 388  <h1>Template variables <a name="templatevars" href="#top" class="toplink"><img src="../icon-up.gif" width="15" height="15" alt="back to top" /></a></h1>
 389  
 390  <h2>Description</h2>
 391  
 392  <p>
 393  Template plugin variables work in the same way as skin plugin vars. There are two differences:</p>
 394  
 395  <ol>
 396      <li>They are called from within templates instead of from within skins</li>
 397      <li>They don't take a <code>$skinType</code> parameter. Instead, they take extra parameters with info on the item and comment that is currently being parsed:
 398          <ul>
 399              <li>The <code>doTemplateVar</code>-method gets a <code>&amp;$item</code> parameter.</li>
 400              <li>The <code>doTemplateCommentsVar</code>-method gets an <code>&amp;$item</code> parameter as well as a <code>&amp;$comment</code> parameter.</li>
 401          </ul>
 402          <strong>Note the ampersands!</strong>
 403      </li>
 404  </ol>
 405  
 406  <p>Template variables are called in exactly the same way as skinvars (using <code>&lt;%plugin(<i>PlugName</i>,<i>parameters</i>)%&gt; </code> or <code>&lt;%PlugName(parameters)%&gt;</code>)
 407  </p>
 408  
 409  <p>
 410  By default, all template variables are passed on to the <code>doSkinVar</code>-method, using '<code>template</code>' as <code>skinType</code>-parameter.
 411  </p>
 412  
 413  <p>
 414  If you want to provide your own implementation, you'll need to redefine the method <code>doTemplateVar</code> and/or <code>doTemplateCommentsVar</code>. It works in the same way as <code>doSkinVar</code>, except that now the <code>skinType</code>-parameter is missing.
 415  </p>
 416  
 417  <pre class="example"><code>function doTemplateVar(&amp;$item)
 418  function doTemplateVar(&amp;$item, $param1, $param2)
 419  function doTemplateVar(&amp;$item, $type, $param1, $param2)
 420  function doTemplateVar(&amp;$item, $type, $param1 = 'default value')
 421  function doTemplateCommentsVar(&amp;$item, &amp;$comment)
 422  function doTemplateCommentsVar(&amp;$item, &amp;$comment, $param1, $param2)
 423  function doTemplateCommentsVar(&amp;$item, &amp;$comment, $type, $param1, $param2)
 424  function doTemplateCommentsVar(&amp;$item, &amp;$comment, $type, $param1 = 'default value')</code></pre>
 425  
 426  <h2>Notes</h2>
 427  
 428  <ul>
 429      <li>(v2.0b) You can find the name of the template that's currently being used inside the global variable <code>$currentTemplateName</code></li>
 430  </ul>
 431  
 432  
 433  
 434  
 435  <h1>Actions <a name="actions" href="#top" class="toplink"><img src="../icon-up.gif" width="15" height="15" alt="back to top" /></a></h1>
 436  
 437  <p>Plugins can perform actions through <code>action.php</code>, the same script that's being used to receive comments and karma votes. You can call it using both GET and POST methods. Required parameters are <code>action</code> (should be 'plugin'), <code>name</code> (name of the plugin) and <code>type</code> (type of requested action)</p>
 438  
 439  <p>To enable these actions, you should implement the <code>doAction($actionType)</code> method in your plugin. Extra parameters from the request can be received using <code>requestVar('<i>name</i>')</code> (<code>requestVar</code> takes care of magic_quotes_gpc that PHP might have added)</p>
 440  
 441  <p>
 442  When your <code>doAction</code> method returns a string, it will be interpreted as an error, and an error message will be shown.
 443  </p>
 444  
 445  
 446  
 447  
 448  
 449  
 450  <h1>Events <a name="events" href="#top" class="toplink"><img src="../icon-up.gif" width="15" height="15" alt="back to top" /></a></h1>
 451  
 452  <p>
 453  Nucleus Plugins can subscribe to events that occur whenever something important happens. The plugin can then execute some actions, or output some text.
 454  </p>
 455  
 456  <h2>Example</h2>
 457  
 458  <p>
 459  Below is an example of how a plugin subscribes to the <code>PreAddComment</code>-event, an event that is generated immediately before a comment is added to a blog.
 460  </p>
 461  
 462  <pre class="example"><code>class NP_Acronyms extends NucleusPlugin {
 463    ...
 464    function getEventList() { return array('PreAddComment'); }
 465    ...
 466    function event_PreAddComment(&amp;$data) {
 467      // replace acronym HTML
 468      $data['comment']['body'] =
 469          strreplace('HTML',
 470                     '&lt;acronym title="HyperText Markup Language"&gt;HTML&lt;/acronym&gt;',
 471                     $data['comment']['body']);
 472    }
 473  }
 474  </code></pre>
 475  
 476  <p>This plugin replaces the text <code>HTML</code> in each comment by the text <code>&lt;acronym title="HyperText Markup Language"&gt;HTML&lt;/acronym&gt;</code>. The <code>acronym</code>-tag is a <acronym title="HyperText Markup Language">HTML</acronym>-tag that allows authors to provide extra information on acronyms.</p>
 477  
 478  <h2>Subscribing to events</h2>
 479  
 480  <p>Here's the steps you need to take to subscribe to an event:</p>
 481  
 482  <ol>
 483      <li>Add the event name to the array returned by the <code>getEventList</code>-method</li>
 484      <li>Create a method with signature <code>event_<em>EventName</em>($data)</code>, in which the handling of the event is done</li>
 485  </ol>
 486  
 487  <p>Multiple plugins can subscribe to the same event. The order in which these plugins are notified is the same order as the ordening in the plugin list of the admin area. Plugins higher in the list get notified earlier on.</p>
 488  
 489  <h2>Parameters</h2>
 490  
 491  <p>The <code>event_<em>EventName</em></code>-method gets only one parameter, <code>$data</code>, of which the contents differs depending on the event. It is an associative array with data. Objects and arrays that are passed in this array, are passed by <strong>reference</strong>, so the changes you make there will be remembered.</p>
 492  
 493  <p>The event list below uses some colors to indicate if changes in the parameters will be seen by nucleus or not:</p>
 494  
 495  <ul>
 496      <li><var class="ref">pass-by-reference</var>: when changes are made to this kind of parameters, they will be seen by Nucleus.</li>
 497      <li><var class="ro">pass-by-value</var>: a copy of the value is made before it is sent to the plugin event handler. Changes in the contents of these variables will be discarded automatically.</li>
 498  </ul>
 499  
 500  <p>Objects that are passed as parameters are indicates as follows: <var class="obj">object</var>. Most objects are also passed by reference, making them look like <var class="obj ref">object by ref</var></p>
 501  
 502  <h2>Event List</h2>
 503  
 504  <table summary="An overview of events to which a Nucleus Plugin can subscribe, and what parameters are passed along to the method that handles the event">
 505      <caption>Events on which a plugin can subscribe</caption>
 506      <tr>
 507          <th>Name</th><th>When</th><th>Parameters</th>
 508      </tr>
 509      <tr>
 510          <td>InitSkinParse</td>
 511          <td>Just before the skin is initialized</td>
 512          <td><dl>
 513              <dt class="obj ref">skin</dt>
 514              <dd>The <code>SKIN</code>-object that is handling the parse</dd>
 515              <dt class="ro">type</dt>
 516              <dd>Type of skinpart (one of 'index', 'item', 'archive', 'archivelist', 'member', 'error', 'search', 'imagepopup', 'fileparser')</dd>
 517          </dl></td>
 518      </tr>
 519      <tr>
 520          <td>PreSkinParse</td>
 521          <td>Immediately before the parsing of a skin begins</td>
 522          <td><dl>
 523              <dt class="obj ref">skin</dt>
 524              <dd>The <code>SKIN</code>-object that is handling the parse</dd>
 525              <dt class="ro">type</dt>
 526              <dd>Type of skinpart (one of 'index', 'item', 'archive', 'archivelist', 'member', 'error', 'search', 'imagepopup', 'fileparser')</dd>
 527              <dt class="ref">contents</dt>
 528              <dd>The content of the skin</dd>
 529          </dl></td>
 530      </tr>
 531      <tr>
 532          <td>PostSkinParse</td>
 533          <td>Immediately after parsing a skin</td>
 534          <td><dl>
 535              <dt class="obj ref">skin</dt>
 536              <dd>The <code>SKIN</code>-object that is handling the parse</dd>
 537              <dt class="ro">type</dt>
 538              <dd>Type of skinpart (one of 'index', 'item', 'archive', 'archivelist', 'member', 'error', 'search', 'imagepopup', 'fileparser')</dd>
 539          </dl></td>
 540      </tr>
 541      <tr>
 542          <td>PreItem</td>
 543          <td>Before an item is parsed, but after the item header has been placed</td>
 544          <td><dl>
 545              <dt class="ref obj">blog</dt>
 546              <dd><code>BLOG</code> object</dd>
 547              <dt class="ref obj">item</dt>
 548              <dd>object containing item data</dd>
 549          </dl></td>
 550      </tr>
 551      <tr>
 552          <td>PostItem</td>
 553          <td>After an item has been parsed, but before the item footer has been parsed</td>
 554          <td><dl>
 555              <dt class="ref obj">blog</dt>
 556              <dd><code>BLOG</code> object</dd>
 557              <dt class="ref obj">item</dt>
 558              <dd>object containing item data</dd>
 559          </dl></td>
 560      </tr>
 561      <tr>
 562          <td>PreComment</td>
 563          <td>Before a comment is shown</td>
 564          <td><dl>
 565              <dt class="ref">comment</dt>
 566              <dd>associative array containing comment data</dd>
 567          </dl></td>
 568      </tr>
 569      <tr>
 570          <td>PostComment</td>
 571          <td>After a comment has been shown</td>
 572          <td><dl>
 573              <dt class="ref">comment</dt>
 574              <dd>associative array containing comment data</dd>
 575          </dl></td>
 576      </tr>
 577      <tr>
 578          <td>PreDateHead</td>
 579          <td>Before a date header is shown</td>
 580          <td><dl>
 581              <dt class="obj ref">blog</dt>
 582              <dd><code>BLOG</code> object</dd>
 583              <dt class="ro">timestamp</dt>
 584              <dd>Timestamp for date header</dd>
 585          </dl></td>
 586      </tr>
 587      <tr>
 588          <td>PostDateHead</td>
 589          <td>After a date header has been parsed</td>
 590          <td><dl>
 591              <dt class="obj ref">blog</dt>
 592              <dd><code>BLOG</code> object</dd>
 593              <dt class="ro">timestamp</dt>
 594              <dd>Timestamp for date header</dd>
 595          </dl></td>
 596      </tr>
 597      <tr>
 598          <td>PreDateFoot</td>
 599          <td>Before a date footer is parsed</td>
 600          <td><dl>
 601              <dt class="ref obj">blog</dt>
 602              <dd><code>BLOG</code> object</dd>
 603              <dt class="ro">timestamp</dt>
 604              <dd>Timestamp for day that is closed</dd>
 605          </dl></td>
 606      </tr>
 607      <tr>
 608          <td>PostDateFoot</td>
 609          <td>After a date footer has been parsed</td>
 610          <td><dl>
 611              <dt class="ref obj">blog</dt>
 612              <dd><code>BLOG</code> object</dd>
 613              <dt class="ro">timestamp</dt>
 614              <dd>Timestamp for day that is closed</dd>
 615          </dl></td>
 616      </tr>
 617      <tr>
 618          <td>LoginSuccess</td>
 619          <td>After a successful login</td>
 620          <td><dl>
 621              <dt class="obj ref">member</dt>
 622              <dd><code>MEMBER</code> object</dd>
 623          </dl></td>
 624      </tr>
 625      <tr>
 626          <td>LoginFailed</td>
 627          <td>After a failed login</td>
 628          <td><dl>
 629              <dt class="ro">username</dt>
 630              <dd>login name that was used in the login attempt</dd>
 631          </dl></td>
 632      </tr>
 633      <tr>
 634          <td>Logout</td>
 635          <td>After logout</td>
 636          <td><dl>
 637              <dt class="ro">username</dt>
 638              <dd>name of the user that logged out</dd>
 639          </dl></td>
 640      </tr>
 641      <tr>
 642          <td>PreBlogContent</td>
 643          <td>Before blog content has been inserted through a skinvar</td>
 644          <td><dl>
 645              <dt class="obj ref">blog</dt>
 646              <dd><code>BLOG</code> object</dd>
 647              <dt class="ro">type</dt>
 648              <dd>Type of skinvar that's being called ('blog', 'otherblog', 'archive', 'archivelist', 'item', 'searchresults', 'othersearchresults', 'categorylist', 'otherarchive', 'otherarchivelist')</dd>
 649          </dl></td>
 650      </tr>
 651      <tr>
 652          <td>PostBlogContent</td>
 653          <td>After blog content has been inserted through a skinvar</td>
 654          <td><dl>
 655              <dt class="obj ref">blog</dt>
 656              <dd><code>BLOG</code> object</dd>
 657              <dt class="ro">type</dt>
 658              <dd>Type of skinvar that's being called ('blog', 'otherblog', 'archive', 'archivelist', 'item', 'searchresults', 'othersearchresults', 'categorylist', 'otherarchive', 'otherarchivelist')</dd>
 659          </dl></td>
 660      </tr>
 661      <tr>
 662          <td>PreAddComment</td>
 663          <td>Before adding a comment to the database</td>
 664          <td><dl>
 665              <dt class="ref">comment</dt>
 666              <dd>comment data (associative array)</dd>
 667              <dt class="ref">spamcheck</dt>
 668              <dd>the resulting datastructure of the previously called <code>SpamCheck</code> event (associative array)</dd>
 669          </dl></td>
 670      </tr>
 671      <tr>
 672          <td>PostAddComment</td>
 673          <td>After adding a comment to the database</td>
 674          <td><dl>
 675              <dt class="ref">comment</dt>
 676              <dd>comment data (associative array)</dd>
 677              <dt class="ref">commentid</dt>
 678              <dd>comment ID</dd>
 679              <dt class="ref">spamcheck</dt>
 680              <dd>the resulting datastructure of the previously called <code>SpamCheck</code> event (associative array)</dd>
 681          </dl></td>
 682      </tr>
 683      <tr>
 684          <td>PostRegister</td>
 685          <td>After a new user has registered</td>
 686          <td><dl>
 687              <dt class="obj ref">member</dt>
 688              <dd>New <code>MEMBER</code> object</dd>
 689          </dl></td>
 690      </tr>
 691      <tr>
 692          <td>PostAddItem</td>
 693          <td>After an item has been added to the database</td>
 694          <td><dl>
 695              <dt class="ro">itemid</dt>
 696              <dd>new itemid in database</dd>
 697          </dl></td>
 698      </tr>
 699      <tr>
 700          <td>PostUpdateItem</td>
 701          <td>Immediately after an item gets updates in the database</td>
 702          <td><dl>
 703              <dt class="ro">itemid</dt>
 704              <dd>item ID</dd>
 705          </dl></td>
 706      </tr>
 707      <tr>
 708          <td>PreAddItem</td>
 709          <td>Immediately before an item is added to the database</td>
 710          <td><dl>
 711              <dt class="ref">title</dt>
 712              <dd>title</dd>
 713              <dt class="ref">body</dt>
 714              <dd>body text</dd>
 715              <dt class="ref">more</dt>
 716              <dd>extended text</dd>
 717              <dt class="ref obj">blog</dt>
 718              <dd><code>BLOG</code> object</dd>
 719              <dt class="ref">authorid</dt>
 720              <dd>ID of author</dd>
 721              <dt class="ref">timestamp</dt>
 722              <dd>UNIX timestamp</dd>
 723              <dt class="ref">closed</dt>
 724              <dd>1 (no comments allowed) or 0 (comments allowed)</dd>
 725              <dt class="ref">draft</dt>
 726              <dd>1 (draft) or 0 (not draft)</dd>
 727              <dt class="ref">catid</dt>
 728              <dd>ID fo category</dd>
 729          </dl></td>
 730      </tr>
 731      <tr>
 732          <td>PreUpdateItem</td>
 733          <td>Immediately before an item gets updates in the database</td>
 734          <td><dl>
 735              <dt class="ro">itemid</dt>
 736              <dd>item ID</dd>
 737              <dt class="ref">title</dt>
 738              <dd>title</dd>
 739              <dt class="ref">body</dt>
 740              <dd>body text</dd>
 741              <dt class="ref">more</dt>
 742              <dd>extended text</dd>
 743              <dt class="ref obj">blog</dt>
 744              <dd><code>BLOG</code> object</dd>
 745              <dt class="ref">closed</dt>
 746              <dd>1 (no comments allowed) or 0 (comments allowed)</dd>
 747              <dt class="ref">catid</dt>
 748              <dd>ID fo category</dd>
 749          </dl></td>
 750      </tr>
 751      <tr>
 752          <td>PrepareItemForEdit</td>
 753          <td>Called after getting an item from the database, and before presenting it to the user to be edited.</td>
 754          <td><dl>
 755              <dt class="ref">item</dt>
 756              <dd>associative array containing item data</dd>
 757          </dl></td>
 758      </tr>
 759      <tr>
 760          <td>PreUpdateComment</td>
 761          <td>Immediately before a comment is updated and saved into the database</td>
 762          <td><dl>
 763              <dt class="ref">body</dt>
 764              <dd>Comment body</dd>
 765          </dl></td>
 766      </tr>
 767      <tr>
 768          <td>PrepareCommentForEdit</td>
 769          <td>After a comment is retrieved from the database, and before it is presented to the user to be edited.</td>
 770          <td><dl>
 771              <dt class="ref">comment</dt>
 772              <dd>comment data (associative array)</dd>
 773          </dl></td>
 774      </tr>
 775      <tr>
 776          <td>PrePluginOptionsEdit</td>
 777          <td>
 778              (v2.0b) before the 'edit plugin options' form is created.
 779              <br />(v2.2) extra parameters
 780        <br />(v3.2) extra parameter for every option
 781          </td>
 782          <td><dl>
 783              <dt class="ro">context</dt>
 784              <dd>(v2.2) <code>global</code>, <code>blog</code>, <code>member</code>, <code>item</code> or <code>category</code></dd>
 785              <dt class="ref">options</dt>
 786              <dd>Array with for each option an associative array, having the following indices: <code>name</code>, <code>value</code>, <code>oid</code>, <code>description</code>, <code>type</code>, <code>typeinfo</code>, <code>contextid</code>, <code>extra</code>. Extra options can be added here (if you want to do something with them, you'll need to subscribe to PostPluginOptionsUpdate as well)<br />
 787        Using the <code>extra</code>-field you can add extra html (by example formcontrols) to the option. If you do so, you should compare <code>pid</code> with <code>getID()</code> and also check <code>name</code> before adding things to <code>extra</code></dd>
 788              <dt class="ro">plugid</dt>
 789              <dd>plugin ID (compare with <code>GetID()</code> to find out if this concerns you) (only present when context is global)</dd>
 790              <dt class="ro">contextid</dt>
 791              <dd>context ID (blogid, memberid, catid, itemid depending on context)</dd>
 792  
 793          </dl></td>
 794      </tr>
 795    <tr>
 796          <td>PrePluginOptionsUpdate</td>
 797          <td>
 798              (v3.2) Before the options for a plugin have been updated. (using this event you can validate/change the new value for an option)
 799          </td>
 800          <td><dl>
 801        <dt class="ro">context</dt>
 802              <dd>(v2.2) <code>global</code>, <code>member</code>, <code>blog</code>, <code>item</code> or <code>category</code></dd>
 803              <dt class="ro">plugid</dt>
 804              <dd>plugin ID (compare with <code>GetID()</code> to find out if this concerns you)</dd>
 805        <dt class="ro">optionname</dt>
 806              <dd>Name of the option</dd>
 807              <dt class="ro">contextid</dt>
 808              <dd>context ID (blogid, memberid, catid, itemid depending on context)</dd>
 809              <dt class="ref">value</dt>
 810              <dd>New value for the option</dd>
 811          </dl></td>
 812  
 813      </tr>
 814  
 815      <tr>
 816          <td>PostPluginOptionsUpdate</td>
 817          <td>
 818              (v2.0b) After the options for a plugin have been updated.
 819              <br />(v2.2) Different parameters depending on context
 820          </td>
 821          <td><dl>
 822              <dt class="ro">context</dt>
 823              <dd>(v2.2) <code>global</code>, <code>member</code>, <code>blog</code>, <code>item</code> or <code>category</code></dd>
 824              <dt class="ro">plugid</dt>
 825              <dd>plugin ID (compare with <code>GetID()</code> to find out if this concerns you) (global context)</dd>
 826              <dt class="ro">blogid</dt>
 827              <dd>(v2.2) blog ID (blog context)</dd>
 828              <dt class="ref obj">blog</dt>
 829              <dd>(v2.2) BLOG object (blog context)</dd>
 830              <dt class="ro">memberid</dt>
 831              <dd>(v2.2) member ID (member context)</dd>
 832              <dt class="ref obj">member</dt>
 833              <dd>(v2.2) MEMBER object (member context)</dd>
 834              <dt class="ro">catid</dt>
 835              <dd>(v2.2) category ID (category context)</dd>
 836        <dt class="ro">itemid</dt>
 837              <dd>(v2.2) item ID (item context)</dd>
 838        <dt class="ref obj">member</dt>
 839              <dd>(v2.2) ITEM object (item context)</dd>
 840          </dl></td>
 841  
 842      </tr>
 843      <tr>
 844          <td>PostAuthentication</td>
 845          <td>(v2.0b) After the login procedure has been completed. This occurs on each page request.</td>
 846          <td><dl>
 847              <dt class="ro">loggedIn</dt>
 848              <dd>result of <code>$member->isLoggedIn()</code></dd>
 849          </dl></td>
 850      </tr>
 851      <tr>
 852          <td>PreAddItemForm</td>
 853          <td>(v2.0b) Immediately before an add item form (bookmarklet or admin area) is created.</td>
 854          <td><dl>
 855              <dt class="ref">contents</dt>
 856              <dd>reference to an associative array, in which the values 'title', 'body' and 'more' can be filled with initial values for the formfields. To avoid multiple plugins to alter these values, set the 'hasBeenSet' value to 1 when you're done (and check for it before starting)</dd>
 857              <dt class="ref obj">blog</dt>
 858              <dd>reference to a <code>BLOG</code> object</dd>
 859          </dl></td>
 860      </tr>
 861      <tr>
 862          <td>AddItemFormExtras</td>
 863          <td>(v2.0b) Somewhere inside the add item page or bookmarklet. Here, plugins can add their custom fields without having to alter one of the <code>.template</code> files.</td>
 864          <td><dl>
 865              <dt class="ref obj">blog</dt>
 866              <dd>reference to a <code>BLOG</code> object</dd>
 867          </dl></td>
 868      </tr>
 869      <tr>
 870          <td>EditItemFormExtras</td>
 871          <td>
 872              (v2.0b) Somewhere inside the edit item page or bookmarklet. Here, plugins can add their custom fields without having to alter one of the <code>.template</code> files.
 873              <br /><br />
 874              Don't add too much data, and please generate <strong>valid XHTML</strong>, looking like this:
 875  <pre class="example"><code>&lt;h3&gt;plugin name&lt;/h3&gt;
 876  &lt;p&gt;your stuff&lt;/p&gt;</code></pre>
 877              This way, multiple plugins can add options here while things keep a good structure. Also try to use prefixes for your fieldnames, in order to avoid nameclashes (e.g. <code>plug_tb_url</code>)
 878          </td>
 879          <td><dl>
 880              <dt class="ref obj">blog</dt>
 881              <dd>reference to a <code>BLOG</code> object</dd>
 882              <dt class="ro">variables</dt>
 883              <dd>
 884                  (read-only) An associative array containing all sorts of information on the item that's being edited: 'itemid', 'draft', 'closed', 'title', 'body', 'more', 'author', 'authorid', 'timestamp', 'karmapos', 'karmaneg', 'catid'
 885              </dd>
 886              <dt class="ro">itemid</dt>
 887              <dd>shortcut to the item ID</dd>
 888          </dl></td>
 889