Table of Contents
A plugin is made of one file named the same way. For example the Db plugin is in the file
Db.php. Plugin's file must always start with an uppercase letter.
Plugins are loaded at the beginning of a request, just after the configuration. The content of the file is free or it can be a class.
To build more complex plugins you can instead of a file create a folder named after your plugin.
Your php file goes into that folder and must be named Plugin.php.
When using folders, it is possible to add a sub folder named libraries which
will automatically be added to php's include_path.
A folder must be used when creating pluggable applications.
As said in the "Using plugins" section, plugins can have custom configuration. To retrieve this configuration a $config variable is automatically available. It contains the array used in the configuration.
Example 16.1. Retrieving plugin custom configuration
In the configuration file:
Atomik::set('plugins', array(
'MyPlugin' => array(
'name' => 'Peter'
)
));
In the plugin file:
echo 'hello ' . $config['name'];
For better application design it is advice to use a class to define your plugin. When loading a plugin, it will look for a class named like the plugin suffixed with “Plugin”.
If this class has a static start method, it will be called
with the plugin's custom configuration as argument, when the plugin is loaded.
Example 16.2. Plugin class
The plugin class for a plugin named Db
class DbPlugin
{
public static function start($config)
{
// $config['name'] == 'Peter'
}
}
The class can contain static methods that will be automatically registered as callback on events. These methods have to start by "on" followed by the event name without the double ":".
Example 16.3. Plugin class with event callback methods
class DbPlugin
{
public static onAtomikDispatchStart()
{
// listener for Atomik::Dispatch::Start
}
}
You can prevent automatic callback registration by returning false in the start method.
Pluggable applications are really simple to create. Create a normal plugin using a folder. Create your
Plugin.php file. Call Atomik::registerPluggableApplication() when
the plugin starts using the plugin name as first parameter (and eventually the pattern to trigger the application
as the second). Create standards Atomik folders inside your plugin folder: actions,
views, helpers and layouts
and code your application normally.
Example 16.4. Example of a Plugin.php file registering a pluggable application
class PluggAppPlugin
{
public static $config = array(
'route' => '/pluggapp/*'
);
public static start($config)
{
self::$config = array_merge(self::$config, $config);
Atomik::registerPluggableApplication('PluggAp', $config['route']);
}
}
A pluggable application can also have a file named Application.php at the root of the plugin
folder. This file act the same way as the bootstrap.php file. It will be called before
the pluggable application is dispatched.
If Atomik detects the Application.php file, a Plugin.php file is not
necessary and the pluggable application will automatically be registered.
A pluggable application behaves as a normal Atomik application and all features are available. The configuration
will be reseted before the dispatch occurs. These applications can provide their own config in their
Application.php file like their own routes, default action... The pre_dispatch.php
and post_dispatch.php files can also be used.
Note that every url will be relative to the pluggable application root. That is to say you do not have to care of the route used to trigger your application. For this to work properly, read carefully the next section.
Atomik::registerPluggableApplication() as more options which are described in the
API reference.
When using the default .htaccess file, plugins can have an assets folder which
is accessible from the Web. Of course, to use this folder, the plugin must come as a folder.
You can use Atomik::asset() like with a normal application. However in the case of plugins, asset's
filename will be prepended with a template defined in “atomik/plugin_assets_tpl”.
The default is “app/plugins/%s/assets”. The “%s” sign will be replaced with the plugin name.
Example 16.5. Using Atomik::asset()
echo Atomik::asset('css/styles.css');
echo Atomik::pluginAsset('MyPlugin', 'css/styles.css');
// will output app/plugins/MyPlugin/assets/css/styles.css
Atomik::set('atomik/plugin_assets_tpl', 'plugins/%s/assets');
echo Atomik::asset('css/styles.css');
echo Atomik::pluginAsset('MyPlugin', 'css/styles.css');
// will output plugins/MyPlugin/assets/css/styles.css
Once you created your plugin, you might want to share it. The Atomik's website feature a plugin repository where anyone can submit their creations. To ease plugins distribution, you can bundle with your plugin a Manifest.xml file. It contains information about your plugin like name, description, author...
The file is very simple. You can get the XMLSchema at http://www.atomikframework.com/docs/manifest/manifest.xsd. The file's xml namespace is http://www.atomikframework.com/manifest. Below are all available tags:
<manifest xmlns="http://www.atomikframework.com/manifest"> <author> <name></name> <email></email> <website></website> </author> <name><!-- plugin name without spaces or special characters (eg. MyPlugin) --></name> <displayName><!-- plugin name that will be displayed (eg. My Plugin) --></displayName> <version><!-- version (same format as php version number) --></version> <category><!-- the category name --></category> <minAtomikVersion><!-- the minimum Atomik version that is needed --></minAtomikVersion> <description><!-- plugin's short description (in list pages) --></description> <longDescription><!-- plugin's long description --></longDescription> <link><!-- link to the plugin website --></link> <directory><!-- directory inside the archive where the plugin's source code is located --></directory> <license><!-- license name --></license> <dependencies> <!-- list of dependencies (these plugin should also be registered in the atomik plugins repository --> <dependency name="pluginName" /> </dependencies> </manifest>
The “directory” tag is special and used by the distribution builder. When you're creating a package for your plugin, you could put the source files into a specific folder. For the distribution builder to work, it's needed to know where the sources are. This is the purpose of the “directory” tag. It must be relative to the root of your archive and specify which folder contains the files to be extracted to the plugins directory. Leave it blank for the root, which is the default value.
You can create a plugin file and the associated manifest online at http://www.atomikframework.com/plugins/create. To submit your plugin, browse to http://www.atomikframework.com/plugins/submit
It is of course possible to load plugins at runtime. Atomik provides a bunch of loading methods so it's simpler for plugins to load dependency plugins or to create custom plugins.
The most common method is Atomik::loadPlugin() which will load a plugin and use
the user plugin's configuration (from the plugins key) if one is available.
If a plugin is not available, loading it will throw an exception. To prevent that you can use
Atomik::loadPluginIfAvailable().
You can also load plugins by specifying custom configuration. This is done using
Atomik::loadCustomPlugin(). As it's name imply, this method can also be used to load
custom plugins, which can be named differently, follow other development guidelines...
Example 16.7. Loading a plugin at runtime with some configuration
Atomik::loadCustomPlugin('Db', array('dbname' => 'test'));
Example 16.8. More advance use of Atomik::loadCustomPlugin()
// load plugins from a custom directory
Atomik::loadCustomPlugin('MyPlugin', array(), array('dirs' => '/custom/plugins/directory'));
// using a custom plugin class name (in this case the class name will be MyPluginCustomPlugin)
Atomik::loadCustomPlugin('MyPlugin', array(), array('classNameTemplate' => '%CustomPlugin'));
// do not call the start() method when loading plugins
Atomik::loadCustomPlugin('MyPlugin', array(), array('callStart' => false));
Atomik::loadCustomPluginIfAvailable() is also available.
You can check if a plugin is already loaded using Atomik::isPluginLoaded() or if it's
available using Atomik::isPluginAvailable().
Finally, you can retreive all loaded plugins using Atomik::getLoadedPlugins().