Documenation

Creating plugins

Swiftlet is very modular by design. Almost all of it's functionality can be replaced or extended with plugins.

To create a plugin, copy an existing plugin or start with an empty file in the /_plugins directory. By convention, the name of the file should be the name of the plugin.

Example plugin (/_plugins/example.php)

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<?php
if ( !isset($model) ) die('Direct access to this file is not allowed');

switch ( 
$hook )
{
    case 
'info':
        
$info = array(
            
'name'       => 'example',
            
'version'    => '1.0.0',
            
'compatible' => array('from' => '1.2.0''to' => '1.2.*'),
            
'hooks'      => array('init' => 1)
            );

        break;
    case 
'init':
        
$view->load('example.html.php');

        break;
}
?>

The first line is to make sure the plugin isn't being called directly from the browser.

Initially the Model will use the info hook to gather information about the plugin. This includes the plugin's name, version number and compatibility info (Swiftlet version numbers). This is also where other hooks are registered, in the example's case only the init hook.

When the init hook is called the plugin is reloaded, this time executing the code in the init block.

Creating database tables

In many cases plugins need access to the database and new tables need to be created. This can be done using the install hook. These plugins need to be installed through the plugin installer at /installer/. Here is a more elaborate example of a plugin:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
if ( !isset($model) ) die('Direct access to this file is not allowed');

switch ( 
$hook )
{
    case 
'load':
        
$info = array(
            
'name'         => 'example',
            
'description'  => 'Description here.',
            
'version'      => '1.0.0',
            
'compatible'   => array('from' => '1.2.0''to' => '1.2.*'),
            
'upgradable'   => array('from' => '1.1.0''to' => '1.1.*'),
            
'dependencies' => array('db'),
            
'hooks'        => array('init' => 1'install' => 1)
            );

        break;
    case 
'install':
        
$model->db->sql('
            CREATE TABLE `' 
$model->db->prefix 'example` (
                `id`  INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
                `foo` VARCHAR(256)     NOT NULL,
                PRIMARY KEY (`id`)
                )
            ;'
);

        break;
    case 
'upgrade':
        
$model->db->sql('
            UPDATE `' 
$model->db->prefix 'example` SET
                `foo` = "bar"
            ;'
);

        break;
    case 
'init':
        require(
$contr->classPath 'example.php');

        
$model->example = new example($model);

        break;
}
?>

The install and upgrade hooks are used by the plugin installer. Plugins can only be upgraded if the Swiftlet version matches the values in $info['upgradable'] (to go from version 1.0.x to 3.0.x, you usually have to upgrade to version 2.0.x first).

Because this plugin requires a database, the db plugin should be declared as a dependency. This ensures the plugin will not be installed unless the Database plugin is installed and ready.

Classes

It's good practice to put plugin functionality in a separate class (these are stored in the /_plugins/classes directory). This way functions are more or less sandboxed and won't interfere with other plugins or the global scope.

This is a basic example of a plugin class:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<?php
if ( !isset($model) ) die('Direct access to this file is not allowed');

class 
example
{
    public
        
$ready
        
;

    function 
__construct($model)
    {
        
$this->ready TRUE;
    }
}
?>

An instance of $model should be passed to each class in order to access the Model inside the class.

If the plugin is required by other plugins or pages the $ready variable is checked using $model->check_dependencies(). The variable should always be set.

See also