b2evolution

Multilingual multiuser multiblog engine

b2evolution Technical Documentation (Version 2.4) [ class tree: plugins ] [ index: plugins ] [ all elements ]

Source for file _plugin.class.php

Documentation is available at _plugin.class.php

  1. <?php
  2. /**
  3.  * This file implements the abstract {@link Plugin} class.
  4.  *
  5.  * This file is part of the evoCore framework - {@link http://evocore.net/}
  6.  * See also {@link http://sourceforge.net/projects/evocms/}.
  7.  *
  8.  * @copyright (c)2003-2008 by Francois PLANQUE - {@link http://fplanque.net/}
  9.  *  Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
  10.  *
  11.  *  {@internal License choice
  12.  *  - If you have received this file as part of a package, please find the license.txt file in
  13.  *    the same folder or the closest folder above for complete license terms.
  14.  *  - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
  15.  *    then you must choose one of the following licenses before using the file:
  16.  *    - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
  17.  *    - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
  18.  *  }}}
  19.  *
  20.  *  {@internal Open Source relicensing agreement:
  21.  *  Daniel HAHLER grants Francois PLANQUE the right to license
  22.  *  Daniel HAHLER's contributions to this file and the b2evolution project
  23.  *  under any OSI approved OSS license (http://www.opensource.org/licenses/).
  24.  *  }}}
  25.  *
  26.  * @package plugins
  27.  *
  28.  * @todo Add links to pages on manual.b2evolution.net, once they are "clean"/tiny
  29.  *
  30.  *  {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  31.  * @author fplanque: Francois PLANQUE - {@link http://fplanque.net/}
  32.  * @author blueyed: Daniel HAHLER
  33.  *
  34.  * @version $Id: _plugin.class.php,v 1.6.2.1 2009/04/30 21:21:16 tblue246 Exp $
  35.  */
  36. if!defined('EVO_MAIN_INIT') ) die'Please, do not access this page directly.' );
  37.  
  38.  
  39. /**
  40.  * Plugin Class
  41.  *
  42.  * Real plugins should be derived from this class.
  43.  *
  44.  * @abstract
  45.  * @package plugins
  46.  */
  47. class Plugin
  48. {
  49.     /**#@+
  50.      * Variables below MUST be overriden by plugin implementations,
  51.      * either in the subclass declaration or in the subclass constructor.
  52.      */
  53.  
  54.     /**
  55.      * Default plugin name as it will appear in lists.
  56.      *
  57.      * To make it available for translations set it in the constructor by
  58.      * using the {@link Plugin::T_()} function.
  59.      *
  60.      * This should be no longer than 50 characters.
  61.      *
  62.      * @var string 
  63.      */
  64.     var $name = '';
  65.  
  66.     /**
  67.      * Globally unique code for this plugin functionality. 32 chars. MUST BE SET.
  68.      *
  69.      * A common code MIGHT be shared between different plugins providing the same functionnality.
  70.      * This allows to replace a given renderer with another one and keep the associations with posts.
  71.      * Example: replacing a GIF smiley renderer with an SWF smiley renderer...
  72.      *
  73.      * @var string 
  74.      */
  75.     var $code = '';
  76.  
  77.     /**
  78.      * Default priority.
  79.      *
  80.      * Priority determines in which order the plugins get called.
  81.      * Range: 1 to 100 (the lower the number, the earlier it gets called)
  82.      *
  83.      * @var int 
  84.      */
  85.     var $priority = 50;
  86.  
  87.     /**
  88.      * Plugin version number (max 42 chars, so obscure CVS Revision keywords get handled).
  89.      *
  90.      * This must be compatible to PHP's {@link version_compare()},
  91.      * e.g. '1', '2', '1.1', '2.1b' and '10-1-1a' are fine.
  92.      *
  93.      * This can be used by other plugins when requiring your plugin
  94.      * through {@link Plugin::GetDependencies()}.
  95.      *
  96.      * By increasing it you can request a call of {@link GetDbLayout()} upon instantiating.
  97.      * If there are DB layout changes to be made, the plugin gets changed to status "needs_config".
  98.      *
  99.      * @var string 
  100.      */
  101.     var $version = '0';
  102.  
  103.     /**
  104.      * Plugin author.
  105.      *
  106.      * This is for user info only.
  107.      *
  108.      * @var string 
  109.      */
  110.     var $author = 'Unknown author';
  111.  
  112.     /**
  113.      * URL for more info about the plugin, author and new versions.
  114.      *
  115.      * This is for user info only.
  116.      *
  117.      * If empty, it defaults to 'http://manual.b2evolution.net/[plugin_classname]',
  118.      * where '[plugin_classname]' is the plugin's PHP class name (with first char uppercased).
  119.      *
  120.      * @var string 
  121.      */
  122.     var $help_url = '';
  123.  
  124.     /**
  125.      * Plugin short description.
  126.      *
  127.      * This should be no longer than a line and is limited to 255 chars.
  128.      *
  129.      * @var string 
  130.      */
  131.     var $short_desc;
  132.  
  133.     /**#@-*/
  134.  
  135.  
  136.     /**#@+
  137.      * Variables below MAY be overriden.
  138.      */
  139.  
  140.     /**
  141.      * Plugin long description.
  142.      *
  143.      * This should be no longer than a line.
  144.      *
  145.      * @var string 
  146.      */
  147.     var $long_desc;
  148.  
  149.  
  150.     /**
  151.      * If this is a rendering plugin, when should rendering apply?
  152.      *
  153.      * This is the default value for the plugin and can be overriden in the Plugins
  154.      * administration for plugins that provide rendering events.
  155.      *
  156.      * {@internal The actual value for the plugin gets stored in T_plugins.plug_apply_rendering.}}
  157.      *
  158.      * Possible values:
  159.      * - 'stealth': gets always used, but not displayed as option
  160.      * - 'always': gets always used, and displayed as disabled checkbox
  161.      * - 'opt-out': enabled by default
  162.      * - 'opt-in': disabled by default
  163.      * - 'lazy': checkbox gets displayed, but is disabled
  164.      * - 'never': cannot get used as a renderer
  165.      *
  166.      * @todo blueyed>> IMHO we would need another value, which is the same as "lazy", but does not display a checkbox, which is useful for Plugins that add themselves as renderers on Item update
  167.      *
  168.      * @var string 
  169.      */
  170.     var $apply_rendering = 'never'// By default, this may not be a rendering plugin
  171.  
  172.  
  173.     /**
  174.      * Number of allowed installs.
  175.      *
  176.      * When installing the plugin it gets checked if the plugin is already installed this
  177.      * many times. If so, the installation gets aborted.
  178.      */
  179.     var $number_of_installs;
  180.  
  181.  
  182.     /**
  183.      * Main group of the plugin.
  184.      *
  185.      * @var string 
  186.      */
  187.     var $group;
  188.  
  189.  
  190.     /**
  191.      * Sub-Group of the plugin.
  192.      *
  193.      * @var string 
  194.      */
  195.     var $sub_group;
  196.  
  197.  
  198.     /**
  199.      * Name of the ping service (if this is a ping plugin, see {@link Plugin::ItemSendPing()})
  200.      * @var string 
  201.      */
  202.     var $ping_service_name;
  203.  
  204.     /**
  205.      * Note about the ping service, used in the list of ping services in the blog settings
  206.      * (if this is a ping plugin, see {@link Plugin::ItemSendPing()})
  207.      * @var string 
  208.      */
  209.     var $ping_service_note;
  210.  
  211.     /**#@-*/
  212.  
  213.  
  214.     /**#@+
  215.      * Variables below MUST NOT be overriden or changed by you!
  216.      * @access private
  217.      */
  218.  
  219.     /**
  220.      * Name of the current class. (AUTOMATIC)
  221.      *
  222.      * Will be set automatically (from filename) when registering plugin.
  223.      *
  224.      * @var string 
  225.      */
  226.     var $classname;
  227.  
  228.     /**
  229.      * Internal (DB) ID. (AUTOMATIC)
  230.      *
  231.      * ID < 1 means 'NOT installed'
  232.      *
  233.      * @var int 
  234.      */
  235.     var $ID 0;
  236.  
  237.  
  238.     /**
  239.      * If the plugin provides settings, this will become the object to access them.
  240.      *
  241.      * This gets instantianted on Plugin registration for PHP4 and through
  242.      * overloading in PHP5+, which means on first access.
  243.      *
  244.      * @see GetDefaultSettings()
  245.      * @var PluginSettings 
  246.      */
  247.     var $Settings;
  248.  
  249.  
  250.     /**
  251.      * If the plugin provides user settings, this will become the object to access them.
  252.      *
  253.      * This gets instantianted on Plugin registration for PHP4 and through
  254.      * overloading in PHP5+, which means on first access.
  255.      *
  256.      * NOTE: its methods use {@link $current_User::$ID} by default, but you may call it
  257.      *       if there's no {@link $current_User} instantiated (yet).
  258.      *
  259.      * @see GetDefaultUserSettings()
  260.      * @var PluginUserSettings 
  261.      */
  262.     var $UserSettings;
  263.  
  264.  
  265.     /**
  266.      * The status of the plugin.
  267.      *
  268.      * Use {@link set_status()} to change it, if you need to.
  269.      * Either 'enabled', 'disabled', 'needs_config' or 'broken'.
  270.      *
  271.      * @var string 
  272.      */
  273.     var $status;
  274.  
  275.     /**
  276.      * The "mother" object, where this Plugin got instantiated from.
  277.      *
  278.      * @deprecated since 2.0
  279.      * @var Plugins|Plugins_admin
  280.      */
  281.     var $Plugins;
  282.  
  283.     /**
  284.      * The translations keyed by locale. They get loaded through include() of _global.php.
  285.      * @see Plugin::T_()
  286.      * @var array 
  287.      */
  288.     var $_trans array();
  289.  
  290.     /**
  291.      * The translation charsets keyed by locale. They get loaded through include() of _global.php.
  292.      * @see Plugin::T_()
  293.      * @var array 
  294.      */
  295.     var $_trans_charsets array();
  296.  
  297.     /**
  298.      * Has the global /locales/_global.php file (where translation for
  299.      * all languages can be put into) been loaded?
  300.      *
  301.      * @var boolean 
  302.      */
  303.     var $_trans_loaded_global false;
  304.  
  305.     /**#@-*/
  306.  
  307.  
  308.     /**
  309.      * Constructor.
  310.      *
  311.      * You should not use a constructor with your plugin, but the
  312.      * {@link Plugin::PluginInit()} method instead!
  313.      */
  314.     function Plugin()
  315.     {
  316.     }
  317.  
  318.  
  319.     /**
  320.      * Init the Plugin after it has been registered/instantiated.
  321.      *
  322.      * Should set name and description in a localizable fashion.
  323.      *
  324.      * This gets called on every instantiated plugin, also if it's just for
  325.      * discovering the list of available plugins in the backoffice.
  326.      *
  327.      * Use this to validate Settings/requirements and/or cache them into class properties.
  328.      *
  329.      * @param array Associative array of parameters.
  330.      *               'is_installed': true, if the plugin is installed; false if not (probably it got discovered then)
  331.      *               'db_row': an array with the columns of the plugin DB entry (in T_plugins).
  332.      *                         This is empty, if the plugin is not installed!
  333.      *                         E.g., 'plug_version' might be interesting to compare again "$this->version".
  334.      * @return boolean If this method returns false, the Plugin gets unregistered (for the current request only).
  335.      */
  336.     function PluginInit$params )
  337.     {
  338.         // NOTE: the code below is just to handle stuff that has been deprecated since
  339.         //       b2evolution 1.9. You don't have to include this, if you override this method.
  340.  
  341.         ifis_null($this->short_desc) )
  342.         // may have been set in plugin's constructor (which is deprecated since 1.9)
  343.             $this->short_desc = T_('No desc available');
  344.         }
  345.         ifis_null($this->long_desc) )
  346.         // may have been set in plugin's constructor (which is deprecated since 1.9)
  347.             $this->long_desc = T_('No description available');
  348.         }
  349.  
  350.         ifmethod_exists$this'AppendPluginRegister' && $params['is_installed')
  351.         // Wrapper for deprecated AppendPluginRegister method (deprecated since 1.9)
  352.             $this->debug_log('Plugin has deprecated AppendPluginRegister method. Use PluginInit instead.'array('deprecated'));
  353.  
  354.             return $this->AppendPluginRegister($params);
  355.         }
  356.  
  357.         return true;
  358.     }
  359.  
  360.  
  361.     // Plugin information (settings, DB layout, ..): {{{
  362.  
  363.     /**
  364.      * Define default settings here.
  365.      * Those can then be edited in the backoffice.
  366.      *
  367.      * You can access them in the plugin through the member object
  368.      * {@link Plugin::$Settings}, e.g.:
  369.      * <code>$this->Settings->get( 'my_param' );</code>
  370.      *
  371.      * fp> this is unclear: You probably don't need to set or change values (other than the
  372.      * defaultvalues), but if you know what you're doing, see
  373.      * {@link PluginSettings}, where {@link Plugin::$Settings} gets derived from.
  374.      *
  375.      * NOTE: this method gets called by b2evo when instantiating the plugin
  376.      *       settings and when the settings get displayed for editing in the backoffice.
  377.      *       In the second case, $params['for_editing'] will be true.
  378.      *
  379.      * @todo 3.0 fp> 1) This is not an event: RENAME to lowercase (in b2evo 3.0)
  380.      *            dh> Not only events are CamelCase, but "interactions" with the Plugins(_admin) class, too!
  381.      *                Maybe it should get prefixed with "Plugin"?!
  382.      *                The intention is: all interfacing methods are camel-cased. That makes a lot of sense,
  383.      *                given the provided helpers (get_plugin_url etc).
  384.      *                This applies to the other todos below, too.
  385.      * @todo 3.0 fp> 2) This defines more than Default values ::  confusing name
  386.      * @todo name tentative get_general_param_definitions()
  387.      *
  388.      * @param array Associative array of parameters (since 1.9).
  389.      *     'for_editing': true, if the settings get queried for editing;
  390.      *                    false, if they get queried for instantiating {@link Plugin::$Settings}.
  391.      * @return array 
  392.      *  The array to be returned should define the names of the settings as keys (max length is 30 chars)
  393.      *  and assign an array with the following keys to them (only 'label' is required):
  394.      *
  395.      *    <ul><li>
  396.      *    'label': Name/Title of the param, gets displayed as label for the input field, or
  397.      *               as "legend" tag with types "array" and "fieldset".
  398.      *    </li><li>
  399.      *    'defaultvalue': Default value for the setting, defaults to '' (empty string)
  400.      *    </li><li>
  401.      *    'type', which can be:
  402.      *      <ul><li>
  403.      *      'text' (default): a simple string
  404.      *      </li><li>
  405.      *      'html_input' : like text, but allows html
  406.      *      </li><li>
  407.      *      'password': like text, but hidden during input
  408.      *      </li><li>
  409.      *      'checkbox': either 0 or 1
  410.      *      </li><li>
  411.      *      'integer': a number (no float, can have leading "+" or "-")
  412.      *                   (like 'text' for input, but gets validated when submitting)
  413.      *      </li><li>
  414.      *      'float': a floating number (can have leading "+" or "-", e.g. "+1", "-0.05")
  415.      *                   (like 'text' for input, but gets validated when submitting)
  416.      *      </li><li>
  417.      *      'textarea': several lines of input. The following can be set for this type:
  418.      *        <ul><li>
  419.      *        'rows': number of rows
  420.      *        </li><li>
  421.      *        'cols': number of columns
  422.      *        </li></ul>
  423.      *      </li><li>
  424.      *      'html_textarea': like textarea, but allows html
  425.      *      </li><li>
  426.      *      'select': a drop down field; you must set 'options' for it:
  427.      *        <ul><li>
  428.      *        'options': an array of options ('value' => 'description'), see {@link Form::select_input_array()}.
  429.      *        </li></ul>
  430.      *      </li><li>
  431.      *      'select_blog': a drop down field, providing all existing blogs (Blog ID is the value or "" if "allow_none" is true)
  432.      *                     (WARNING: does not scale - not recommended)
  433.      *      </li><li>
  434.      *      'select_group': a drop down field, providing all existing groups (Group ID is the value or "" if "allow_none" is true)
  435.      *      </li><li>
  436.      *      'select_user': a drop down field, providing all existing groups (User ID is the value or "" if "allow_none" is true)
  437.      *                     (WARNING: does not scale - not recommended)
  438.      *      </li><li>
  439.      *      'array': a subset of settings. The value gets automagically (un)serialized through get() and set().
  440.      *        The following keys apply to this type:
  441.      *        <ul><li>
  442.      *        'entries': an array with meta information about sub-settings
  443.      *            (which can be everything from the top-level, except: "valid_pattern", "valid_range").
  444.      *            Note: currently there's no type forcing or checking
  445.      *                  for sub-entries involved (e.g., if you have an entry of type "integer", you could get
  446.      *                  a non-numeric string there).
  447.      *  fp> TODO: !!!! very unsafe
  448.      *        </li><li>
  449.      *        'key': defines the key to use for each entry. This may be a text input for example
  450.      *               (with label, note etc). (optional, default is numeric keys, which are not editable)
  451.      *        </li><li>
  452.      *        'max_count': maximum count of sets (optional, default is no restriction)
  453.      *        </li><li>
  454.      *        'min_count': minimum count of sets (optional, default is no restriction)
  455.      *        </li></ul>
  456.      *      </li></ul>
  457.      *    </li><li>
  458.      *    'note' (gets displayed as a note to the param field),
  459.      *    </li><li>
  460.      *    'size': Size of the HTML input field (applies to types 'text', 'password' and 'integer'; defaults to 15)
  461.      *    </li><li>
  462.      *    'maxlength': maxlength attribute for the input field (See 'size' above; defaults to no limit)
  463.      *    </li><li>
  464.      *    'disabled': if true, it adds a 'disabled="disabled"' html attribute to the element and the value cannot be changed
  465.      *    </li><li>
  466.      *    'no_edit': if true, the setting is not editable. This is useful for internal settings.
  467.      *    </li><li>
  468.      *    'allow_none': set this to true to have "None" in the options list for types
  469.      *                    'select_group' and 'select_user'.
  470.      *    </li><li>
  471.      *    'valid_pattern': A regular expression pattern that the value must match.
  472.      *                       This is either just a regexp pattern as string or an array
  473.      *                       with the keys 'pattern' and 'error' to define a custom error message.
  474.      *    </li><li>
  475.      *    'valid_range': An array with keys 'min', 'max' and (optionally) 'error' to define
  476.      *                     a custom error message. At least "min" or "max" must be given.
  477.      *    </li><li>
  478.      *    'help': can be:
  479.      *           <ul><li>
  480.      *           '#anchor': anchor that gets appended to {@link $help_url}
  481.      *           </li><li>
  482.      *           true: the settings name/key gets transformed to an html ID and gets used as anchor to {@link $help_url}.
  483.      *           </li><li>
  484.      *           'http://example.com/uri': a full URL (starting with http:// or https://)
  485.      *           </li></ul>
  486.      *    </li><li>
  487.      *    'layout': Use this to visually group your settings.
  488.      *                Either 'begin_fieldset', 'end_fieldset' or 'separator'. You can use 'label' for 'begin_fieldset'.
  489.      *    </li><li>
  490.      *    'multiple': This allows to select multiple values in a SELECT (including select_*) (boolean)
  491.      *                (since EVO_NEXT_VERSION)
  492.      *    </li><li>
  493.      *    'id', 'onchange', 'onclick', 'onfocus', 'onkeyup', 'onkeydown', 'onreset', 'onselect', 'cols', 'rows', 'maxlength':
  494.      *        get passed through as attributes to the form/input element.
  495.      *    </li></ul>
  496.      *
  497.      *
  498.      *  e.g.:
  499.      *  <code>
  500.      *  return array(
  501.      *    'my_param' => array(
  502.      *      'label' => $this->T_('My Param'),
  503.      *      'defaultvalue' => '10',
  504.      *      'note' => $this->T_('Quite cool, eh?'),
  505.      *      'valid_pattern' => array( 'pattern' => '[1-9]\d+', $this->T_('The value must be >= 10.') ),
  506.      *    ),
  507.      *    'another_param' => array( // this one has no 'note'
  508.      *      'label' => $this->T_('My checkbox'),
  509.      *      'defaultvalue' => '1',
  510.      *      'type' => 'checkbox',
  511.      *    ),
  512.      *    array( 'layout' => 'separator' ),
  513.      *    'my_select' => array(
  514.      *      'label' => $this->T_('Selector'),
  515.      *      'defaultvalue' => 'one',
  516.      *      'type' => 'select',
  517.      *      'options' => array( 'sun' => $this->T_('Sunday'), 'mon' => $this->T_('Monday') ),
  518.      *    ) );
  519.      *  </code>
  520.      *
  521.      */
  522.     function GetDefaultSettings$params )
  523.     {
  524.         return array();
  525.     }
  526.  
  527.  
  528.     /**
  529.      * Define here default user settings that are then available in the backoffice.
  530.      *
  531.      * You can access them in the plugin through the member object
  532.      * {@link $UserSettings}, e.g.:
  533.      * <code>$this->UserSettings->get( 'my_param' );</code>
  534.      *
  535.      * This method behaves exactly like {@link Plugin::GetDefaultSettings()},
  536.      * except that it defines user specific settings instead of global settings.
  537.      *
  538.      * @todo 3.0 fp> 1) This is not an event: RENAME to lowercase (in b2evo 3.0)
  539.      * @todo 3.0 fp> 2) This defines more than Default values ::  confusing name
  540.      * @todo name tentative get_user_param_definitions()
  541.      *
  542.      * @see Plugin::GetDefaultSettings()
  543.      * @param array Associative array of parameters.
  544.      *     'for_editing': true, if the settings get queried for editing;
  545.      *                    false, if they get queried for instantiating {@link Plugin::$UserSettings}.
  546.      * @return array See {@link Plugin::GetDefaultSettings()}.
  547.      */
  548.     function GetDefaultUserSettings$params )
  549.     {
  550.         return array();
  551.     }
  552.  
  553.  
  554.   /**
  555.    * Get definitions for widget specific editable params
  556.    *
  557.      * @see Plugin::GetDefaultSettings()
  558.      * @param local params like 'for_editing' => true
  559.      */
  560.     function get_widget_param_definitions$params )
  561.     {
  562.         return array();
  563.     }
  564.  
  565.  
  566.     /**
  567.      * Get the list of dependencies that the plugin has.
  568.      *
  569.      * This gets checked on install or uninstall of a plugin.
  570.      *
  571.      * There are two <b>classes</b> of dependencies:
  572.      *  - 'recommends': This is just a recommendation. If it cannot get fulfilled
  573.      *                  there will just be a note added on install.
  574.      *  - 'requires': A plugin cannot be installed if the dependencies cannot get
  575.      *                fulfilled. Also, a plugin cannot get uninstalled, if another
  576.      *                plugin depends on it.
  577.      *
  578.      * Each <b>class</b> of dependency can have the following types:
  579.      *  - 'events_by_one': A list of eventlists that have to be provided by a single plugin,
  580.      *                     e.g., <code>array( array('CaptchaPayload', 'CaptchaValidated') )</code>
  581.      *                     to look for a plugin that provides both events.
  582.      *  - 'plugins':
  583.      *    A list of plugins, either just the plugin's classname or an array with
  584.      *    classname and minimum version of the plugin (see {@link Plugin::$version}).
  585.      *    E.g.: <code>array( 'test_plugin', '1' )</code> to require at least version "1"
  586.      *          of the test plugin.
  587.      *  - 'app_min': Minimum application (b2evo) version, e.g. "1.9".
  588.      *               This way you can make sure that the hooks you need are implemented
  589.      *               in the core.
  590.      *               (Available since b2evo 1.8.3. To make it work before 1.8.2 use
  591.      *               "api_min" and check for array(1, 2) (API version of 1.9)).
  592.      *  - 'api_min': You can require a specific minimum version of the Plugins API here.
  593.      *               If it's just a number, only the major version is checked against.
  594.      *               To check also for the minor version, you have to give an array:
  595.      *               array( major, minor ).
  596.      *               Obsolete since 1.9! Used API versions: 1.1 (b2evo 1.8.1) and 1.2 (b2evo 1.9).
  597.      *
  598.      * @see test_plugin::GetDependencies()
  599.      * @return array 
  600.      */
  601.     function GetDependencies()
  602.     {
  603.         return array()// no dependencies by default, of course
  604.     }
  605.  
  606.  
  607.     /**
  608.      * This method should return your DB schema, consisting of a list of CREATE TABLE
  609.      * queries.
  610.      *
  611.      * The DB gets changed accordingly on installing or enabling your Plugin.
  612.      *
  613.      * If you want to change your DB layout in a new version of your Plugin, simply
  614.      * adjust the queries here and increase {@link Plugin::$version}, because this will
  615.      * request to check the current DB layout against the one you require.
  616.      *
  617.      * For restrictions see {@link db_delta()}.
  618.      */
  619.     function GetDbLayout()
  620.     {
  621.         return array();
  622.     }
  623.  
  624.  
  625.     /**
  626.      * This method gets asked when plugins get installed and allows you to return a list
  627.      * of extra events, which your plugin triggers itself (e.g. through
  628.      * {@link $Plugins->trigger_event()}).
  629.      *
  630.      * NOTE: PLEASE use a distinct prefix for the event name, e.g. "$this->classname".
  631.      *
  632.      * NOTE: The length of event names is limited to 40 chars.
  633.      *
  634.      * NOTE: Please comment the params and the return value here with the list
  635.      *       that you return. Only informal as comment, but makes it easier for
  636.      *       others.
  637.      *
  638.      * @see test_plugin::GetExtraEvents()
  639.      * @return NULL|array"event_name" => "description"
  640.      */
  641.     function GetExtraEvents()
  642.     {
  643.     }
  644.  
  645.  
  646.     /**
  647.      * Override this method to define methods/functions that you want to make accessible
  648.      * through /htsrv/call_plugin.php, which allows you to call those methods by HTTP request.
  649.      *
  650.      * This is useful for things like AJAX or displaying an <iframe> element, where the content
  651.      * should get provided by the plugin itself.
  652.      *
  653.      * E.g., the image captcha plugin uses this method to serve a generated image.
  654.      *
  655.      * NOTE: the Plugin's method must be prefixed with "htsrv_", but in this list (and the URL) it
  656.      *       is not. E.g., to have a method "disp_image" that should be callable through this method
  657.      *       return <code>array('disp_image')</code> here and implement it as
  658.      *       <code>function htsrv_disp_image( $params )</code> in your plugin.
  659.      *       This is used to distinguish those methods from others, but keep URLs nice.
  660.      *
  661.      * @see get_htsrv_url()
  662.      * @return array 
  663.      */
  664.     function GetHtsrvMethods()
  665.     {
  666.         return array();
  667.     }
  668.  
  669.  
  670.     /**
  671.      * This method gets asked for a list of cronjobs that the plugin
  672.      * provides.
  673.      * If a user installs a cron job out of this list, the
  674.      * {@link Plugin::ExecCronJob()} of the plugin gets called.
  675.      *
  676.      * @return array Array of arrays with keys "name", "ctrl" and "params".
  677.      *                "name" gets used for display. "ctrl" (string) and
  678.      *                "params" (array) get passed to the
  679.      *                {@link Plugin::ExecCronJob()} method when the cronjob
  680.      *                gets executed.
  681.      */
  682.     function GetCronJobs$params )
  683.     {
  684.         return array();
  685.     }
  686.  
  687.  
  688.     /**
  689.      * Execute/handle a cron job, which has been scheduled by the admin out
  690.      * of the list that the Plugin provides (see {@link GetCronJobs()}).
  691.      *
  692.      * @param array Associative array of parameters
  693.      *    - 'ctrl': The "ctrl" name as defined in {@link GetCronJobs()}
  694.      *    - 'params': The "params" value as defined in {@link GetCronJobs()},
  695.      *                plus "ctsk_ID" which holds the cron task ID.
  696.      * @return array with keys "code" (integer, 1 is ok), "message" (gets logged)
  697.      */
  698.     function ExecCronJob$params )
  699.     {
  700.     }
  701.  
  702.     // }}}
  703.  
  704.  
  705.     /*
  706.      * Event handlers. These are meant to be implemented by your plugin. {{{
  707.      */
  708.  
  709.     // Admin/backoffice events (without events specific to Items or Comments): {{{
  710.  
  711.     /**
  712.      * Event handler: Gets invoked in /admin.php for every backoffice page after
  713.      *                the menu structure is build. You could use the {@link $AdminUI} object
  714.      *                to modify it.
  715.      *
  716.      * This is the hook to register menu entries. See {@link register_menu_entry()}.
  717.      */
  718.     function AdminAfterMenuInit()
  719.     {
  720.         // Example:
  721.         $this->register_menu_entry$this->T_('My Tab') );
  722.     }
  723.  
  724.  
  725.     /**
  726.      * Event handler: Called when ending the admin html head section.
  727.      *
  728.      * @param array Associative array of parameters
  729.      * @return boolean did we do something?
  730.      */
  731.     function AdminEndHtmlHead$params )
  732.     {
  733.         return false;        // Do nothing by default.
  734.     }
  735.  
  736.  
  737.     /**
  738.      * Event handler: Called right after displaying the admin page footer.
  739.      *
  740.      * @param array Associative array of parameters
  741.      * @return boolean did we do something?
  742.      */
  743.     function AdminAfterPageFooter$params )
  744.     {
  745.         return false;        // Do nothing by default.
  746.     }
  747.  
  748.  
  749.     /**
  750.      * Event handler: Called when displaying editor buttons.
  751.      *
  752.      * This method, if implemented, should output the buttons
  753.      * (probably as html INPUT elements) and return true, if
  754.      * button(s) have been displayed.
  755.      *
  756.      * You should provide an unique html ID with your button.
  757.      *
  758.      * @param array Associative array of parameters.
  759.      *    - 'target_type': either 'Comment' or 'Item'.
  760.      *    - 'edit_layout': "simple", "expert", etc. (users, hackers, plugins, etc. may create their own layouts in addition to these)
  761.      *                     NOTE: Please respect the "simple" mode, which should display only the most simple things!
  762.      * @return boolean did we display a button?
  763.      */
  764.     function AdminDisplayEditorButton$params )
  765.     {
  766.         if$params['edit_layout'== 'simple' )
  767.         // Do nothing in simple mode
  768.             return false;
  769.         }
  770.  
  771.         return false;        // Do nothing by default.
  772.     }
  773.  
  774.  
  775.     /**
  776.      * Event handler: Called when displaying editor toolbars.
  777.      *
  778.      * @param array Associative array of parameters
  779.      *    - 'target_type': either 'Comment' or 'Item'.
  780.      *    - 'edit_layout': "simple", "expert", etc. (users, hackers, plugins, etc. may create their own layouts in addition to these)
  781.      *                     NOTE: Please respect the "simple" mode, which should display only the most simple things!
  782.      * @return boolean did we display a toolbar?
  783.      */
  784.     function AdminDisplayToolbar$params )
  785.     {
  786.         return false;        // Do nothing by default.
  787.     }
  788.  
  789.  
  790.     /**
  791.      * Event handler: Called when handling actions for the "Tools" menu.
  792.      *
  793.      * Use {@link msg()} to add messages for the user.
  794.      */
  795.     function AdminToolAction()
  796.     {
  797.     }
  798.  
  799.  
  800.     /**
  801.      * Event handler: Called when displaying the block in the "Tools" menu.
  802.      *
  803.      * @return boolean did we display something?
  804.      */
  805.     function AdminToolPayload()
  806.     {
  807.         return false;        // Do nothing by default.
  808.     }
  809.  
  810.  
  811.     /**
  812.      * Event handler: Method that gets invoked when our tab is selected.
  813.      *
  814.      * You should catch (your own) params (using {@link param()}) here and do actions
  815.      * (but no output!).
  816.      *
  817.      * Use {@link msg()} to add messages for the user.
  818.      */
  819.     function AdminTabAction()
  820.     {
  821.     }
  822.  
  823.  
  824.     /**
  825.      * Event handler: Gets invoked when our tab is selected and should get displayed.
  826.      *
  827.      * Do your output here.
  828.      *
  829.      * @return boolean did we display something?
  830.      */
  831.     function AdminTabPayload()
  832.     {
  833.         return false;        // Do nothing by default.
  834.     }
  835.  
  836.  
  837.     /**
  838.      * Event handler: Gets invoked before the main payload in the backoffice.
  839.      */
  840.     function AdminBeginPayload()
  841.     {
  842.     }
  843.  
  844.     // }}}
  845.  
  846.  
  847.     // Skin/Blog events: {{{
  848.  
  849.     /**
  850.      * Event handler: Called before a blog gets displayed (in _blog_main.inc.php).
  851.      */
  852.     function BeforeBlogDisplay$params )
  853.     {
  854.     }
  855.  
  856.  
  857.     /**
  858.      * Event handler: Called at the beginning of the skin's HTML HEAD section.
  859.      *
  860.      * Use this to add any HTML HEAD lines (like CSS styles or links to resource
  861.      * files (CSS, JavaScript, ..)).
  862.      */
  863.     function SkinBeginHtmlHead$params )
  864.     {
  865.     }
  866.  
  867.  
  868.     /**
  869.      * Event handler: Called at the end of the skin's HTML BODY section.
  870.      *
  871.      * Use this to add any HTML snippet at the end of the generated page.
  872.      */
  873.     function SkinEndHtmlBody$params )
  874.     {
  875.     }
  876.  
  877.  
  878.     /**
  879.      * Event handler: Gets asked about a list of skin names that the plugin handles.
  880.      *
  881.      * If one of the skins returned gets called through the "skin=X" URL param, the
  882.      * {@link Plugin::DisplaySkin()} method of your plugin gets called.
  883.      *
  884.      * @return array 
  885.      */
  886.     function GetProvidedSkins()
  887.     {
  888.         return array();
  889.     }
  890.  
  891.  
  892.     /**
  893.      * Event handler: Display a skin. Use {@link Plugin::GetProvidedSkins()} to return
  894.      * a list of names that you register.
  895.      *
  896.      * @param array Associative array of parameters
  897.      *    - 'skin': name of skin to be displayed (from the list of {@link Plugin::GetProvidedSkins()}).
  898.      *              If your Plugin only registers one skin, you can ignore it.
  899.      */
  900.     function DisplaySkin$params )
  901.     {
  902.     }
  903.  
  904.     // }}}
  905.  
  906.  
  907.     // (Un)Install / (De)Activate events: {{{
  908.  
  909.     /**
  910.      * Event handler: Called before the plugin is going to be installed.
  911.      *
  912.      * This is the hook to create any DB tables or the like.
  913.      *
  914.      * If you just want to add a note, use {@link Plugin::msg()} (and return true).
  915.      *
  916.      * @return true|stringTrue, if the plugin can be enabled/activated,
  917.      *                      a string with an error/note otherwise.
  918.      */
  919.     function BeforeInstall()
  920.     {
  921.         return true;  // default is to allow Installation
  922.     }
  923.  
  924.  
  925.     /**
  926.      * Event handler: Called after the plugin has been installed.
  927.      */
  928.     function AfterInstall()
  929.     {
  930.     }
  931.  
  932.  
  933.     /**
  934.      * Event handler: Called before the plugin is going to be un-installed.
  935.      *
  936.      * This is the hook to remove any files or the like - tables with canonical names
  937.      * (see {@link Plugin::get_sql_table()}, are handled internally.
  938.      *
  939.      * See {@link BeforeUninstallPayload()} for the corresponding payload handler, which you
  940.      * can request to invoke by returning NULL here.
  941.      *
  942.      * Note: this method gets called again, if the uninstallation has to be confirmed,
  943.      *       either because you've requested a call to {@link BeforeUninstallPayload()}
  944.      *       or there are tables to be dropped (what the admin user has to confirm).
  945.      *
  946.      * @param array Associative array of parameters.
  947.      *               'unattended': true if Uninstall is unattended (e.g., the /install action "deletedb" uses it).
  948.      *                             This should cleanup everything without confirmation!
  949.      * @return boolean|NULL
  950.      *          true when it's ok to uninstall,
  951.      *          false on failure (the plugin won't get uninstalled then).
  952.      *                You should add the reason for it through {@link Plugin::msg()}.
  953.      *          NULL requests to execute the {@link BeforeUninstallPayload()} method.
  954.      */
  955.     function BeforeUninstall$params )
  956.     {
  957.         return true;
  958.     }
  959.  
  960.  
  961.     /**
  962.      * Event handler: Gets invoked to display the payload before uninstalling the plugin.
  963.      *
  964.      * You have to request a call to this during the plugin uninstall procedure by
  965.      * returning NULL in {@link BeforeUninstall()}.
  966.      *
  967.      * @param array Associative array of parameters.
  968.      *               'Form': The {@link Form} that asks the user for confirmation (by reference).
  969.      *                       If your plugin uses canonical table names (see {@link Plugin::get_sql_table()}),
  970.      *                       there will be already a list of those tables included in it.
  971.      *                       Do not end the form, just add own inputs or hidden keys to it.
  972.      */
  973.     function BeforeUninstallPayload$params )
  974.     {
  975.     }
  976.  
  977.  
  978.     /**
  979.      * Event handler: Called when the admin tries to enable the plugin, changes
  980.      * its configuration/settings and after installation.
  981.      *
  982.      * Use this, if your plugin needs configuration before it can be used.
  983.      *
  984.      * @todo dh> Call this from Plugins::set_Plugin_status()?
  985.      * @return true|stringTrue, if the plugin can be enabled/activated,
  986.      *                      a string with an error/note otherwise.
  987.      */
  988.     function BeforeEnable()
  989.     {
  990.         return true;  // default is to allow Activation
  991.     }
  992.  
  993.  
  994.     /**
  995.      * Event handler: Your plugin gets notified here, just before it gets
  996.      * disabled.
  997.      *
  998.      * You cannot prevent this, but only clean up stuff, if you have to.
  999.      *
  1000.      * @todo dh> Only call this from Plugins::set_Plugin_status(), if it has not been disabled before?! ("status change")
  1001.      */
  1002.     function BeforeDisable()
  1003.     {
  1004.     }
  1005.  
  1006.  
  1007.     /*
  1008.      * NOTE: function AppendPluginRegister( & $params ) is deprecated since 1.9.
  1009.      * Use Plugin::PluginInit() instead.
  1010.      */
  1011.  
  1012.  
  1013.     /**
  1014.      * Event handler: Called when we detect a version change (in {@link Plugins::register()}).
  1015.      *
  1016.      * Use this for your upgrade needs.
  1017.      *
  1018.      * @param array Associative array of parameters.
  1019.      *               'old_version': The old version of your plugin as stored in DB.
  1020.      *               'db_row': an array with the columns of the plugin DB entry (in T_plugins).
  1021.      *                         The key 'plug_version' is the same as the 'old_version' key.
  1022.      * @return boolean If this method returns false, the Plugin's status gets changed to "needs_config" and
  1023.      *                  it gets unregistered for the current request.
  1024.      */
  1025.     function PluginVersionChanged$params )
  1026.     {
  1027.         return true;
  1028.     }
  1029.  
  1030.     // }}}
  1031.  
  1032.  
  1033.     // Item events: {{{
  1034.  
  1035.     /**
  1036.      * Event handler: Called when rendering item/post contents as HTML. (CACHED)
  1037.      *
  1038.      * The rendered content will be *cached* and the cached content will be reused on subsequent displays.
  1039.      * Use {@link DisplayItemAsHtml()} instead if you want to do rendering at display time.
  1040.      *
  1041.       * Note: You have to change $params['data'] (which gets passed by reference).
  1042.      *
  1043.      * @param array Associative array of parameters
  1044.      *    - 'data': the data (by reference). You probably want to modify this.
  1045.      *    - 'format': see {@link format_to_output()}. Only 'htmlbody' and 'entityencoded' will arrive here.
  1046.      *    - 'Item': the {@link Item} object which gets rendered.
  1047.      * @return boolean Have we changed something?
  1048.      */
  1049.     function RenderItemAsHtml$params )
  1050.     {
  1051.         /*
  1052.         $content = & $params['data'];
  1053.         $content = 'PREFIX__'.$content.'__SUFFIX'; // just an example
  1054.         return true;
  1055.         */
  1056.     }
  1057.  
  1058.  
  1059.     /**
  1060.      * Event handler: Called when rendering item/post contents as XML.
  1061.      *
  1062.      * Should this plugin apply to XML?
  1063.      * It should actually only apply when:
  1064.      * - it generates some content that is visible without HTML tags
  1065.      * - it removes some dirty markup when generating the tags (which will get stripped afterwards)
  1066.      * Note: htmlentityencoded is not considered as XML here.
  1067.      *
  1068.      * Note: You have to change $params['data'] (which gets passed by reference).
  1069.      *
  1070.      * @param array Associative array of parameters
  1071.      *    - 'data': the data (by reference). You probably want to modify this.
  1072.      *    - 'format': see {@link format_to_output()}. Only 'xml' will arrive here.
  1073.      *    - 'Item': the {@link Item} object which gets rendered.
  1074.      * @return boolean Have we changed something?
  1075.      */
  1076.     function RenderItemAsXml$params )
  1077.     {
  1078.         return false;        // Do nothing by default.
  1079.     }
  1080.  
  1081.  
  1082.     /**
  1083.      * Event handler: Called when rendering item/post contents other than XML or HTML.
  1084.      *
  1085.      * Note: return value is ignored. You have to change $params['data'].
  1086.      *
  1087.      * @param array Associative array of parameters
  1088.      *    - 'data': the data (by reference). You probably want to modify this.
  1089.      *    - 'format': see {@link format_to_output()}. Only 'text' will arrive here.
  1090.      *    - 'Item': the {@link Item} object which gets rendered.
  1091.      * @return boolean Have we changed something?
  1092.      */
  1093.     function RenderItemAsText()
  1094.     {
  1095.         return false;        // Do nothing by default.
  1096.     }
  1097.  
  1098.  
  1099.     /**
  1100.      * Event handler: Called when displaying an item/post's content as HTML.
  1101.      *
  1102.      * This is different from {@link RenderItemAsHtml()}, because it gets called
  1103.      * on every display (while rendering gets cached).
  1104.      *
  1105.      * @param array Associative array of parameters
  1106.      *    - 'data': the data (by reference). You probably want to modify this.
  1107.      *    - 'format': see {@link format_to_output()}.
  1108.      *    - 'Item': The {@link Item} that gets displayed (by reference).
  1109.      *    - 'preview': Is this only a preview?
  1110.      *    - 'dispmore': Does this include the "more" text (if available), which means "full post"?
  1111.      * @return boolean Have we changed something?
  1112.      */
  1113.     function DisplayItemAsHtml$params )
  1114.     {
  1115.         return false;        // Do nothing by default.
  1116.     }
  1117.  
  1118.  
  1119.     /**
  1120.      * Event handler: Called when displaying an item/post's content as XML.
  1121.      *
  1122.      * This is different from {@link RenderItemAsXml()}, because it gets called
  1123.      * on every display (while rendering gets cached).
  1124.      *
  1125.      * @param array Associative array of parameters
  1126.      *    - 'data': the data (by reference). You probably want to modify this.
  1127.      *    - 'format': see {@link format_to_output()}.
  1128.      *    - 'Item': The {@link Item} that gets displayed (by reference).
  1129.      *    - 'preview': Is this only a preview?
  1130.      *    - 'dispmore': Does this include the "more" text (if available), which means "full post"?
  1131.      * @return boolean Have we changed something?
  1132.      */
  1133.     function DisplayItemAsXml$params )
  1134.     {
  1135.         return false;        // Do nothing by default.
  1136.     }
  1137.  
  1138.  
  1139.     /**
  1140.      * Event handler: Called when displaying an item/post's content as text.
  1141.      *
  1142.      * This is different from {@link RenderItemAsText()}, because it gets called
  1143.      * on every display (while rendering gets cached).
  1144.      *
  1145.      * @param array Associative array of parameters
  1146.      *    - 'data': the data (by reference). You probably want to modify this.
  1147.      *    - 'format': see {@link format_to_output()}. Only 'text' will arrive here.
  1148.      *    - 'Item': The {@link Item} that gets displayed (by reference).
  1149.      *    - 'preview': Is this only a preview?
  1150.      *    - 'dispmore': Does this include the "more" text (if available), which means "full post"?
  1151.      * @return boolean Have we changed something?
  1152.      */
  1153.     function DisplayItemAsText$params )
  1154.     {
  1155.         return false;        // Do nothing by default.
  1156.     }
  1157.  
  1158.  
  1159.     /**
  1160.      * Event handler: called at the beginning of {@link Item::dbupdate() updating}
  1161.      * an item/post in the database}.
  1162.      *
  1163.      * Use this to manipulate the {@link Item}, e.g. adding a renderer code
  1164.      * through {@link Item::add_renderer()}.
  1165.      *
  1166.      * @param array Associative array of parameters
  1167.      *    - 'Item': the related Item (by reference)
  1168.      */
  1169.     function PrependItemUpdateTransact$params )
  1170.     {
  1171.     }
  1172.  
  1173.  
  1174.     /**
  1175.      * Event handler: called at the end of {@link Item::dbupdate() updating}
  1176.      * an item/post in the database}, which means that it has been changed.
  1177.      *
  1178.      * @param array Associative array of parameters
  1179.      *    - 'Item': the related Item (by reference)
  1180.      *    - 'dbchanges': array with DB changes; a copy of {@link Item::dbchanges()},
  1181.      *                   before they got applied (since 1.9)
  1182.      */
  1183.     function AfterItemUpdate$params )
  1184.     {
  1185.     }
  1186.  
  1187.  
  1188.     /**
  1189.      * Event handler: called at the beginning of {@link Item::dbinsert() inserting}
  1190.      * an item/post in the database}.
  1191.      *
  1192.      * Use this to manipulate the {@link Item}, e.g. adding a renderer code
  1193.      * through {@link Item::add_renderer()}.
  1194.      *
  1195.      * @param array Associative array of parameters
  1196.      *    - 'Item': the related Item (by reference)
  1197.      */
  1198.     function PrependItemInsertTransact$params )
  1199.     {
  1200.     }
  1201.  
  1202.  
  1203.     /**
  1204.      * Event handler: called at the end of {@link Item::dbinsert() inserting}
  1205.      * a item/post into the database}, which means it has been created.
  1206.      *
  1207.      * @param array Associative array of parameters
  1208.      *    - 'Item': the related Item (by reference)
  1209.      *    - 'dbchanges': array with DB changes; a copy of {@link Item::dbchanges()},
  1210.      *                   before they got applied (since 1.9)
  1211.      */
  1212.     function AfterItemInsert$params )
  1213.     {
  1214.     }
  1215.  
  1216.  
  1217.     /**
  1218.      * Event handler: called at the end of {@link Item::dbdelete() deleting}
  1219.      * an item/post from the database}.
  1220.      *
  1221.      * @param array Associative array of parameters
  1222.      *    - 'Item': the related Item (by reference)
  1223.      */
  1224.     function AfterItemDelete$params )
  1225.     {
  1226.     }
  1227.  
  1228.  
  1229.     /**
  1230.      * Event handler: called when instantiating an Item for preview.
  1231.      *
  1232.      * @param array Associative array of parameters
  1233.      *    - 'Item': the related Item (by reference)
  1234.      */
  1235.     function AppendItemPreviewTransact$params )
  1236.     {
  1237.     }
  1238.  
  1239.  
  1240.     /**
  1241.      * Event handler: Called when the view counter of an item got increased.
  1242.      *
  1243.      * @param array Associative array of parameters
  1244.      *    - 'Item': the Item object (by reference)
  1245.      */
  1246.     function ItemViewsIncreased$params )
  1247.     {
  1248.     }
  1249.  
  1250.  
  1251.     /**
  1252.      * Event handler: Called at the end of the "Edit item" form.
  1253.      *
  1254.      * @param array Associative array of parameters
  1255.      *    - 'Form': the {@link Form} object (by reference)
  1256.      *    - 'Item': the Item which gets edited (by reference)
  1257.      *    - 'edit_layout': "simple", "expert", etc. (users, hackers, plugins, etc. may create their own layouts in addition to these)
  1258.      *                     NOTE: Please respect the "simple" mode, which should display only the most simple things!
  1259.      * @return boolean did we display something?
  1260.      */
  1261.     function AdminDisplayItemFormFieldset$params )
  1262.     {
  1263.         return false;        // Do nothing by default.
  1264.     }
  1265.  
  1266.  
  1267.     /**
  1268.      * Event handler: Called before an item gets deleted (in the backoffice).
  1269.      *
  1270.      * You could {@link Plugin::msg() add a message} of
  1271.      * category "error" here, to prevent the comment from being deleted.
  1272.      *
  1273.      * @since 2.0
  1274.      * @param array Associative array of parameters
  1275.      *               'Item': the Item which gets created (by reference)
  1276.      */
  1277.     function AdminBeforeItemEditDelete$params )
  1278.     {
  1279.     }
  1280.  
  1281.  
  1282.     /**
  1283.      * Event handler: Called before a new item gets created (in the backoffice).
  1284.      *
  1285.      * You could {@link Plugin::msg() add a message} of
  1286.      * category "error" here, to prevent the comment from being inserted.
  1287.      *
  1288.      * @param array Associative array of parameters
  1289.      *               'Item': the Item which gets created (by reference)
  1290.      */
  1291.     function AdminBeforeItemEditCreate$params )
  1292.     {
  1293.     }
  1294.  
  1295.  
  1296.     /**
  1297.      * Event handler: Called before an existing item gets updated (in the backoffice).
  1298.      *
  1299.      * You could {@link Plugin::msg() add a message} of
  1300.      * category "error" here, to prevent the comment from being inserted.
  1301.      *
  1302.      * @param array Associative array of parameters
  1303.      *               'Item': the Item which gets updated (by reference)
  1304.      */
  1305.     function AdminBeforeItemEditUpdate$params )
  1306.     {
  1307.     }
  1308.  
  1309.  
  1310.     /**
  1311.      * Event handler: the plugin gets asked if an item can receive feedback/comments.
  1312.      *
  1313.      * @param array Associative array of parameters
  1314.      *               'Item': the Item
  1315.      * @return boolean|string
  1316.      *    true, if the Item can receive feedback
  1317.      *    false/string, if the Item cannot receive feedback. If you return a string
  1318.      *                  this gets displayed as an error/explanation.
  1319.      *    NULL, if you do not want to say "yes" or "no".
  1320.      */
  1321.     function ItemCanComment$params )
  1322.     {
  1323.     }
  1324.  
  1325.  
  1326.     /**
  1327.      * Event handler: send a ping about a new item.
  1328.      *
  1329.      * @param array Associative array of parameters
  1330.      *         'Item': the Item (by reference)
  1331.      *         'xmlrpcresp': Set this to the {@link xmlrpcresp} object, if the plugin
  1332.      *                       uses XMLRPC.
  1333.      *         'display': Should results get displayed? (normally you should not need
  1334.      *                    to care about this, especially if you can set 'xmlrpcresp')
  1335.      * @return boolean Was the ping successful?
  1336.      */
  1337.     function ItemSendPing$params )
  1338.     {
  1339.     }
  1340.  
  1341.  
  1342.     /**
  1343.      * Event handler: called to display the URL that accepts trackbacks for
  1344.      *                an item.
  1345.      *
  1346.      * @param array Associative array of parameters
  1347.      *    - 'Item': the {@link Item} object (by reference)
  1348.      *    - 'template': the template to display the URL (%url%)
  1349.      */
  1350.     function DisplayTrackbackAddr$params )
  1351.     {
  1352.     }
  1353.  
  1354.  
  1355.     /**
  1356.      * Event handler: Does your Plugin want to apply as a renderer for the item?
  1357.      *
  1358.      * NOTE: this is especially useful for lazy Plugins, which would look
  1359.      *       at the content and decide, if they apply.
  1360.      *
  1361.      * @return boolean|NULLIf true, the Plugin gets added as a renderer, false
  1362.      *          removes it as a renderer (if existing) and NULL does not change the
  1363.      *          renderer setting regarding your Plugin.
  1364.      */
  1365.     function ItemApplyAsRenderer$params )
  1366.     {
  1367.     }
  1368.  
  1369.     // }}}
  1370.  
  1371.  
  1372.     // Feedback (Comment/Trackback) events: {{{
  1373.  
  1374.     /**
  1375.      * Event handler: Called when displaying editor toolbars.
  1376.      *
  1377.      * @param array Associative array of parameters
  1378.      * @return boolean did we display a toolbar?
  1379.      */
  1380.     function DisplayCommentToolbar$params )
  1381.     {
  1382.         return false;        // Do nothing by default.
  1383.     }
  1384.  
  1385.  
  1386.     /**
  1387.      * Event handler: Called at the end of the "Edit comment" form.
  1388.      *
  1389.      * @param array Associative array of parameters
  1390.      *    - 'Form': the {@link Form} object (by reference)
  1391.      *    - 'Comment': the Comment which gets edited (by reference)
  1392.      *    - 'edit_layout': only NULL currently, as there's only one layout
  1393.      * @return boolean did we display something?
  1394.      */
  1395.     function AdminDisplayCommentFormFieldset$params )
  1396.     {
  1397.         return false;        // Do nothing by default.
  1398.     }
  1399.  
  1400.  
  1401.     /**
  1402.      * Event handler: Called at the end of the frontend comment form.
  1403.      *
  1404.      * You might want to use this to inject antispam payload to use in
  1405.      * in {@link GetSpamKarmaForComment()} or modify the Comment according
  1406.      * to it in {@link BeforeCommentFormInsert()}.
  1407.      *
  1408.      * @see Plugin::BeforeCommentFormInsert(), Plugin::AfterCommentFormInsert()
  1409.      * @param array Associative array of parameters
  1410.      *    - 'Form': the comment form generating object
  1411.      *    - 'Item': the Item for which the comment is meant
  1412.      */
  1413.     function DisplayCommentFormFieldset$params )
  1414.     {
  1415.     }
  1416.  
  1417.  
  1418.     /**
  1419.      * Event handler: Called in the submit button section of the
  1420.      * frontend comment form.
  1421.      *
  1422.      * @param array Associative array of parameters
  1423.      *    - 'Form': the comment form generating object
  1424.      *    - 'Item': the Item for which the comment is meant
  1425.      */
  1426.     function DisplayCommentFormButton$params )
  1427.     {
  1428.     }
  1429.  
  1430.  
  1431.     /**
  1432.      * Event handler: Called before at the beginning, if a comment form gets sent (and received).
  1433.      *
  1434.      * Use this to filter input, e.g. the OpenID uses this to provide alternate authentication.
  1435.      *
  1436.      * @since 1.10.0
  1437.      * @see Plugin::DisplayCommentFormFieldset()
  1438.      * @param array Associative array of parameters
  1439.      *    - 'comment_post_ID': ID of the item the comment is for
  1440.      *    - 'comment': the comment text (by reference)
  1441.      *    - 'original_comment': the original, unfiltered comment text - you should not modify it here,
  1442.      *       this is meant e.g. for the OpenID plugin to re-inject it after redirection (by reference)
  1443.      *    - 'comment_autobr': is the Auto-BR checkbox checked (by reference)
  1444.      *    - 'action': "save" or "preview" (by reference)
  1445.      *    - 'User': {@link User}, if logged in or null (by reference)
  1446.      *    - 'anon_name': Name of the anonymous commenter (by reference)
  1447.      *    - 'anon_email': E-Mail of the anonymous commenter (by reference)
  1448.      *    - 'anon_url': URL of the anonymous commenter (by reference)
  1449.      *    - 'anon_allow_msgform': "Allow msgform" preference of the anonymous commenter (by reference)
  1450.      *    - 'anon_cookies': "Remember me" preference of the anonymous commenter (by reference)
  1451.      *    - 'redirect_to': URL where to redirect to in the end of comment posting (by reference)
  1452.      */
  1453.     function CommentFormSent$params )
  1454.     {
  1455.     }
  1456.  
  1457.  
  1458.     /**
  1459.      * Event handler: Called before a comment gets inserted through the public comment
  1460.      *                form.
  1461.      *
  1462.      * Use this, to validate a comment: you could {@link Plugin::msg() add a message} of
  1463.      * category "error" here, to prevent the comment from being inserted.
  1464.      *
  1465.      * @see Plugin::DisplayCommentFormFieldset()
  1466.      * @param array Associative array of parameters
  1467.      *    - 'Comment': the Comment (by reference)
  1468.      *    - 'original_comment': this is the unstripped and unformated posted comment
  1469.      *    - 'action': "save" or "preview" (by reference) (since 1.10)
  1470.      *    - 'is_preview': is this a request for previewing the comment? (boolean)
  1471.      */
  1472.     function BeforeCommentFormInsert$params )
  1473.     {
  1474.     }
  1475.  
  1476.  
  1477.     /**
  1478.      * Event handler: Called when a comment form has been processed and the comment
  1479.      *                got inserted into DB.
  1480.      *
  1481.      * @param array Associative array of parameters
  1482.      *    - 'Comment': the Comment (by reference)
  1483.      *    - 'original_comment': this is the unstripped and unformated posted comment
  1484.      */
  1485.     function AfterCommentFormInsert$params )
  1486.     {
  1487.     }
  1488.  
  1489.  
  1490.     /**
  1491.      * Event handler: Called to ask the plugin for the spam karma of a comment/trackback.
  1492.      *
  1493.      * This gets called just before the comment gets stored.
  1494.      *
  1495.      * @param array Associative array of parameters
  1496.      *    - 'Comment': the {@link Comment} object (by reference)
  1497.      *    - The following values are interesting if you want to provide skipping of a test:
  1498.      *      - 'cur_karma': current karma value (cur_karma_abs/cur_karma_divider or NULL)
  1499.      *      - 'cur_karma_abs': current karma absolute value or NULL (if no Plugin returned karma before)
  1500.      *      - 'cur_karma_divider': current divider (sum of weights)
  1501.      *      - 'cur_count_plugins': number of Plugins that have already been asked
  1502.      * @return integer|NULLSpam probability (-100 - 100).
  1503.      *                 -100 means "absolutely no spam", 100 means "absolutely spam".
  1504.      *                 Only if you return a numeric value, it gets considered (e.g., "", NULL or false get ignored).
  1505.      */
  1506.     function GetSpamKarmaForComment$params )
  1507.     {
  1508.         return;
  1509.     }
  1510.  
  1511.  
  1512.     /**
  1513.      * Event handler: called at the end of {@link Comment::dbupdate() updating}
  1514.      * a comment in the database}, which means that it has changed.
  1515.      *
  1516.      * @param array Associative array of parameters
  1517.      *    - 'Comment': the related Comment (by reference)
  1518.      *    - 'dbchanges': array with DB changes; a copy of {@link Comment::dbchanges()},
  1519.      *                   before they got applied (since 1.9)
  1520.      */
  1521.     function AfterCommentUpdate$params )
  1522.     {
  1523.     }
  1524.  
  1525.  
  1526.     /**
  1527.      * Event handler: called at the end of {@link Comment::dbinsert() inserting}
  1528.      * a comment into the database}, which means it has been created.
  1529.      *
  1530.      * @param array Associative array of parameters
  1531.      *    - 'Comment': the related Comment (by reference)
  1532.      *    - 'dbchanges': array with DB changes; a copy of {@link Comment::dbchanges()},
  1533.      *                   before they got applied (since 1.9)
  1534.      */
  1535.     function AfterCommentInsert$params )
  1536.     {
  1537.     }
  1538.  
  1539.  
  1540.     /**
  1541.      * Event handler: called at the end of {@link Comment::dbdelete() deleting}
  1542.      * a comment from the database}.
  1543.      *
  1544.      * @param array Associative array of parameters
  1545.      *    - 'Comment': the related Comment (by reference)
  1546.      */
  1547.     function AfterCommentDelete$params )
  1548.     {
  1549.     }
  1550.  
  1551.  
  1552.     /**
  1553.      * Event handler: called before a trackback gets recorded.
  1554.      *
  1555.      * Use this, to validate a trackback: you could {@link Plugin::msg() add a message} of
  1556.      * category "error" here, to prevent the trackback from being accepted.
  1557.      *
  1558.      * @param array Associative array of parameters
  1559.      *    - 'Comment': the trackback (which is a {@link Comment} object with "trackback" type) (by reference)
  1560.      *         The trackback-params get mapped like this:
  1561.      *         - "blog_name" => "author"
  1562.      *         - "url" => "author_url"
  1563.      *         - "title"/"excerpt" => "comment"
  1564.      *
  1565.      */
  1566.     function BeforeTrackbackInsert$params )
  1567.     {
  1568.     }
  1569.  
  1570.  
  1571.     /**
  1572.      * Event handler: called to filter the comment's author name (blog name for trackbacks)
  1573.      *
  1574.      * @param array Associative array of parameters
  1575.      *    - 'data': the name of the author/blog (by reference)
  1576.      *    - 'makelink': true, if the "data" contains a link
  1577.      *    - 'Comment': the {@link Comment} object
  1578.      */
  1579.     function FilterCommentAuthor$params )
  1580.     {
  1581.     }
  1582.  
  1583.  
  1584.     /**
  1585.      * Event handler: called to filter the comment's author URL.
  1586.      * This may be either the URL only or a full link (A tag).
  1587.      *
  1588.      * @param array Associative array of parameters
  1589.      *    - 'data': the URL of the author/blog (by reference)
  1590.      *    - 'makelink': true, if the "data" contains a link (HTML A tag)
  1591.      *    - 'Comment': the {@link Comment} object
  1592.      */
  1593.     function FilterCommentAuthorUrl$params )
  1594.     {
  1595.     }
  1596.  
  1597.  
  1598.     /**
  1599.      * Event handler: called to filter the comment's content
  1600.      *
  1601.      * @param array Associative array of parameters
  1602.      *    - 'data': the name of the author/blog (by reference)
  1603.      *    - 'Comment': the {@link Comment} object
  1604.      */
  1605.     function FilterCommentContent$params )
  1606.     {
  1607.     }
  1608.  
  1609.     // }}}
  1610.  
  1611.  
  1612.     // Message form events: {{{
  1613.  
  1614.     /**
  1615.      * Event handler: Called at the end of the frontend message form, which
  1616.      * allows to send an email to a user/commentator.
  1617.      *
  1618.      * You might want to use this to inject antispam payload to use in
  1619.      * in {@link MessageFormSent()}.
  1620.      *
  1621.      * @param array Associative array of parameters
  1622.      *    - 'Form': the comment form generating object
  1623.      *    - 'recipient_ID': ID of the user (if any)
  1624.      *    - 'item_ID': ID of the item where the user clicked the msgform icon (if any)
  1625.      *    - 'comment_ID': ID of the comment where the user clicked the msgform icon (if any)
  1626.      */
  1627.     function DisplayMessageFormFieldset$params )
  1628.     {
  1629.     }
  1630.  
  1631.  
  1632.     /**
  1633.      * Event handler: Called in the submit button section of the
  1634.      * frontend message form.
  1635.      *
  1636.      * @param array Associative array of parameters
  1637.      *    - 'Form': the comment form generating object
  1638.      *    - 'recipient_ID': ID of the user (if any)
  1639.      *    - 'item_ID': ID of the item where the user clicked the msgform icon (if any)
  1640.      *    - 'comment_ID': ID of the comment where the user clicked the msgform icon (if any)
  1641.      */
  1642.     function DisplayMessageFormButton$params )
  1643.     {
  1644.     }
  1645.  
  1646.  
  1647.     /**
  1648.      * Event handler: Called when a message form has been submitted.
  1649.      *
  1650.      * Add messages of category "error" to prevent the message from being sent.
  1651.      *
  1652.      * You can also alter the "message" or "message_footer" that gets sent here.
  1653.      *
  1654.      * @param array Associative array of parameters
  1655.      *    - 'recipient_ID': ID of the user (if any)
  1656.      *    - 'item_ID': ID of the item where the user clicked the msgform icon (if any)
  1657.      *    - 'comment_ID': ID of the comment where the user clicked the msgform icon (if any)
  1658.      *    - 'sender_name': The name of the sender (by reference) (since 1.10.0)
  1659.      *    - 'sender_email': The email address of the sender (by reference) (since 1.10.0)
  1660.      *    - 'subject': The subject of the message to be sent (by reference) (since 1.10.0)
  1661.      *    - 'message': The message to be sent (by reference)
  1662.      *    - 'message_footer': The footer of the message (by reference)
  1663.      *    - 'Blog': The blog, depending on the context (may be null) (by reference) (since 1.10.0)
  1664.      */
  1665.     function MessageFormSent$params )
  1666.     {
  1667.     }
  1668.  
  1669.  
  1670.     /**
  1671.      * Event handler: Called after a message has been sent through the public email form.
  1672.      *
  1673.      * This is meant to cleanup generated data.
  1674.      */
  1675.     function MessageFormSentCleanup()
  1676.     {
  1677.     }
  1678.  
  1679.     // }}}
  1680.  
  1681.  
  1682.     // Caching events: {{{
  1683.  
  1684.     /**
  1685.      * Event handler: called to cache object data.
  1686.      *
  1687.      * @param array Associative array of parameters
  1688.      *    - 'action': 'delete', 'set', 'get'
  1689.      *    - 'key': The key to refer to 'data'
  1690.      *    - 'data': The actual data. This must be set by the plugin.
  1691.      * @return boolean True if action was successful, false otherwise.
  1692.      */
  1693.     function CacheObjects$params )
  1694.     {
  1695.     }
  1696.  
  1697.  
  1698.     /**
  1699.      * Event handler: called to cache page content (get cached content or request caching).
  1700.      *
  1701.      * This method must build a unique key for the requested page (including cookie/session info) and
  1702.      * start an output buffer, to get the content to cache.
  1703.      *
  1704.      * Note, that there are special occassions when this event does not get called, because we want
  1705.      * really fresh content always:
  1706.      *  - we're generating static pages
  1707.      *  - there gets a "dynamic object", such as "Messages" or "core.preview_Comment" transported in the session
  1708.      *
  1709.      * @see Plugin::CacheIsCollectingContent()
  1710.      * @param array Associative array of parameters
  1711.      *    - 'data': this must get set to the page content on cache hit
  1712.      * @return boolean True if we handled the request (either returned caching data or started buffering),
  1713.      *                  false if we do not want to cache this page.
  1714.      */
  1715.     function CachePageContent$params )
  1716.     {
  1717.     }
  1718.  
  1719.  
  1720.     /**
  1721.      * Event handler: gets asked for if we are generating cached content.
  1722.      *
  1723.      * This is useful to not generate a list of online users or the like.
  1724.      *
  1725.      * @see Plugin::CachePageContent()
  1726.      * @return boolean 
  1727.      */
  1728.     function CacheIsCollectingContent()
  1729.     {
  1730.     }
  1731.  
  1732.     // }}}
  1733.  
  1734.  
  1735.     // PluginSettings {{{
  1736.     /**
  1737.      * Event handler: Called before displaying or setting a plugin's setting in the backoffice.
  1738.      *
  1739.      * @see GetDefaultSettings()
  1740.      * @param array Associative array of parameters
  1741.      *    - 'name': name of the setting
  1742.      *    - 'value': value of the setting (by reference)
  1743.      *    - 'meta': meta data of the setting (as given in {@link GetDefaultSettings()})
  1744.      *    - 'action': 'display' or 'set' (since b2evo EVO_NEXT_VERSION)
  1745.      * @return string|NULLReturn a string with an error to prevent the setting from being set
  1746.      *                      and/or a message added to the settings field.
  1747.      */
  1748.     function PluginSettingsValidateSet$params )
  1749.     {
  1750.     }
  1751.  
  1752.  
  1753.     /**
  1754.      * Event handler: Called as action just before updating the {@link Plugin::$Settings plugin's settings}.
  1755.      *
  1756.      * The "regular" settings from {@link GetDefaultSettings()} have been set into
  1757.      * {@link Plugin::$Settings}, but get saved into DB after this method has been called.
  1758.      *
  1759.      * Use this to catch custom input fields from {@link PluginSettingsEditDisplayAfter()} or
  1760.      * add notes/errors through {@link Plugin::msg()}.
  1761.      *
  1762.      * If you want to modify plugin events (see {@link Plugin::enable_event()} and
  1763.      * {@link Plugin::disable_event()}), you should use {@link Plugin::BeforeEnable()}, because Plugin
  1764.      * events get saved (according to the edit settings screen) after this event.
  1765.      *
  1766.      * @return false|NULLReturn false to prevent the settings from being updated to DB.
  1767.      */
  1768.     function PluginSettingsUpdateAction()
  1769.     {
  1770.     }
  1771.  
  1772.  
  1773.     /**
  1774.      * Event handler: Called as action before displaying the "Edit plugin" form,
  1775.      * which includes the display of the {@link Plugin::$Settings plugin's settings}.
  1776.      *
  1777.      * You may want to use this to check existing settings or display notes about
  1778.      * something.
  1779.      */
  1780.     function PluginSettingsEditAction()
  1781.     {
  1782.     }
  1783.  
  1784.  
  1785.     /**
  1786.      * Event handler: Called after the form to edit the {@link Plugin::$Settings} has been
  1787.      * displayed.
  1788.      *
  1789.      * Use this to add custom input fields (and catch them in {@link PluginSettingsUpdateAction()})
  1790.      * or display custom output (e.g. a test link).
  1791.      *
  1792.      * @param array Associative array of parameters
  1793.      *    - 'Form': the {@link Form}, where an fieldset has been opened already (by reference)
  1794.      */
  1795.     function PluginSettingsEditDisplayAfter$params )
  1796.     {
  1797.     }
  1798.  
  1799.     // }}}
  1800.  
  1801.  
  1802.     // PluginUserSettings {{{
  1803.     /**
  1804.      * Event handler: Called before displaying or setting a plugin's user setting in the backoffice.
  1805.      *
  1806.      * @see GetDefaultUserSettings()
  1807.      * @param array Associative array of parameters
  1808.      *    - 'name': name of the setting
  1809.      *    - 'value': value of the setting (by reference)
  1810.      *    - 'meta': meta data of the setting (as given in {@link GetDefaultUserSettings()})
  1811.      *    - 'User': the {@link User} for which the setting is
  1812.      *    - 'action': 'display' or 'set' (since b2evo EVO_NEXT_VERSION)
  1813.      * @return string|NULLReturn a string with an error to prevent the setting from being set
  1814.      *                      and/or a message added to the settings field.
  1815.      */
  1816.     function PluginUserSettingsValidateSet$params )
  1817.     {
  1818.     }
  1819.  
  1820.  
  1821.     /**
  1822.      * Event handler: Called as action just before updating the {@link Plugin::$UserSettings plugin's user settings}.
  1823.      *
  1824.      * The "regular" settings from {@link GetDefaultUserSettings()} have been set into
  1825.      * {@link Plugin::$UserSettings}, but get saved into DB after this method has been called.
  1826.      *
  1827.      * Use this to catch custom input fields from {@link PluginUserSettingsEditDisplayAfter()} or
  1828.      * add notes/errors through {@link Plugin::msg()}.
  1829.      *
  1830.      * @param array Associative array of parameters
  1831.      *    - 'User': the {@link User} for which the settings get updated
  1832.      *    - 'action': "save", "reset" (since b2evo EVO_NEXT_VERSION - before there was only "save")
  1833.      *
  1834.      * @return false|NULLReturn false to prevent the settings from being updated to DB.
  1835.      */
  1836.     function PluginUserSettingsUpdateAction$params )
  1837.     {
  1838.     }
  1839.  
  1840.  
  1841.     /**
  1842.      * Event handler: Called as action before displaying the "Edit user" form,
  1843.      * which includes the display of the {@link Plugin::$UserSettings plugin's user settings}.
  1844.      *
  1845.      * You may want to use this to check existing settings or display notes about
  1846.      * something.
  1847.      *
  1848.      * @param array Associative array of parameters
  1849.      *    - 'User': the {@link User} for which the settings are being displayed/edited
  1850.      */
  1851.     function PluginUserSettingsEditAction$params )
  1852.     {
  1853.     }
  1854.  
  1855.  
  1856.     /**
  1857.      * Event handler: Called after the form to edit the {@link Plugin::$UserSettings} has been
  1858.      * displayed.
  1859.      *
  1860.      * Use this to add custom input fields (and catch them in {@link PluginUserSettingsUpdateAction()})
  1861.      * or display custom output (e.g. a test link).
  1862.      *
  1863.      * @param array Associative array of parameters
  1864.      *    - 'Form': the {@link Form}, where an fieldset has been opened already (by reference)
  1865.      *    - 'User': the {@link User} whose settings get displayed for editing (since 1.10.0)
  1866.      */
  1867.     function PluginUserSettingsEditDisplayAfter$params )
  1868.     {
  1869.     }
  1870.  
  1871.     // }}}
  1872.  
  1873.  
  1874.     // User related events, including registration and login (procedure): {{{
  1875.  
  1876.     /**
  1877.      * Event handler: Called at the end of the login procedure, if the
  1878.      *                user is anonymous ({@link $current_User current User} NOT set).
  1879.      *
  1880.      * Use this for example to read some cookie and define further handling of
  1881.      * this visitor or force them to login, by {@link Plugin::msg() adding a message}
  1882.      * of class "login_error", which will trigger the login screen.
  1883.      */
  1884.     function AfterLoginAnonymousUser$params )
  1885.     {
  1886.     }
  1887.  
  1888.  
  1889.     /**
  1890.      * Event handler: Called at the end of the login procedure, if the
  1891.      *                {@link $current_User current User} is set and the
  1892.      *                user is therefor registered.
  1893.      *
  1894.      * Use this for example to re-act on specific {@link Plugin::$UserSettings user settings},
  1895.      * e.g., call {@link Plugin::forget_events()} to de-activate the plugin for
  1896.      * the current request.
  1897.      *
  1898.      * You can also {@link Plugin::msg() add a message} of class "login_error"
  1899.      * to prevent the user from accessing the site and triggering
  1900.      * the login screen.
  1901.      */
  1902.     function AfterLoginRegisteredUser$params )
  1903.     {
  1904.     }
  1905.  
  1906.  
  1907.     /**
  1908.      * Event handler: Called when a new user has registered, at the end of the
  1909.      *                DB transaction that created this user.
  1910.      *
  1911.      * If you want to modify the about-to-be-created user (if the transaction gets
  1912.      * committed), you'll have to call {@link User::dbupdate()} on it, because he
  1913.      * got already inserted (but the transaction is not yet committed).
  1914.      *
  1915.      * Note: if you want to re-act on a new user,
  1916.      * use {@link Plugin::AfterUserRegistration()} instead!
  1917.      *
  1918.      * @param array Associative array of parameters
  1919.      *    - 'User': the {@link User user object} (as reference).
  1920.      * @return boolean false if the whole transaction should get rolled back (the user does not get created).
  1921.      */
  1922.     function AppendUserRegistrTransact$params )
  1923.     {
  1924.         return true;
  1925.     }
  1926.  
  1927.  
  1928.     /**
  1929.      * Event handler: Called when a new user has registered and got created.
  1930.      *
  1931.      * Note: if you want to modify a new user,
  1932.      * use {@link Plugin::AppendUserRegistrTransact()} instead!
  1933.      *
  1934.      * @param array Associative array of parameters
  1935.      *    - 'User': the {@link User user object} (as reference).
  1936.      */
  1937.     function AfterUserRegistration$params )
  1938.     {
  1939.     }
  1940.  
  1941.  
  1942.     /**
  1943.      * Event handler: Called at the end of the "Register as new user" form.
  1944.      *
  1945.      * You might want to use this to inject antispam payload to use
  1946.      * in {@link Plugin::RegisterFormSent()}.
  1947.      *
  1948.      * @param array Associative array of parameters
  1949.      *    - 'Form': the comment form generating object (by reference)
  1950.      */
  1951.     function DisplayRegisterFormFieldset$params )
  1952.     {
  1953.     }
  1954.  
  1955.  
  1956.     /**
  1957.      * Event handler: Called when a "Register as new user" form has been submitted.
  1958.      *
  1959.      * You can cancel the registration process by {@link Plugin::msg() adding a message}
  1960.      * of type "error".
  1961.      *
  1962.      * @param array Associative array of parameters
  1963.      *    - 'login': Login name (by reference) (since 1.10.0)
  1964.      *    - 'email': E-Mail value (by reference) (since 1.10.0)
  1965.      *    - 'locale': Locale value (by reference) (since 1.10.0)
  1966.      *    - 'pass1': Password (by reference) (since 1.10.0)
  1967.      *    - 'pass2': Confirmed password (by reference) (since 1.10.0)
  1968.      */
  1969.     function RegisterFormSent$params )
  1970.     {
  1971.     }
  1972.  
  1973.  
  1974.     /**
  1975.      * Event handler: Called at the end of the "Login" form.
  1976.      *
  1977.      * You might want to use this to inject payload to use
  1978.      * in {@link LoginAttempt()}.
  1979.      *
  1980.      * @param array Associative array of parameters
  1981.      *    - 'Form': the comment form generating object (by reference)
  1982.      */
  1983.     function DisplayLoginFormFieldset$params )
  1984.     {
  1985.     }
  1986.  
  1987.  
  1988.     /**
  1989.      * Event handler: called when a user attemps to login.
  1990.      *
  1991.      * You can prevent the user from logging in by {@link Plugin::msg() adding a message}
  1992.      * of type "login_error".
  1993.      *
  1994.      * Otherwise, this hook is meant to authenticate a user against some
  1995.      * external database (e.g. LDAP) and generate a new user.
  1996.      *
  1997.      * To check, if a user already exists in b2evo with that login/password, you might
  1998.      * want to use <code>user_pass_ok( $login, $pass_md5, true )</code>.
  1999.      *
  2000.      * NOTE: if 'pass_hashed' is not empty, you won't receive the password in clear-type. It
  2001.      *       has been hashed using client-side Javascript.
  2002.      *       SHA1( MD5($params['pass']).$params['pass_salt'] ) should result in $params['pass_hashed']!
  2003.      *       If you need the raw password, see {@link LoginAttemptNeedsRawPassword()}.
  2004.      *
  2005.      * @see Plugin::AlternateAuthentication()
  2006.      * @see Plugin::Logout()
  2007.      * @param array Associative array of parameters
  2008.      *    - 'login': user's login (by reference since 1.10.0)
  2009.      *    - 'pass': user's password (by reference since 1.10.0)
  2010.      *    - 'pass_md5': user's md5 password (by reference since 1.10.0)
  2011.      *    - 'pass_salt': the salt used in "pass_hashed" (by reference) (since EVO_NEXT_VERSION)
  2012.      *    - 'pass_hashed': if non-empty this is the users passwords hashed. See note above. (by reference) (since EVO_NEXT_VERSION)
  2013.      *    - 'pass_ok': is the password ok for 'login'? (by reference) (since 1.10.0)
  2014.      */
  2015.     function LoginAttempt$params )
  2016.     {
  2017.     }
  2018.  
  2019.  
  2020.     /**
  2021.      * Event handler: your Plugin should return true here, if it needs a raw (un-hashed)
  2022.      * password for the {@link Plugin::LoginAttempt()} event. If any Plugin returns true
  2023.      * for this event, client-side hashing of the password is not used.
  2024.      * NOTE: this causes passwords to travel un-encrypted, unless SSL/HTTPS get used.
  2025.      *
  2026.      * @return boolean True, if you need the raw password.
  2027.      */
  2028.     function LoginAttemptNeedsRawPassword()
  2029.     {
  2030.         return false;
  2031.     }
  2032.  
  2033.  
  2034.     /**
  2035.      * Event handler: called when a user logs out.
  2036.      *
  2037.      * This is meant to cleanup data, e.g. if you use the
  2038.      * {@link Plugin::AlternateAuthentication()} hook.
  2039.      *
  2040.      * @see Plugin::AlternateAuthentication()
  2041.      * @see Plugin::Logout()
  2042.      * @param array Associative array of parameters
  2043.      *    - 'User': the user object
  2044.      */
  2045.     function Logout$params )
  2046.     {
  2047.     }
  2048.  
  2049.  
  2050.     /**
  2051.      * Event handler: Called at the end of the "Validate user account" form, which gets
  2052.      *                invoked if newusers_mustvalidate is enabled and the user has not
  2053.      *                been validated yet.
  2054.      *
  2055.      * The corresponding action event is {@link Plugin::ValidateAccountFormSent()}.
  2056.      *
  2057.      * @param array Associative array of parameters
  2058.      *    - 'Form': the comment form generating object (by reference)
  2059.      */
  2060.     function DisplayValidateAccountFormFieldset$params )
  2061.     {
  2062.     }
  2063.  
  2064.  
  2065.     /**
  2066.      * Event handler: Called when a "Validate user account" form has been submitted.
  2067.      *
  2068.      * You can cancel the registration process by {@link Plugin::msg() adding a message}
  2069.      * of type "error".
  2070.      */
  2071.     function ValidateAccountFormSent$params )
  2072.     {
  2073.     }
  2074.  
  2075.  
  2076.     /**
  2077.      * Event handler: called at the end of the login process, if the user did not try to
  2078.      *                login (by sending "login" and "pwd"), the session has no user attached
  2079.      *                or only "login" is given.
  2080.      *
  2081.      * This hook is meant to automagically login/authenticate an user by his/her IP address,
  2082.      * special cookie, etc..
  2083.      *
  2084.      * If you can authenticate the user, you'll have to attach him to the {@link $Session},
  2085.      * either through {@link Session::set_user_ID()} or {@link Session::set_User()}.
  2086.      *
  2087.      * @see Plugin::LoginAttempt()
  2088.      * @see Plugin::Logout()
  2089.      * @return boolean True, if the user has been authentificated (set in $Session)
  2090.      */
  2091.     function AlternateAuthentication$params )
  2092.     {
  2093.     }
  2094.  
  2095.  
  2096.     /**
  2097.      * Event handler: called at the end of {@link User::dbupdate() updating}
  2098.      * an user account in the database}, which means that it has been changed.
  2099.      *
  2100.      * @since 1.8.1
  2101.      * @param array Associative array of parameters
  2102.      *    - 'User': the related User (by reference)
  2103.      */
  2104.     function AfterUserUpdate$params )
  2105.     {
  2106.     }
  2107.  
  2108.  
  2109.     /**
  2110.      * Event handler: called at the end of {@link User::dbinsert() inserting}
  2111.      * an user account into the database}, which means it has been created.
  2112.      *
  2113.      * @since 1.8.1
  2114.      * @param array Associative array of parameters
  2115.      *    - 'User': the related User (by reference)
  2116.      */
  2117.     function AfterUserInsert$params )
  2118.     {
  2119.     }
  2120.  
  2121.  
  2122.     /**
  2123.      * Event handler: called at the end of {@link User::dbdelete() deleting}
  2124.      * an user from the database}.
  2125.      *
  2126.      * @since 1.8.1
  2127.      * @param array Associative array of parameters
  2128.      *    - 'User': the related User (by reference)
  2129.      */
  2130.     function AfterUserDelete$params )
  2131.     {
  2132.     }
  2133.  
  2134.     // }}}
  2135.  
  2136.  
  2137.     // General events: {{{
  2138.  
  2139.     /**
  2140.      * Event handler: general event to inject payload for a captcha test.
  2141.      *
  2142.      * This does not get called by b2evolution itself, but provides an interface
  2143.      * to other plugins. E.g., the {@link dnsbl_antispam_plugin DNS blacklist plugin}
  2144.      * uses this event optionally to whitelist a user.
  2145.      *
  2146.      * @param array Associative array of parameters
  2147.      *    - 'Form': the {@link form} where payload should get added (by reference, OPTIONALLY!)
  2148.      *      If it's not given as param, you have to create an own form, if you need one.
  2149.      *    - 'form_use_fieldset': if a "Form" param is given and we use it, should we add
  2150.      *                           an own fieldset? (boolean, default "true", OPTIONALLY!)
  2151.      *    - 'key': A key that is associated to the caller of the event (string, OPTIONALLY!)
  2152.      * @return boolean True, if you have provided payload for a captcha test
  2153.      */
  2154.     function CaptchaPayload$params )
  2155.     {
  2156.     }
  2157.  
  2158.  
  2159.     /**
  2160.      * Event handler: general event to validate a captcha which payload was added
  2161.      * through {@link CaptchaPayload()}.
  2162.      *
  2163.      * This does not get called by b2evolution itself, but provides an interface
  2164.      * to other plugins. E.g., the {@link dnsbl_antispam_plugin DNS blacklist plugin}
  2165.      * uses this event optionally to whitelist a user.
  2166.      *
  2167.      * NOTE: if the action is verified/completed in total, you HAVE to call
  2168.      *       {@link CaptchaValidatedCleanup()}, so that the plugin can cleanup its data
  2169.      *       and is not vulnerable against multiple usage of the same captcha!
  2170.      *
  2171.      * @param array Associative array of parameters
  2172.      *    - 'validate_error': you can optionally set this, if you want to give a reason
  2173.      *      of the failure. This is optionally and meant to be used by other plugins
  2174.      *      that trigger this event.
  2175.      * @return boolean true if the catcha could be validated
  2176.      */
  2177.     function CaptchaValidated$params )
  2178.     {
  2179.     }
  2180.  
  2181.  
  2182.     /**
  2183.      * Event handler: general event to be called after an action has been taken, which
  2184.      * involved {@link CaptchaPayload()} and {@link CaptchaValidated()}.
  2185.      *
  2186.      * This is meant to cleanup generated data for the Captcha test.
  2187.      *
  2188.      * This does not get called by b2evolution itself, but provides an interface
  2189.      * to other plugins. E.g., the {@link dnsbl_antispam_plugin DNS blacklist plugin}
  2190.      * uses this event optionally to whitelist a user.
  2191.      */
  2192.     function CaptchaValidatedCleanup$params )
  2193.     {
  2194.     }
  2195.  
  2196.     // }}}
  2197.  
  2198.  
  2199.     /**
  2200.      * Event handler: Called when an IP address gets displayed, typically in a protected
  2201.      * area or for a privileged user, e.g. in the backoffice statistics menu.
  2202.      *
  2203.      * @param array Associative array of parameters
  2204.      *    - 'data': the data (by reference). You probably want to modify this.
  2205.      *    - 'format': see {@link format_to_output()}.
  2206.      * @return boolean Have we changed something?
  2207.      */
  2208.     function FilterIpAddress$params )
  2209.     {
  2210.         return false;        // Do nothing by default.
  2211.     }
  2212.  
  2213.  
  2214.     /**
  2215.      * Event handler: Called after initializing plugins, DB, Settings, Hit, .. but
  2216.      * quite early.
  2217.      *
  2218.      * This is meant to be a good point for Antispam plugins to cancel the request.
  2219.      *
  2220.      * @see dnsbl_antispam_plugin
  2221.      */
  2222.     function SessionLoaded()
  2223.     {
  2224.     }
  2225.  
  2226.     /*
  2227.      * Event handlers }}}
  2228.      */
  2229.  
  2230.  
  2231.     /*
  2232.      * Helper methods. You should not change/derive those in your plugin, but use them only. {{{
  2233.      */
  2234.  
  2235.     /**
  2236.      * Get a string, unqiue for the plugin, usable in HTML form elements.
  2237.      *
  2238.      * @param string Optional text to append (gets prefixed with "_").
  2239.      * @return string 
  2240.      */
  2241.     function get_class_id$append '' )
  2242.     {
  2243.         return $this->classname.'_id'.$this->ID.$append '_'.$append '' );
  2244.     }
  2245.  
  2246.  
  2247.     /**
  2248.      * Translate a given string, in the Plugin's context.
  2249.      *
  2250.      * This means, that the translation is obtained from the Plugin's "locales" folder.
  2251.      * @link http://manual.b2evolution.net/Localization#Plugins
  2252.      *
  2253.      *  It uses the global/regular {@link T_()} function as fallback.
  2254.      *
  2255.      *  {@internal This is mainly a copy of {@link T_()}, for the $use_l10n==2 case.  
  2256.      *
  2257.      * @param string The string (english), that should be translated
  2258.      * @param string Requested locale ({@link $current_locale} gets used by default)
  2259.      * @return string 
  2260.      */
  2261.     function T_$string$req_locale '' )
  2262.     {
  2263.         global $current_locale$locales$Debuglog$plugins_path$evo_charset;
  2264.  
  2265.         $trans $this->_trans;
  2266.  
  2267.         ifempty($req_locale) )
  2268.         // By default we use the current locale
  2269.             ifempty$current_locale ) )
  2270.             // don't translate if we have no locale
  2271.                 return $string;
  2272.             }
  2273.  
  2274.             $req_locale $current_locale;
  2275.         }
  2276.  
  2277.         ifisset$locales[$req_locale]['messages') )
  2278.         {
  2279.             $this->debug_log'No messages file dirname for locale. $locales["'
  2280.                                             .$req_locale.'"] is '.var_export@$locales[$req_locale]true )'locale' );
  2281.             $locales[$req_locale]['messages'false;
  2282.         }
  2283.  
  2284.         $messages $locales[$req_locale]['messages'];
  2285.  
  2286.         // replace special characters to msgid-equivalents
  2287.         $search preg_replacearray(
  2288.                                     '|\\\([nrt])|',
  2289.                                     '|\n|',
  2290.                                     '|\t|',
  2291.                                     '|\r|',
  2292.                                 ),
  2293.                                 array(
  2294.                                     '\\\\\\\$1',
  2295.                                     '\\n',
  2296.                                     '\\t',
  2297.                                     '',
  2298.                                 )$string );
  2299.  
  2300.         // echo "Translating ", $search, " to $messages<br />";
  2301.  
  2302.         ifisset($trans$messages ) )
  2303.         // Translations for current locale have not yet been loaded:
  2304.  
  2305.             ifisset($this->classfile_path) )
  2306.             // ->T_() called through the plugin's constructor, which is deprecated!
  2307.                 $this->debug_log'T_() method called through plugin constructor!' );
  2308.                 return $string;
  2309.             }
  2310.  
  2311.             $locales_dir dirname($this->classfile_path).'/';
  2312.             if$locales_dir == $plugins_path )
  2313.             {
  2314.                 $locales_dir .= $this->classname.'/';
  2315.             }
  2316.             $locales_dir .= 'locales/';
  2317.  
  2318.             // First load the global messages file, if existing:
  2319.             if$this->_trans_loaded_global )
  2320.             {
  2321.                 $this->_trans_loaded_global true;
  2322.  
  2323.                 $file_path $locales_dir.'_global.php';
  2324.                 iffile_exists($file_path) )
  2325.                 {
  2326.                     ifis_readable($file_path) )
  2327.                     {
  2328.                         // echo 'LOADING GLOBAL '.$file_path;
  2329.                         include $file_path;
  2330.                     }
  2331.                     else
  2332.                     {
  2333.                         $this->debug_log'Global messages file '.$file_path.' is not readable!''locale' );
  2334.                     }
  2335.                 }
  2336.             }
  2337.  
  2338.             // Then load locale specific files:
  2339.             $file_path $locales_dir.$messages.'/_global.php';
  2340.  
  2341.             iffile_exists($file_path) )
  2342.             {
  2343.                 ifis_readable($file_path) )
  2344.                 {
  2345.                     // echo 'LOADING '.$file_path;
  2346.                     include $file_path;
  2347.                 }
  2348.                 else
  2349.                 {
  2350.                     $this->debug_log'Messages file '.$file_path.' for locale '.$req_locale.' is not readable!''locale' );
  2351.                 }
  2352.             }
  2353.  
  2354.             ifisset($trans$messages ) )
  2355.             // Still not loaded... file doesn't exist, memorize that no translations are available
  2356.                 // echo 'file not found!';
  2357.                 $trans$messages array();
  2358.  
  2359.                 /*
  2360.                 May be an english locale without translation.
  2361.                 TODO: when refactoring locales, assign a key for 'original english'.
  2362.                 $Debuglog->add( 'No messages found for locale ['.$req_locale.'],
  2363.                                                 message file [/locales/'.$messages.'/_global.php]', 'locale' );*/
  2364.             }
  2365.  
  2366.             // Remember the charset:
  2367.             ifisset($trans[$messages]['']) )
  2368.             {
  2369.                 if( ($pos strpos($trans[$messages]['']'Content-Type:')) !== false )
  2370.                 {
  2371.                     ifpreg_match('~^Content-Type:.*charset=([\w\d-]+)~'substr($trans[$messages]['']$pos)$match) )
  2372.                     {
  2373.                         $this->_trans_charsets[$messages$match[1];
  2374.                         $this->debug_log'Charset of messages for '.$messages.' is '.$match[1);
  2375.                     }
  2376.                 }
  2377.             }
  2378.             ifisset($this->_trans_charsets[$messages]) )
  2379.             // not provided, use the one of the main locale files:
  2380.                 $this->_trans_charsets[$messages$locales[$req_locale]['charset'];
  2381.             }
  2382.         }
  2383.  
  2384.         ifisset$trans$messages ]$search ) )
  2385.         // If the string has been translated:
  2386.             $r $trans$messages ]$search ];
  2387.         }
  2388.         else
  2389.         // Fallback to global T_() function:
  2390.             return T_$string$req_locale );
  2391.         }
  2392.  
  2393.         ifempty($evo_charset) ) // this extra check is needed, because $evo_charset may not yet be determined.. :/
  2394.         {
  2395.             $r convert_charset$r$evo_charset$this->_trans_charsets[$messages);
  2396.         }
  2397.  
  2398.         return $r;
  2399.     }
  2400.  
  2401.  
  2402.     /**
  2403.      * Get the absolute URL to the plugin's directory (where the plugins classfile is).
  2404.      * Trailing slash included.
  2405.      *
  2406.      * @param string Get absolute URL? (or make it relative to $ReqHost)
  2407.      * @return string 
  2408.      */
  2409.     function get_plugin_url$abs false )
  2410.     {
  2411.         global $plugins_url$plugins_path;
  2412.  
  2413.         // Get sub-path below $plugins_path, if any:
  2414.         $sub_path preg_replace':^'.preg_quote($plugins_path':').':'''dirname($this->classfile_path).'/' );
  2415.  
  2416.         $r $plugins_url.$sub_path;
  2417.  
  2418.         // Use the same protocol as with current host (so includes from within https do not fail when on http):
  2419.         $r url_same_protocol($r);
  2420.  
  2421.         // Make it relative to current host, if absolute is not required:
  2422.         if$abs )
  2423.         {
  2424.             global $ReqHost;
  2425.             $r url_rel_to_same_host($r$ReqHost);
  2426.         }
  2427.         return $r;
  2428.     }
  2429.  
  2430.  
  2431.     /**
  2432.      * Log a debug message.
  2433.      *
  2434.      * This gets added to {@link $Debuglog the global Debuglog} with
  2435.      * the category '[plugin_classname]_[plugin_ID]'.
  2436.      *
  2437.      * NOTE: if debugging is not enabled (see {@link $debug}), {@link $Debuglog}
  2438.      * is of class {@link Log_noop}, which means it does not accept nor display
  2439.      * messages.
  2440.      *
  2441.      * @param string Message to log.
  2442.      * @param array Optional list of additional categories.
  2443.      */
  2444.     function debug_log$msg$add_cats array() )
  2445.     {
  2446.         global $Debuglog;
  2447.  
  2448.         ifis_array($add_cats) )
  2449.         {
  2450.             $add_cats array($add_cats);
  2451.         }
  2452.  
  2453.         ifisset($this->ID$this->classname) )
  2454.         // plugin not yet instantiated. This happens, if the (deprecated) constructor of a plugin gets used.
  2455.             $add_cats[get_class($this).'_?';
  2456.         }
  2457.         else
  2458.         {
  2459.             $add_cats[$this->classname.'_'.$this->ID;
  2460.         }
  2461.         $Debuglog->add$msg$add_cats );
  2462.     }
  2463.  
  2464.  
  2465.     /**
  2466.      * Get the URL to call a plugin method through http. This links to the /htsrv/call_plugin.php
  2467.      * file.
  2468.      *
  2469.      * It uses either {@link $htsrv_url} or {@link $htsrv_url_sensitive} (if {@link $ReqHost} is on https).
  2470.      *
  2471.      * NOTE: AJAX callbacks are required to be on the same domain/protocol, so if you're using absolute
  2472.      *       blog URLs on different domains you must set {@link $htsrv_url} dynamically, to use the same domain!
  2473.      *
  2474.      * @todo dh> we might want to provide whitelisting of methods through {@link $Session} here and check for it in the htsrv handler.
  2475.      *
  2476.      * @param string Method to call. This must be listed in {@link GetHtsrvMethods()}.
  2477.      * @param array Array of optional parameters passed to the method.
  2478.      * @param string Glue for additional GET params used internally.
  2479.      * @param string Get absolute URL? (or cut off $ReqHost at the beginning)
  2480.      * @return string The URL
  2481.      */
  2482.     function get_htsrv_url$method$params array()$glue '&amp;'$abs false )
  2483.     {
  2484.         global $htsrv_url$htsrv_url_sensitive;
  2485.         global $ReqHost$Blog;
  2486.  
  2487.         $base substr($ReqHost06== 'https:' $htsrv_url_sensitive $htsrv_url;
  2488.  
  2489.         if$abs && strpos$base$ReqHost === )
  2490.         // cut off $ReqHost if the resulting URL starts with it:
  2491.             $base substr($basestrlen($ReqHost));
  2492.         }
  2493.  
  2494.         $r $base.'call_plugin.php?plugin_ID='.$this->ID.$glue.'method='.$method;
  2495.         if!empty$params ) )
  2496.         {
  2497.             $r .= $glue.'params='.rawurlencode(serialize$params ));
  2498.         }
  2499.  
  2500.         return $r;
  2501.     }
  2502.  
  2503.  
  2504.     /**
  2505.      * A simple wrapper around the {@link $Messages} object with a default
  2506.      * catgory of 'note'.
  2507.      *
  2508.      * @param string Message
  2509.      * @param string|arraycategory ('note', 'error', 'success'; default: 'note')
  2510.      */
  2511.     function msg$msg$category 'note' )
  2512.     {
  2513.         global $Messages;
  2514.         $Messages->add$msg$category );
  2515.     }
  2516.  
  2517.  
  2518.     /**
  2519.      * Register a tab (sub-menu) for the backoffice Tools menus.
  2520.      *
  2521.      * @param string Text for the tab.
  2522.      * @param string|arrayPath to add the menu entry into.
  2523.      *         See {@link AdminUI::add_menu_entries()}. Default: 'tools' for the Tools menu.
  2524.      * @param array Optional params. See {@link AdminUI::add_menu_entries()}.
  2525.      */
  2526.     function register_menu_entry$text$path 'tools'$menu_entry_props array() )
  2527.     {
  2528.         global $AdminUI;
  2529.  
  2530.         $menu_entry_props['text'$text;
  2531.         $menu_entry_props['href''admin.php?ctrl=tools&amp;tab=plug_ID_'.$this->ID;
  2532.  
  2533.         $AdminUI->add_menu_entries$patharray'plug_ID_'.$this->ID => $menu_entry_props ) );
  2534.     }
  2535.  
  2536.  
  2537.     /**
  2538.      * Check if the requested list of events is provided by any or one plugin.
  2539.      *
  2540.      * @param array|stringA single event or a list thereof
  2541.      * @param boolean Make sure there's at least one plugin that provides them all?
  2542.      *                 This is useful for event pairs like "CaptchaPayload" and "CaptchaValidated", which
  2543.      *                 should be served by the same plugin.
  2544.      * @return boolean 
  2545.      */
  2546.     function are_events_available$events$by_one_plugin false )
  2547.     {
  2548.         global $Plugins;
  2549.  
  2550.         return $Plugins->are_events_available$events$by_one_plugin );
  2551.     }
  2552.  
  2553.  
  2554.     /**
  2555.      * Set the status of the plugin.
  2556.      *
  2557.      * @param string 'enabled', 'disabled' or 'needs_config'
  2558.      * @return boolean 
  2559.      */
  2560.     function set_status$status )
  2561.     {
  2562.         global $Plugins;
  2563.  
  2564.         ifin_array$statusarray'enabled''disabled''needs_config' ) ) )
  2565.         {
  2566.             return false;
  2567.         }
  2568.  
  2569.         $Plugins->set_Plugin_status$this$status );
  2570.     }
  2571.  
  2572.  
  2573.     /**
  2574.      * Get canonical name for database tables a plugin uses, by adding an unique
  2575.      * prefix for your plugin instance.
  2576.      *
  2577.      * You should use this when refering to your SQL table names.
  2578.      *
  2579.      * E.g., for the "test_plugin" with ID 7 and the default {@link $tableprefix} of "evo_" it
  2580.      * would generate: "evo_plugin_test_7_log" for a requested name "log".
  2581.      *
  2582.      * @param string Your name, which gets returned with the unique prefix.
  2583.      * @return string 
  2584.      */
  2585.     function get_sql_table$name )
  2586.     {
  2587.         global $tableprefix;
  2588.  
  2589.         // NOTE: table name length seems limited to 64 chars (MySQL 5) - classname is limited to 40 (in T_plugins)
  2590.         return $tableprefix.'plugin_'.preg_replace'#_plugin$#'''$this->classname ).'_'.$this->ID.'_'.$name;
  2591.     }
  2592.  
  2593.  
  2594.     /**
  2595.      * Stop propagation of the event to next plugins (with lower priority)
  2596.      * in events that get triggered for a batch of Plugins.
  2597.      *
  2598.      * @see Plugins::trigger_event()
  2599.      * @see Plugins::stop_propagation()
  2600.      */
  2601.     function stop_propagation()
  2602.     {
  2603.         global $Plugins;
  2604.         $Plugins->stop_propagation();
  2605.     }
  2606.  
  2607.  
  2608.     /**
  2609.      * Set a data value for the session.
  2610.      *
  2611.      * NOTE: the session data is limited to about 64kb, so do not use it for huge data!
  2612.      *       Please consider using an own database table (see {@link Plugin::GetDbLayout()}).
  2613.      *
  2614.      * @param string Name of the data's key (gets prefixed with 'plugIDX_' internally).
  2615.      * @param mixed The value
  2616.      * @param integer Time in seconds for data to expire (0 to disable).
  2617.      * @param boolean Should the data get saved immediately? (otherwise it gets saved on script shutdown)
  2618.      */
  2619.     function session_set$name$value$timeout$save_immediately false )
  2620.     {
  2621.         global $Session;
  2622.  
  2623.         $r $Session->set'plugID'.$this->ID.'_'.$name$value$timeout );
  2624.         if$save_immediately )
  2625.         {
  2626.             $Session->dbsave();
  2627.         }
  2628.         return $r;
  2629.     }
  2630.  
  2631.  
  2632.     /**
  2633.      * Get a data value for the session, using a unique prefix to the Plugin.
  2634.      * This checks for the data to be expired and unsets it then.
  2635.      *
  2636.      * @param string Name of the data's key (gets prefixed with 'plugIDX_' internally).
  2637.      * @param mixed Default value to use if key is not set or has expired. (since 1.10.0)
  2638.      * @return mixed The value, if set; otherwise $default
  2639.      */
  2640.     function session_get$name$default NULL )
  2641.     {
  2642.         global $Session;
  2643.  
  2644.         return $Session->get'plugID'.$this->ID.'_'.$name$default );
  2645.     }
  2646.  
  2647.  
  2648.     /**
  2649.      * Delete a value from the session data, using a unique prefix to the Plugin.
  2650.      *
  2651.      * @param string Name of the data's key (gets prefixed with 'plugIDX_' internally).
  2652.      */
  2653.     function session_delete$name )
  2654.     {
  2655.         global $Session;
  2656.  
  2657.         return $Session->delete'plugID'.$this->ID.'_'.$name );
  2658.     }
  2659.  
  2660.  
  2661.     /**
  2662.      * Call this to unregister all your events for the current request.
  2663.      */
  2664.     function forget_events()
  2665.     {
  2666.         global $Plugins;
  2667.         $Plugins->forget_events$this->ID );
  2668.     }
  2669.  
  2670.  
  2671.     /**
  2672.      * Disable an event.
  2673.      *
  2674.      * This removes it from the events table.
  2675.      *
  2676.      * @return boolean True, if status has changed; false if it was disabled already
  2677.      */
  2678.     function disable_event$event )
  2679.     {
  2680.         $Plugins_admin get_Cache('Plugins_admin');
  2681.         return $Plugins_admin->set_event_status$this->ID$event);
  2682.     }
  2683.  
  2684.  
  2685.     /**
  2686.      * Enable an event.
  2687.      *
  2688.      * This adds it to the events table.
  2689.      *
  2690.      * @return boolean True, if status has changed; false if it was enabled already
  2691.      */
  2692.     function enable_event$event )
  2693.     {
  2694.         $Plugins_admin get_Cache('Plugins_admin');
  2695.         return $Plugins_admin->set_event_status$this->ID$event);
  2696.     }
  2697.  
  2698.     /*
  2699.      * Helper methods }}}
  2700.      */
  2701.  
  2702.  
  2703.     /*
  2704.      * Interface methods. You should not override those! {{{
  2705.      *
  2706.      * These are used to access certain plugin internals.
  2707.      */
  2708.  
  2709.     /**
  2710.      * Get a link to a help page (with icon).
  2711.      *
  2712.      * @param string Target; one of the following:
  2713.      *          - anchor to {@link $help_url} ("#anchor")
  2714.      *          - absolute link to some URL, e.g. "http://example.com/example.php"
  2715.      *          - '$help_url' or empty for {@link $help_url}, then also the "www" icon gets used
  2716.      *          - '$readme' to link to the plugin's README.html file (if available)
  2717.      * @return string The html A tag, linking to the help (or empty in case of $readme, if there is none).
  2718.      */
  2719.     function get_help_link$target '' )
  2720.     {
  2721.         static $target_counter 0;
  2722.         $title '';
  2723.         $icon 'help';
  2724.         $word '';
  2725.         $link_attribs array'target' => '_blank''id'=>'anchor_help_plugin_'.$this->ID.'_'.$target_counter++ );
  2726.  
  2727.         if$target == '$help_url' || empty($target) )
  2728.         {
  2729.             $url $this->get_help_url();
  2730.             $title T_('Homepage of the plugin');
  2731.             $icon 'www';
  2732.         }
  2733.         elseif$target == '$readme' )
  2734.         // README
  2735.             if$this->get_help_file() )
  2736.             {
  2737.                 return '';
  2738.             }
  2739.  
  2740.             global $admin_url;
  2741.  
  2742.             $link_attribs['use_js_popup'true;
  2743.             $link_attribs['use_js_size''500, 400';
  2744.             $title T_('Local documentation of the plugin');
  2745.             $url url_add_param$admin_url'ctrl=plugins&amp;action=disp_help_plain&amp;plugin_class='.$this->classname );
  2746.             $icon 'help';
  2747.         }
  2748.         elseifsubstr($target01== '#' )
  2749.         // anchor
  2750.             $url $this->get_help_url().$target;
  2751.         }
  2752.         elseifpreg_match'~^https?://~'$target ) )
  2753.         // absolute URL (strict match to allow other formats later if needed)
  2754.             $url $target;
  2755.         }
  2756.         else
  2757.         {
  2758.             debug_die'Invalid get_help_link() target: '.$target );
  2759.         }
  2760.  
  2761.         return action_icon$title$icon$url$word41$link_attribs );
  2762.     }
  2763.  
  2764.  
  2765.     /**
  2766.      * Get the plugin's external help/website URL.
  2767.      *
  2768.      * If {@link Plugin::$help_url} is empty, it defaults to the manual wiki.
  2769.      *
  2770.      * @return string 
  2771.      */
  2772.     function get_help_url()
  2773.     {
  2774.         ifempty$this->help_url ) )
  2775.         {
  2776.             return 'http://manual.b2evolution.net/'.strtoupper($this->classname[0]).substr($this->classname,1);
  2777.         }
  2778.         else
  2779.         {
  2780.             return $this->help_url;
  2781.         }
  2782.     }
  2783.  
  2784.  
  2785.     /**
  2786.      * @deprecated Backwards compatibility wrapper (for 1.8)
  2787.      */
  2788.     function get_README_link()
  2789.     {
  2790.         return $this->get_help_link('$readme');
  2791.     }
  2792.  
  2793.  
  2794.     /**
  2795.      * Get the help file for a Plugin ID. README.LOCALE.html will take
  2796.      * precedence above the general (english) README.html.
  2797.      *
  2798.      * @todo Handle encoding of files (to $io_charset)
  2799.      *
  2800.      * @return false|string
  2801.      */
  2802.     function get_help_file()
  2803.     {
  2804.         global $default_locale$plugins_path$current_User;
  2805.  
  2806.         if$current_User->check_perm'options''view'false ) )
  2807.         // README gets displayed through plugins controller, which requires these perms
  2808.             // TODO: Catch "disp_help" and "disp_help_plain" messages in plugins.php before general perms check!?
  2809.             return false;
  2810.         }
  2811.  
  2812.         // Get the language. We use $default_locale because it does not have to be activated ($current_locale)
  2813.         $lang substr$default_locale0);
  2814.  
  2815.         $help_dir dirname($this->classfile_path).'/';
  2816.         if$help_dir == $plugins_path )
  2817.         {
  2818.             $help_dir .= $this->classname.'/';
  2819.         }
  2820.  
  2821.         // Try help for the user's locale:
  2822.         $help_file $help_dir.'README.'.$lang.'.html';
  2823.  
  2824.         iffile_exists($help_file) )
  2825.         // Fallback: README.html
  2826.             $help_file $help_dir.'README.html';
  2827.  
  2828.             iffile_exists($help_file) )
  2829.             {
  2830.                 return false;
  2831.             }
  2832.         }
  2833.  
  2834.         return $help_file;
  2835.     }
  2836.  
  2837.  
  2838.     /**
  2839.      * Get a link to edit the Plugin's settings (if the user has permission).
  2840.      *
  2841.      * @return false|string
  2842.      */
  2843.     function get_edit_settings_link()
  2844.     {
  2845.         global $current_User$admin_url;
  2846.  
  2847.         if$current_User->check_perm'options''view'false ) )
  2848.         {
  2849.             return false;
  2850.         }
  2851.  
  2852.         return action_iconT_('Edit plugin settings!')'edit'$admin_url.'?ctrl=plugins&amp;action=edit_settings&amp;plugin_ID='.$this->ID );
  2853.     }
  2854.  
  2855.  
  2856.     /**
  2857.      * PHP5 overloading of get method to lazy-load (User)Settings.
  2858.      *
  2859.      * @return Reference to the object or null
  2860.      */
  2861.     function __get$nm )
  2862.     {
  2863.         global $inc_path;
  2864.         require_once $inc_path.'_core/_class4.funcs.php';
  2865.         $admin_Plugins get_Cache('Plugins_admin')// we need Plugins_admin here, because Plugin::BeforeEnable() may use $Settings
  2866.  
  2867.         switch$nm )
  2868.         {
  2869.             case 'Settings':
  2870.                 $admin_Plugins->instantiate_Settings$this'Settings' );
  2871.                 ifisset($this->Settings) )
  2872.                 {
  2873.                     return $this->Settings;
  2874.                 }
  2875.                 break;
  2876.  
  2877.             case 'UserSettings':
  2878.                 $admin_Plugins->instantiate_Settings$this'UserSettings' );
  2879.                 ifisset($this->UserSettings) )
  2880.                 {
  2881.                     return $this->UserSettings;
  2882.                 }
  2883.                 break;
  2884.         }
  2885.         $r null;
  2886.         return $r;
  2887.     }
  2888.  
  2889.     /*
  2890.      * Interface methods }}}
  2891.      */
  2892.  
  2893. }
  2894.  
  2895.  
  2896. /*
  2897.  * $Log: _plugin.class.php,v $
  2898.  * Revision 1.6.2.1  2009/04/30 21:21:16  tblue246
  2899.  * Apply T_() fixes to Plugin::T_(), too
  2900.  *
  2901.  * Revision 1.6  2008/01/21 09:35:32  fplanque
  2902.  * (c) 2008
  2903.  *
  2904.  * Revision 1.5  2008/01/14 23:41:47  fplanque
  2905.  * cleanup load_funcs( urls ) in main because it is ubiquitously used
  2906.  *
  2907.  * Revision 1.4  2007/09/22 22:11:18  fplanque
  2908.  * minor
  2909.  *
  2910.  * Revision 1.3  2007/08/11 17:59:05  blueyed
  2911.  * Mention also trackback in GetSpamKarmaForComment doc
  2912.  *
  2913.  * Revision 1.2  2007/08/03 20:40:49  blueyed
  2914.  * - doc for todos/discussion
  2915.  * - Made get_plugin_url more usable again
  2916.  *
  2917.  * Revision 1.1  2007/06/25 11:00:41  fplanque
  2918.  * MODULES (refactored MVC)
  2919.  *
  2920.  * Revision 1.161  2007/06/20 21:42:14  fplanque
  2921.  * implemented working widget/plugin params
  2922.  *
  2923.  * Revision 1.160  2007/06/19 22:54:04  blueyed
  2924.  * doc fix
  2925.  *
  2926.  * Revision 1.159  2007/06/19 22:53:25  blueyed
  2927.  * todos/doc fixes
  2928.  *
  2929.  * Revision 1.158  2007/06/19 00:03:26  fplanque
  2930.  * doc / trying to make sense of automatic settings forms generation.
  2931.  *
  2932.  * Revision 1.157  2007/05/28 15:18:30  fplanque
  2933.  * cleanup
  2934.  *
  2935.  * Revision 1.156  2007/05/26 19:05:03  blueyed
  2936.  * Return array() in GetDefaultUserSettings, as with GetDefaultSettings
  2937.  *
  2938.  * Revision 1.155  2007/05/06 21:14:19  personman2
  2939.  * Fixed broken link from Tools > Scheduler to Tools > [any plugin tab]
  2940.  *
  2941.  * Revision 1.154  2007/04/28 22:33:26  blueyed
  2942.  * Fixed "must return reference notice" for __get()
  2943.  *
  2944.  * Revision 1.153  2007/04/26 00:11:08  fplanque
  2945.  * (c) 2007
  2946.  *
  2947.  * Revision 1.152  2007/03/26 21:34:59  blueyed
  2948.  * Removed $Plugin->Plugins reference
  2949.  *
  2950.  * Revision 1.151  2007/03/26 21:04:12  blueyed
  2951.  * Return by reference in __get()
  2952.  *
  2953.  * Revision 1.150  2007/02/28 23:21:53  blueyed
  2954.  * Pass $original_comment to CommentFormSent and "action" to BeforeCommentFormInsert
  2955.  *
  2956.  * Revision 1.149  2007/02/25 02:03:51  fplanque
  2957.  * no message
  2958.  *
  2959.  * Revision 1.148  2007/02/23 00:21:23  blueyed
  2960.  * Fixed Plugins::get_next() if the last Plugin got unregistered; Added AdminBeforeItemEditDelete hook
  2961.  *
  2962.  * Revision 1.147  2007/02/22 22:14:13  blueyed
  2963.  * Improved CommentFormSent hook
  2964.  *
  2965.  * Revision 1.146  2007/02/19 23:20:07  blueyed
  2966.  * Added plugin event SkinEndHtmlBody
  2967.  *
  2968.  * Revision 1.145  2007/02/17 21:12:14  blueyed
  2969.  * Removed magic in Plugin::get_htsrv_url() which used the blog url and assumed that "htsrv" was available in there
  2970.  *
  2971.  * Revision 1.144  2007/02/03 20:25:37  blueyed
  2972.  * Added "sender_name", "sender_email" and "subject" params to MessageFormSent
  2973.  *
  2974.  * Revision 1.143  2007/02/03 19:49:36  blueyed
  2975.  * Added "Blog" param to MessageFormSent hook
  2976.  *
  2977.  * Revision 1.142  2007/01/28 23:58:46  blueyed
  2978.  * - Added hook CommentFormSent
  2979.  * - Re-ordered comment_post.php to: init, validate, process
  2980.  * - RegisterFormSent hook can now filter the form values in a clean way
  2981.  *
  2982.  * Revision 1.141  2007/01/27 16:08:53  blueyed
  2983.  * Pass "User" param to PluginUserSettingsEditDisplayAfter plugin hook
  2984.  *
  2985.  * Revision 1.140  2007/01/27 15:19:06  blueyed
  2986.  * doc
  2987.  *
  2988.  * Revision 1.139  2007/01/26 21:52:42  blueyed
  2989.  * Improved LoginAttempt hook: all params get passed by reference and "pass_ok" has been added
  2990.  *
  2991.  * Revision 1.138  2007/01/25 00:59:49  blueyed
  2992.  * Do not pass "original_comment" in BeforeCommentFormInsert as a reference: makes no sense
  2993.  *
  2994.  * Revision 1.137  2007/01/24 00:48:58  fplanque
  2995.  * Refactoring
  2996.  *
  2997.  * Revision 1.136  2007/01/20 23:48:10  blueyed
  2998.  * Changed plugin default URL to manual.b2evolution.net/classname_plugin
  2999.  *
  3000.  * Revision 1.135  2007/01/17 23:37:10  blueyed
  3001.  * Bypass new $default param in Plugin::session_get()
  3002.  *
  3003.  * Revision 1.134  2007/01/14 18:05:45  blueyed
  3004.  * Optimized "info", "disp_help" and "disp_help_plain" actions by refering to them through classname, which makes Plugins::discover() unnecessary
  3005.  *
  3006.  * Revision 1.133  2007/01/13 16:41:51  blueyed
  3007.  * doc
  3008.  *
  3009.  * Revision 1.132  2007/01/13 03:34:00  fplanque
  3010.  * ...
  3011.  *
  3012.  * Revision 1.131  2007/01/12 21:01:23  blueyed
  3013.  * doc about $Plugins member
  3014.  *
  3015.  * Revision 1.130  2007/01/12 05:14:42  fplanque
  3016.  * doc
  3017.  *
  3018.  * Revision 1.129  2006/12/28 23:20:40  fplanque
  3019.  * added plugin event for displaying comment form toolbars
  3020.  * used by smilies plugin
  3021.  *
  3022.  * Revision 1.128  2006/12/22 22:29:35  blueyed
  3023.  * Support for "multiple" attribute in SELECT elements, especially for GetDefault(User)Settings plugin callback
  3024.  *
  3025.  * Revision 1.127  2006/12/07 23:13:13  fplanque
  3026.  * @var needs to have only one argument: the variable type
  3027.  * Otherwise, I can't code!
  3028.  *
  3029.  * Revision 1.126  2006/12/05 00:24:10  blueyed
  3030.  * doc fix
  3031.  *
  3032.  * Revision 1.125  2006/12/04 00:18:53  fplanque
  3033.  * keeping the login hashing
  3034.  *
  3035.  * Revision 1.123  2006/12/01 20:34:03  blueyed
  3036.  * Moved Plugins::get_apply_rendering_values() and Plugins::set_apply_rendering() to Plugins_admin class
  3037.  *
  3038.  * Revision 1.122  2006/12/01 16:47:26  blueyed
  3039.  * - Use EVO_NEXT_VERSION, which should get replaced with the next version 1.10 or 2.0 or whatever
  3040.  * - "action" param for PluginSettingsValidateSet
  3041.  * - Removed deprecated Plugin::set_param()
  3042.  *
  3043.  * Revision 1.121  2006/12/01 16:26:34  blueyed
  3044.  * Added AdminDisplayCommentFormFieldset hook
  3045.  *
  3046.  * Revision 1.120  2006/12/01 02:03:04  blueyed
  3047.  * Moved Plugins::set_event_status() to Plugins_admin
  3048.  *
  3049.  * Revision 1.119  2006/11/24 18:27:27  blueyed
  3050.  * Fixed link to b2evo CVS browsing interface in file docblocks
  3051.  *
  3052.  * Revision 1.118  2006/11/17 18:36:22  blueyed
  3053.  * dbchanges param for AfterItemUpdate, AfterItemInsert, AfterCommentUpdate and AfterCommentInsert
  3054.  *
  3055.  * Revision 1.117  2006/11/16 23:43:39  blueyed
  3056.  * - "key" entry for array-type Plugin(User)Settings can define an input field for the key of the settings entry
  3057.  * - cleanup
  3058.  *
  3059.  * Revision 1.116  2006/11/15 21:14:04  blueyed
  3060.  * "Restore defaults" in user profile
  3061.  *
  3062.  * Revision 1.115  2006/11/14 00:21:33  blueyed
  3063.  * doc
  3064.  *
  3065.  * Revision 1.114  2006/11/12 02:12:58  blueyed
  3066.  * removed bloat param
  3067.  *
  3068.  * Revision 1.113  2006/11/11 20:33:14  blueyed
  3069.  * Moved BeforeBlogDisplay hook to after $skin has been determined
  3070.  *
  3071.  * Revision 1.112  2006/11/10 17:14:20  blueyed
  3072.  * Added "select_blog" type for Plugin (User)Settings
  3073.  *
  3074.  * Revision 1.111  2006/11/09 22:27:57  blueyed
  3075.  * doc
  3076.  *
  3077.  * Revision 1.110  2006/11/04 18:16:31  blueyed
  3078.  * MFB: note about bug in 1.8.x
  3079.  *
  3080.  * Revision 1.109  2006/11/02 15:57:10  blueyed
  3081.  * doc
  3082.  *
  3083.  * Revision 1.108  2006/11/01 23:18:58  blueyed
  3084.  * Fixed __get()
  3085.  *
  3086.  * Revision 1.106  2006/10/30 19:53:27  blueyed
  3087.  * doc fix
  3088.  *
  3089.  * Revision 1.105  2006/10/30 19:00:36  blueyed
  3090.  * Lazy-loading of Plugin (User)Settings for PHP5 through overloading
  3091.  *
  3092.  * Revision 1.104  2006/10/29 20:07:34  blueyed
  3093.  * Added "app_min" plugin dependency; Deprecated "api_min"
  3094.  *
  3095.  * Revision 1.103  2006/10/28 20:07:01  blueyed
  3096.  * Deprecated Plugin::set_param() - no use
  3097.  *
  3098.  * Revision 1.102  2006/10/28 15:01:36  blueyed
  3099.  * Documentation
  3100.  *
  3101.  * Revision 1.100  2006/10/14 16:27:05  blueyed
  3102.  * Client-side password hashing in the login form.
  3103.  *
  3104.  * Revision 1.99  2006/10/08 22:59:31  blueyed
  3105.  * Added GetProvidedSkins and DisplaySkin hooks. Allow for optimization in Plugins::trigger_event_first_return()
  3106.  *
  3107.  * Revision 1.98  2006/10/08 22:13:06  blueyed
  3108.  * Added "float" type to Plugin Setting types.
  3109.  *
  3110.  * Revision 1.97  2006/10/05 01:06:37  blueyed
  3111.  * Removed dirty "hack"; added ItemApplyAsRenderer hook instead.
  3112.  *
  3113.  * Revision 1.96  2006/10/04 23:51:02  blueyed
  3114.  * Dirty workaround for lazy renderers who detect when they should apply and pre-rendering
  3115.  *
  3116.  * Revision 1.95  2006/10/01 22:21:54  blueyed
  3117.  * edit_layout param fixes/doc
  3118.  *
  3119.  * Revision 1.94  2006/10/01 22:11:42  blueyed
  3120.  * Ping services as plugins.
  3121.  *
  3122.  * Revision 1.93  2006/10/01 15:11:08  blueyed
  3123.  * Added DisplayItemAs* equivs to RenderItemAs*; removed DisplayItemAllFormats; clearing of pre-rendered cache, according to plugin event changes
  3124.  */
  3125. ?>

Documentation generated on Sat, 06 Mar 2010 03:38:35 +0100 by phpDocumentor 1.4.2. This site is hosted and maintained by Daniel HAHLER (Contact).