Widgets API
Widgets inherit from the WidgetBase base class. The base class automagically generates ajax calls and javascript functions for you.
A basic template of a Movim widget is as follows:
class MyWidget extends WidgetBase
{
function WidgetLoad()
{
$this->registerEvent('incomemessage', 'onIncomingMessage');
}
function onIncomingMessage($data)
{
RPC::call('movim_prepend',
'chatMessages',
RPC::cdata($data['message']));
}
function build()
{
?>
<div id="chatMessages">
</div>
<?
}
}
Note that the class constructor must not be shadowed. Instead the parent class provides a WidgetLoad() function that is called right at the end of the parent constructor.
Event handlers must be defined into WidgetLoad().
The build() function is called when the widget is being written onto the interface. That's typically where you should put your HTML code.
Events
XMPP triggers many different kinds of events that are run against all the loaded widgets. In order to process an event, you may register one or more handlers in your widget.
Handling events
An event handler is a public method that only takes one the paramter $data, which usually is an array that contains the data returned by the XMPP server.
Your handlers must be registered in WidgetLoad() with the method:
WidgetBase::registerEvent($eventType, $handler)
$handler is the name of the method as a string, and $eventType is the name of the event as a string.
Event types
The XMPP subsystem currently raises the following events:
| Event | Description |
|---|---|
| postdisconnected | Event that is triggered immediately after the account has been disconnected on the user's request. |
| serverdisconnect | The server has gone offline. |
| incomingemptybody | A message that comes in without body. This is typically a presence ping. |
| myvcardreceived | Your vcard has arrived. |
| vcardreceived | The user's vcard was received. $data contains the vcard as a base64-encoded string. |
| rosterreceived | The roster's list was received. $data is an array of groups and users. |
| incomeactive | The contact is currently looking at his message list. |
| incomecomposing | The contact is writing a message. |
| incomepaused | The contact paused the conversation. |
| incomemessage | A new message was received (contained in $data). |
| incomeoffline | A contact as gone offline. |
| incomeaway | A contact is now marked as away. |
| incomednd | A contact is now marked as do not disturb. |
| incomeonline | A contact is now online. |
| incomepresence | You've got a presence from a contact. |
| incomemypresence | You've got your presence. |
One additional event type is availble: allEvents. This type of event is a catchall that is always executed before the other event handlers in the widget.
The event handling process cannot be interrupted. All loaded widgets will be requested to run their eventhandlers, unless of course a fatal error occurs.
MovimRPC
Movim's javascript and PHP parts communicate through a custom xmlrpc protocol. It is implemented in the class RPC on the PHP side.
RPC exposes two static functions to the widget:
| Method | Description |
|---|---|
| RPC::call(funcname, …) | Calls the javascript function @emph{funcname} with the rest of arguments. |
| RPC::cdata(text) | Packs text into a cdata container. This is useful when passing through strings containing messy characters (like HTML). |
You can define your own javascript functions on a per-widget basis, or use one of the standard functions.
Standard javascript callbacks
You may define your own javascript callback functions and use them as appropriate. Alternatively, Movim comes with a standard set of javascript callbacks that allow simple operations on HTML elements (picked up by ID).
| Callback | Description |
|---|---|
| movim_append(target, string) | Appends string to the html element with ID target. |
| movim_prepend(target, string) | Prepends string to the html element with ID target. |
| movim_fill(target, string) | Fills string to the html element with ID target. |
| movim_drop() | Doesn't do anything. |
Ajax calls
Any method defined in your widget that starts with ajax will have a javascript ajax call automatically generated.
This ajax call can be explicitely called upon with the method:
WidgetBase::callAjax($funcname, ...)
$funcname is the name of the ajax function. The rest of paramters are passed to the ajax-called PHP function.
It is important to understand how the ajax calls work in Movim. Movim uses a custom-designed xmlrpc protocol to callback PHP functions directly. Therefore, making an ajax call is very similar to making a straight callback in PHP.
So for example if you have defined an ajax function
ajaxMyfunction($param)
you can call it with
$this->callAjax('ajaxMyfunction', "'myparam'")
Here is a complete example of a widget that implements an ajax call:
class MyWidget extends WidgetBase
{
function ajaxTest($param1, $param2)
{
RPC::call('movim_append', 'test',
RPC::cdata('<p>Test</p>'));
}
function build()
{
?>
<div id="test"></div>
<input type="button"
onclick="<? $this->callAjax(
'ajaxTest',
'"param1"',
'2');?>"/>
<?
}
}
Note that string parameters passed to the ajax method must be double-quoted. The reason for this is that javascript will remove the first set of quotes. Thus single-quoted parameters will be javascript objects.
The drawback of WidgetBase::callAjax() is that it prints the ajax call straight away. It is sometimes desirable to have it return the generated call. Another variant of the function exists that does this:
WidgetBase::genCallAjax($funcname, $callback, $target, ...)
Widget resource
Widgets can come along with their own resources, in particular their CSS and javascript.
The Widget base class includes two methods to ease the integration of custom javascript and css:
WidgetBase::addjs($jsfile) WidgetBase::addcss($cssfile)
The file paths given to these functions are relative to the widget's directory.
For resources, you can use the function:
WidgetBase::respath($file, $fspath = false)
This returns the URL to the specified file. The optional parameter $fspath will make the function return the file-system path rather than the URL to the file.
Session
Movim has moved away from using PHP’s sessions, which couldn’t provide an efficient locking and handling of Movim’s multi-threaded behaviour.
If you need to store data in session, use Movim’s Session class rather than PHP’s session. The class provides you the following methods.
| Method | Description |
|---|---|
| static Session::start($name) | Starts a session container named $name. Returns the session handle. |
| Session::get($varname) | Retrieves the value of $varname. |
| Session::set($varname, $value) | Sets the value of $varname to $value. |
| Session::remove($varname) | Deletes $varname from the session. |
| Session::delete_container() | Deletes the physical storage of the container. |
| static Session::dispose($name) | Deletes the container $name along with its physical storage. |
Cache
Movim uses caching heavily in order to minimise load-time. Depending on how your widget works, it might be convenient for you to cache parts of it, or even the whole of its html output, rather than regenerate it every time.
Movim’s cache is user-specific. So you don’t have to worry about your cached data being accessible to others.
Movim’s Cache provides the following methods:
| Method | Description |
|---|---|
| static Cache::create() | Gets a cache handle. |
| Cache::handle($key,…) | Retrieves or stores one or more objects depending on the way it’s called. If only $key is provided, handle() will return the corresponding cached object. If one or more extra objects are provided, they are cached under $key. |
| static Cache::c($key,…) | Shorthand for the two previous functions. |
Here is an example of how to use Cache in its two different forms:
$cache = Cache::create();
// Storing some object.
$cache->handle('foo', 'bar', 'baz');
// Retrieving data
list($bar, $baz) = $cache->handle('foo');
// Using the shorthand
Cache::c('foo', $bar);
// Usual cache routine
if(!$bar = Cache::c('foo')) {
Cache::c('foo', $bar);
}