Extension Development - shish/shimmie2 GitHub Wiki

Events

An event is a little blob of data saying "something happened", possibly "something happened, here's the specific data". Events are sent with the send_event() function. Since events can store data, they can be used to return data to the extension which sent them, for example:

$tfe = new TextFormattingEvent($original_text);  // create an empty event
send_event($tfe);                                // broadcast it to the world
$formatted_text = $tfe->formatted;               // see what it brought home

Extensions

An extension is something which is capable of reacting to events.

// ext/make_text_bold/main.php
class MakeTextBold extends Extension {
    public function onTextFormatting(TextFormattingEvent $event) {
        $event->formatted = "<b>" . $event->formatted . "</b>";
    }
}

Configuration

// ext/make_text_bold/config.php
class MakeTextBoldConfig extends ConfigGroup
{
    // must match the KEY in Extension / ExtensionInfo
    public const KEY = "make_text_bold";

    // ConfigMeta is used to automatically generate the Board Config page.
    // The const name is how to refer to this setting within the code.
    // The string can be anything unique, but shouldn't be changed because
    // it ends up being written to and read from the database.
    #[ConfigMeta("Font Size", ConfigType::INT, default: 10)]
    public const FONT_SIZE = 'make_text_bold_font_size';
}

Useful Variables

There are a few global variables which are pretty essential to most extensions:

Ctx::$config -- some variety of Config subclass

Ctx::$config->get(MakeTextBoldConfig::FONT_SIZE);  // Get a config value

Ctx::$database -- a Database object used to get raw SQL access

Ctx::$database->execute(...);
Ctx::$database->get_all(...);
Ctx::$database->get_row(...);
Ctx::$database->get_col(...);
Ctx::$database->get_one(...);

Ctx::$page -- a Page to hold all the loose bits of extension output

// For rendering a web page
Ctx::$page->set_title(...);
Ctx::$page->add_block(...);
Ctx::$page->flash("Hello world!");

// To output specific data
Ctx::$page->set_data(MimeType::JSON, json_encode($data));

// To redirect to a different URL
Ctx::$page->set_redirect(make_link("post/list"));

Ctx::$user -- the currently logged in User

// Get basic info
Ctx::$user->id;
Ctx::$user->name;

// Check if a user has permission to perform a certain action
Ctx::$user->can(IndexPermission::BIG_SEARCH);

Ctx::$cache -- an optional Cache for fast key / value lookups (eg Memcache)

Ctx::$cache->set("foo", "bar");
Ctx::$cache->get("foo");
Ctx::$cache->delete("foo");

The Hello World Extension

Here's a simple extension which listens for PageRequestEvents, and each time it sees one, it sends out a HelloEvent.

// ext/hello/main.php
public class HelloEvent extends Event {
    public function __construct(string $username) {
        $this->username = $username;
    }
}

public class Hello extends Extension {
    public const KEY = "hello";                                // A unique ID for this extension

    public function onPageRequest(PageRequestEvent $event) {   // Every time a page request is sent
        send_event(new HelloEvent(Ctx::$user->name));          // Broadcast a signal saying hello to that user
    }

    public function onHello(HelloEvent $event) {               // When the "Hello" signal is received
        $this->theme->display_hello($event->username);         // Display a message on the web page
    }
}
// ext/hello/theme.php
public class HelloTheme extends Themelet {
    public function display_hello(string $username) {
        $block = new Block("Hello!", DIV("Hello there $username"));
        Ctx::$page->add_block($block);
    }
}
// themes/my_theme/hello.theme.php
public class MyThemeHelloTheme extends HelloTheme {     // MyThemeHelloTheme overrides HelloTheme
    public function display_hello(string $username) {   // the display_hello() function is customised
        Ctx::$page->add_block(new Block(
            "Hello!",
            DIV("Hello there $username, look at my snazzy custom theme!")
        );
    }
}