Plugins can do just about anything. Create custom cron tasks, listen for events, create pages, create widgets, extend the API, etc., etc. If it's not a Module or a Payment Gateway, it's a plugin. So let's dig in.
Getting Started
Plugins follow the same MVC design pattern that Blesta adheres to. The plugin system is provided as a feature of the minPHP framework, Blesta simply defines the naming convention. For the purpose of this manual, the plugin name we'll refer to is my_plugin. Your plugin name will, of course, differ.
Info |
---|
title | Plugin names must be unique |
---|
|
A user will not be able to install two plugins with the same name, so try to use descriptive and non-generic terms for your plugin name. |
File Structure
Plugins are fully contained within their named plugin directory and placed in the /plugins/ directory. Below is the minimum required file structure for a plugin:
- /plugins/
- my_plugin/
- controllers/
- models/
- views/
- language/
- my_plugin_controller.php
- my_plugin_model.php
- my_plugin_plugin.php
- config.json (for version 3.1+)
Tip |
---|
title | Use the Extension Generator |
---|
|
As of Blesta 4.12 we've included a useful tool to help developers get started and save time. Blesta's Extension Generator can be used to generate many the files necessary for a plugin and will create basic code with an option to include comments to help you understand each part of the code. |
Getting Started
Plugins follow the same MVC design pattern that Blesta adheres to. The plugin system is provided as a feature of the minPHP framework, Blesta simply defines the naming convention. For the purpose of this manual, the plugin name we'll refer to is my_plgn. Your plugin name will, of course, differ.
Info |
---|
title | Plugin names must be unique |
---|
|
A user will not be able to install two plugins with the same name, so try to use descriptive and non-generic terms for your plugin name. |
File Structure
Plugins are fully contained within their named plugin directory and placed in the /plugins/ directory. Below is the minimum required file structure for a plugin:
- /plugins/
- my_plgn/
- controllers/
- models/
- views/
- language/
- my_plgn_controller.php
- my_plgn_model.php
- my_plgn_plugin.php
- config.json (for version 3.1+)
my_plgnmy_plugin_controller.php is the plugin's parent controller. This controller can be used to add supporting methods for the other controllers to inherit. Similarly, my_pluginplgn_model.php is the plugin's parent model and can be used to add supporting methods for the other models to inherit.
Because plugins inherit from the application stack their views default to the view directory defined for application. For this reason, you should always declare the view directory for the views within your plugin. The example below requires that you place all views (.pdt files) into /plugins/my_pluginplgn/views/default/.
Code Block |
---|
language | php |
---|
firstline | 1 |
---|
title | /plugins/my_pluginplgn/my_pluginplgn_controller.php | firstline |
---|
1 | linenumbers | true |
---|
|
<?php
class MyPluginControllerMyPlgnController extends AppController {
public function preAction() {
// Set the view parent::preAction();
// Override default view directorydirectory to the default core view directory so that AppController preAction code uses the appropriate
$this->view->view = "default";// directory for the structure file
$this->structure->view = "default";
}
}
?>>setDefaultView(APPDIR);
parent::preAction();
// Override default view directory with that of the plugin
$this->view->view = "default";
}
}
?> |
Finally, my_plgnFinally, my_plugin_plugin.php is a special class that must extend the Plugin class of /components/plugins/lib/plugin.php. This class is used for installing, upgrading, uninstalling, and branding the plugin in conjunction with the config.json file.
...
Code Block |
---|
language | php |
---|
title | /plugins/my_pluginplgn/my_pluginplgn_plugin.php |
---|
linenumbers | true |
---|
|
<?php
class MyPluginPluginMyPlgnPlugin extends Plugin {
...
public function install($plugin_id) {
#
# TODO: Place installation logic here
#
}
}
?> |
...
Code Block |
---|
language | php |
---|
title | /plugins/my_pluginplgn/my_pluginplgn_plugin.php |
---|
linenumbers | true |
---|
|
<?php
class MyPluginPluginMyPlgnPlugin extends Plugin {
...
public function uninstall($plugin_id, $last_instance) {
#
# TODO: Place uninstallation logic here
#
}
}
?> |
...
Code Block |
---|
language | php |
---|
title | /plugins/my_pluginplgn/my_pluginplgn_plugin.php |
---|
linenumbers | true |
---|
|
<?php
class MyPluginPluginMyPlgnPlugin extends Plugin {
...
public function upgrade($current_version, $plugin_id) {
#
# TODO: Place upgrade logic here
#
}
}
?> |
...
Code Block |
---|
language | php |
---|
title | /plugins/my_pluginplgn/my_pluginplgn_plugin.php |
---|
linenumbers | true |
---|
|
<?php
class MyPluginPluginMyPlgnPlugin extends Plugin {
public function __construct() {
Loader::loadComponents($this, array("Input"));
}
...
public function upgrade($current_version, $plugin_id) {
// Ensure new version is greater than installed version
if (version_compare($this->version, $current_version) < 0) {
$this->Input->setErrors(array([
'version' => array([
'invalid' => "Downgrades are not allowed."
)]
]);
return;
}
}
}
?> |
Branding The Plugin
For version 3.1+ simply create a config.json file and include it in the constructor of your plugin.
Code Block |
---|
language | javascript |
---|
title | /plugins/my_pluginplgn/config.json |
---|
|
{
"version": "1.0.0",
"name": "My Plugin Name",
"description": "A plugin like no other!",
"authors": [
{
"name": "Phillips Data, Inc.",
"url": "http://www.blesta.com"
}
]
} |
...
Code Block |
---|
language | php |
---|
title | /plugins/my_pluginplgn/my_pluginplgn_plugin.php |
---|
linenumbers | true |
---|
|
<?php
class MyPluginPluginMyPlgnPlugin extends Plugin {
public function __construct() {
$this->loadConfig(dirname(__FILE__) . DS . "config.json");
}
}
?> |
For version 3.0, you must define all of the branding details through methods.
Expand |
---|
title | Show plugin branding in 3.0 |
---|
|
All that any plugin truly requires is branding. These options come from three methods: getName(), getVersion(), getAuthors(). Code Block |
---|
language | php |
---|
title | /plugins/my_pluginplgn/my_pluginplgn_plugin.php |
---|
linenumbers | true |
---|
| <?php
class MyPluginPluginMyPlgnPlugin extends Plugin {
...
public function getName() {
return "MyPlugin";
}
public function getVersion() {
return "1.0.0";
}
public function getAuthors() {
return array([
array([
'name' => "MyCompany",
'url' => "http://www.mycompanyplugindevelopment.com"
)]
)];
}
}
?> |
The getAuthors() method requires a multi-dimensional array, so you can specify multiple authors if needed. Lastly, each plugin needs a logo. By default these are loaded from /plugins/my_pluginplgn/views/default/images/logo.png. You can override the location of the logo file by implementing the getLogo() method in your plugin. Code Block |
---|
language | php |
---|
title | /plugins/my_plgn/my_plgn_plugin.php |
---|
linenumbers | true |
---|
| <?php
class | MyPluginPluginMyPlgnPlugin extends Plugin {
|
public function getLogo() {
| return "views" . DS . "default" . DS . "images" . DS . "some_other_logo.png";
}
}
?> |
|
Info |
---|
title | Internationalize it! |
---|
|
Use the Language library to help internationalize your plugin. Just create a language directory in your plugin, then a directory for each language (i.e. /plugins/my_pluginplgn/language/en_us/) and place your language files in there. See Translating Blesta for how to load, format, and use language definitions. |
...
Code Block |
---|
language | php |
---|
title | /plugins/my_pluginplgn/controllers/admin_manage_plugin.php |
---|
linenumbers | true |
---|
plugin.php | linenumbers | true |
---|
|
<?php
class AdminManagePlugin extends AppController {
/**
* Performs necessary initialization
*/
private function init()
{
// Set the view to render for all actions under this controller
$this->view->setView(null, 'MyPlgn.default');
}<?php
class AdminManagePlugin extends AppController {
public function index() {
$this->init();
$var1 = "hello";
$var2 = "world";
return $this->partial("admin_manage_plugin", compact("var1", "var2"));
}
public function foo() {
$this->init();
return $this->partial("admin_manage_plugin_foo");
}
}
?> |
...
Code Block |
---|
language | php |
---|
title | /plugins/my_pluginplgn/views/default/admin_manage_plugin.pdt |
---|
|
<a href="<?php echo $this->Html->safe($this->base_uri . "settings/company/plugins/manage/" . $this->Html->_($plugin_id, true) . "/?controller=admin_manage_plugin&action=foo");?>">Link to other action</a> |
...
Plugins that need to perform certain tasks automatically at either set intervals are certain times of the day can register cron tasks. See Plugin Cron Tasks for how to register cron tasks.