Plugin Manager
The Plugin Manager module provides a simple user interface and standardized procedures for
- installing,
- uninstalling,
- updating,
- managing and
- integrating
plugins in Admidio.
With the Plugin Manager it is now also possible to easily and quickly integrate your own custom overview plugins.
A Basic “Overview Plugin Example” can by found here: Admidio Overview Plugin Example
Make your plugin compatible with the Plugin Manager (Admidio 5)
To make your plugin compatible with the Plugin Manager certain requirements must first be met. These include:
- A consistent folder structure
- A JSON configuration file
- A main plugin class extending the PluginAbstract class
- A preference presenter class with a single FormPresenter element or with multiple FormPresenter elements if your plugin preferences should be accessable via Admidios preferences panel
Naming conventions
When using the new Plugin Manager, the following naming conventions must be observed:
- For better readability file and folder names containing multiple words should follow kebab-case (dash separated) notation.
- All folder and file names containing multiple words and are placed inside the classes folder should follow UpperCamelCase (PascalCase) notation.
- No plugin file defining a class may contain delimiters such as “-” or “_” especially if it will be used via a class import.
Folder structure
The basic folder structure of any plugin is shown below using the “Birthday” overview plugin as an example:
classes folder
Main plugin class
The main plugin class (e.g.: Birthday) must be placed directly in the classes folder.
Presenter classes
Plugin-specific classes
Inside the Presenter folder all necessary PagePresenter classes of the plugin are placed. These should be similar to the module-specific PagePresenter classes.
Plugin preferences class
Single FormPresenter element
If the plugin provides preferences there should be a class “[PluginName]PreferencesPresenter”. This class contains a single static preference method following the naming conventions of Admidio's Preferences class.
Below is an example snippet of the createBirthdayForm preference method from the “Birthday” overview plugin:
public static function createBirthdayForm(Smarty $smarty): string { global $gL10n, $gCurrentSession; $pluginBirthday = Birthday::getInstance(); $formValues = $pluginBirthday::getPluginConfig(); $formBirthday = new FormPresenter( 'adm_preferences_form_birthday', $pluginBirthday::getPluginPath() . '/templates/preferences.plugin.birthday.tpl', SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/preferences.php', array('mode' => 'save', 'panel' => 'birthday')), null, array('class' => 'form-preferences') ); $selectBoxEntries = array( '0' => $gL10n->get('SYS_DISABLED'), '1' => $gL10n->get('SYS_ENABLED'), '2' => $gL10n->get('ORG_ONLY_FOR_REGISTERED_USER') ); $formBirthday->addSelectBox( 'birthday_plugin_enabled', Language::translateIfTranslationStrId($formValues['birthday_plugin_enabled']['name']), $selectBoxEntries, array( 'defaultValue' => $formValues['birthday_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['birthday_plugin_enabled']['description'] ) ); $formBirthday->addCheckbox( 'birthday_show_names_extern', Language::translateIfTranslationStrId($formValues['birthday_show_names_extern']['name']), $formValues['birthday_show_names_extern']['value'], array('helpTextId' => $formValues['birthday_show_names_extern']['description']) ); [...] $formBirthday->addSubmitButton( 'adm_button_save_birthday', $gL10n->get('SYS_SAVE'), array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') ); $formBirthday->addToSmarty($smarty); $gCurrentSession->addFormObject($formBirthday); return $smarty->fetch($pluginBirthday::getPluginPath() . '/templates/preferences.plugin.birthday.tpl'); }
Multiple FormPresenter elements
With Admidio 5 the preference page has been redesigned. It is now possible to display multiple “subcards” on one preference panel. To use this feature from a plugin the hasSubcards configuration flag must be set to true.
In your PluginPreferencePresenter class you can now define multiple FormPresenter elements and add different preferences to each form. The first FormPresenter can now be assigned to the smarty variable like the following example shows:
public static function createBirthdayForm(Smarty $smarty): string { [...] $formBirthday = new FormPresenter( 'adm_preferences_form_birthday', $pluginBirthday::getPluginPath() . '/templates/preferences.plugin.birthday.tpl', SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/preferences.php', array('mode' => 'save', 'panel' => 'birthday')), null, array('class' => 'form-preferences') ); $selectBoxEntries = array( '0' => $gL10n->get('SYS_DISABLED'), '1' => $gL10n->get('SYS_ENABLED'), '2' => $gL10n->get('ORG_ONLY_FOR_REGISTERED_USER') ); $formBirthday->addSelectBox( 'birthday_plugin_enabled', Language::translateIfTranslationStrId($formValues['birthday_plugin_enabled']['name']), $selectBoxEntries, array('defaultValue' => $formValues['birthday_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['birthday_plugin_enabled']['description']) ); [...] $formBirthday->addSubmitButton( 'adm_button_save_birthday', $gL10n->get('SYS_SAVE'), array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') ); $formBirthday->addToSmarty($smarty); $gCurrentSession->addFormObject($formBirthday); [...]
Now you can define a new FormPresenter for the second “card”:
$formBirthday2= new FormPresenter( 'adm_preferences_form_birthday_2', $pluginBirthday::getPluginPath() . '/templates/preferences.plugin.birthday.2.tpl', SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/preferences.php', array('mode' => 'save', 'panel' => 'birthday')), null, array('class' => 'form-preferences') ); [...] $formBirthday2->addSubmitButton( 'adm_button_save_birthday_2', $gL10n->get('SYS_SAVE'), array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') ); [...]
This form cannot be added to smarty with the addToSmarty method because this would override all values set by the previous form element. Therefore a new method appendToSmarty was implemented in the FormPresenter class (currently only available in the plugin-manager branch on GitHub). Use this method to add the second form to the smarty variable:
[...] $formBirthday2->appendToSmarty($smarty); $gCurrentSession->addFormObject($formBirthday2); [..]
You can add as many forms as you like using this method.
When all forms are added to smarty you can use a “wrapper template” to load the form specific template files on one page. For this wrapper template you can add a smarty variable containing informations you want to show. In the following example multiple cards should be used for displaying the different forms:
[...] //assign card titles, icons and corresponding template files $cards = array( array('title' => $birthdayName, 'icon' => $birthdayIcon, 'templateFile' => $birthdayPath . '/templates/preferences.plugin.birthday.tpl'), array('title' => $birthdayName2, 'icon' => $birthdayIcon2, 'templateFile' => $birthdayPath2 . '/templates/preferences.plugin.birthday.2.tpl') ); $smarty->assign('cards', $cards); return $smarty->fetch($birthdayPath . '/templates/preferences.birthday.cards.tpl'); }
The corresponding wrapper template is shown below:
{foreach $cards as $index => $card} <div class="card admidio-tabbed-field-group"> <div class="card-header"><i class="bi {$card.icon} me-1"></i>{$card.title}</div> <div class="card-body"> {include file=$card.templateFile dataIndex=$index} </div> </div> {/foreach}
This template creates cards for each form element defined in the $cards variable and loads the corresponding template file. It is necessary to pass the index of the zero-based $cards array to the corresponding template file to retrieve the correct smarty data that is now also available as a zero-based array for each form variable. These are:
- formType,
- attributes,
- elements,
- javascript and
- hasRequiredFields.
This following example shows a possible implementation of the first form (so with index 0):
<form {foreach $attributes[$dataIndex] as $attribute} {$attribute@key}="{$attribute}" {/foreach}> {include 'sys-template-parts/form.input.tpl' data=$elements[$dataIndex]['adm_csrf_token']} {include 'sys-template-parts/form.select.tpl' data=$elements[$dataIndex]['birthday_plugin_enabled']} {include 'sys-template-parts/form.checkbox.tpl' data=$elements[$dataIndex]['birthday_show_names_extern']} {include 'sys-template-parts/form.select.tpl' data=$elements[$dataIndex]['birthday_show_names']} {include 'sys-template-parts/form.checkbox.tpl' data=$elements[$dataIndex]['birthday_show_age']} {include 'sys-template-parts/form.input.tpl' data=$elements[$dataIndex]['birthday_show_age_salutation']} {include 'sys-template-parts/form.checkbox.tpl' data=$elements[$dataIndex]['birthday_show_notice_none']} {include 'sys-template-parts/form.input.tpl' data=$elements[$dataIndex]['birthday_show_past']} {include 'sys-template-parts/form.input.tpl' data=$elements[$dataIndex]['birthday_show_future']} {include 'sys-template-parts/form.input.tpl' data=$elements[$dataIndex]['birthday_show_display_limit']} {include 'sys-template-parts/form.select.tpl' data=$elements[$dataIndex]['birthday_show_email_extern']} {include 'sys-template-parts/form.select.tpl' data=$elements[$dataIndex]['birthday_roles_view_plugin']} {include 'sys-template-parts/form.select.tpl' data=$elements[$dataIndex]['birthday_roles_sql']} {include 'sys-template-parts/form.select.tpl' data=$elements[$dataIndex]['birthday_sort_sql']} {include 'sys-template-parts/form.button.tpl' data=$elements[$dataIndex]['adm_button_save_birthday']} <div class="form-alert" style="display: none;"> </div> </form> {$javascript[$dataIndex]}
This makes it possible to show seperate forms on the same page. There are no limits to the display options whether as cards (as in the example), tabs, or accordions. With this approach each available Bootstrap/HTML display is possible through the smarty templates.
Entity, Service and ValueObjects classes
If the plugin has specific Entity, Service, or ValueObjects classes these should be placed in the corresponding subfolders as is done with the Admidio modules.
db_scripts folder
This folder is optional and is used to place plugin-specific database scripts used when installing (db-install.sql) or uninstalling (db-uninstall.sql) the plugin.
In addition to database scripts update scripts (e.g.: update_1_0.xml) for the plugin can be placed in this folder. These should be structured like the update scripts used by Admidio to update to a new version.
Similar to Admidio's update scripts it is possible to call plugin-specific update steps. To implement these steps a final class named UpdateStepsCode must be present in the folder “[PluginName]\classes\Service\”.
The class implementation should look like this:
final class UpdateStepsCode { /** * @var Database */ private static Database $db; /** * Set the database * @param Database $database The database instance */ public static function setDatabase(Database $database) { self::$db = $database; } /** * @throws Exception */ public static function /*[method name used in update_x_x.xml]*/() { [...] } }
languages folder
This folder contains the plugin-specific translation files.
templates folder
To move away from the deprecated HtmlPage and HtmlTable classes plugins should exclusively use the Smarty template engine with files stored in this folder.
Root plugin folder
Main plugin file
Inside the root plugin folder a main plugin file is required. This file can contain plugin-specific logic (similar to Admidio’s module entry files) or simply initialize the plugin class as in the following example:
<?php use Birthday\classes\Birthday; /** *********************************************************************************************** * Birthday * * The plugin lists all users who have birthday in a defined timespan. * * @copyright The Admidio Team * @see https://www.admidio.org/ * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2.0 only *********************************************************************************************** */ try { require_once(__DIR__ . '/../../system/common.php'); $pluginBirthday = Birthday::getInstance(); $pluginBirthday->doRender(isset($page) ? $page : null); } catch (Throwable $e) { echo $e->getMessage(); }
Plugin configuration file
Each plugin must provide a JSON configuration file containing basic plugin information and configuration (see: Configuration file).
Configuration file
Each plugin has to provide a JSON configuration file. The following table gives an overview of all keys currently available:
| Key: | Mandatory: | Description: |
|---|---|---|
| “name” | X | Defines the plugin name (can be a translation ID or plain text). |
| “description” | A short description of the plugin shown on the Plugin Manager overview (can be a translation ID or plain text). | |
| “version” | X | The current version of the plugin. |
| “author” | The author of the plugin. | |
| “url” | A URL to a wiki page or a project page. | |
| “icon” | The icon displayed in the Admidio sidebar and on the Plugin Manager overview. | |
| “mainFile” | The filename of the main plugin entry point. If not set “index.php” or “PluginName.php” is assumed. | |
| “overviewPlugin” | This optional flag is used to determinate whether the plugin should be installed as an overview plugin. | |
| “autoload” | (X) | An object containing another object “psr-4” which contains the psr4 autoload mapping(s) of the plugin class(es). |
| “preferencesFile” | The filename of the preferences entry point for the plugin settings. If this key is set there is no integration of the plugin settings into the Admidio Preferences Page. | |
| “hasSubcards” | This optional flag is used to determinate whether a plugins preference page contains multiple “cards” to display (for CSS styling purposes only). | |
| “dependencies” | (X) | An array of all dependencies the plugin needs to work properly. If this is not set the Plugin Manager cannot detect whether the plugin can be installed properly. |
| “defaultConfig” | (X) | An object containing all configuration parameters used by the plugin. Every parameter should contain a “name”, “description”, “type” and “value” key. |
The following example shows the structure based on the “Birthday” overview plugin:
{
"name": "PLG_BIRTHDAY_PLUGIN_NAME",
"description": "PLG_BIRTHDAY_PLUGIN_DESCRIPTION",
"version": "1.0.0",
"author": "Admidio Team",
"url": "https://www.admidio.org",
"icon": "bi-cake2",
"mainFile": "index.php",
"overviewPlugin": true,
"autoload": {
"psr-4": {
"Birthday\\classes\\": "classes/"
}
},
"dependencies": [
"Admidio\\Infrastructure\\Plugins\\Overview",
"Admidio\\Infrastructure\\Plugins\\PluginAbstract",
"Admidio\\Infrastructure\\Utils\\SecurityUtils",
"Admidio\\Roles\\Service\\RolesService"
],
"defaultConfig": {
"birthday_plugin_enabled": {
"name": "ORG_ACCESS_TO_PLUGIN",
"description": "ORG_ACCESS_TO_PLUGIN_DESC",
"type": "integer",
"value" : 1
},
"birthday_overview_sequence": {
"type": "integer",
"value" : 2
},
"birthday_show_names_extern": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_EXTERN",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_EXTERN_DESC",
"type": "boolean",
"value" : false
},
"birthday_show_names": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_DESC",
"type": "integer",
"value" : 0
},
"birthday_show_age": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE_DESC",
"type": "boolean",
"value" : false
},
"birthday_show_age_salutation": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE_SALUTATION",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE_SALUTATION_DESC",
"type": "integer",
"value" : 18
},
"birthday_show_notice_none": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_NOTICE_NONE",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_NOTICE_NONE_DESC",
"type": "boolean",
"value" : true
},
"birthday_show_past": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_PAST",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_PAST_DESC",
"type": "integer",
"value" : 1
},
"birthday_show_future": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_FUTURE",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_FUTURE_DESC",
"type": "integer",
"value" : 2
},
"birthday_show_display_limit": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_DISPLAY_LIMIT",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_DISPLAY_LIMIT_DESC",
"type": "integer",
"value" : 200
},
"birthday_show_email_extern": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_EMAIL_EXTERN",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_EMAIL_EXTERN_DESC",
"type": "integer",
"value" : 0
},
"birthday_roles_view_plugin": {
"name": "PLG_BIRTHDAY_PREFERENCES_ROLES_VIEW_PLUGIN",
"description": "PLG_BIRTHDAY_PREFERENCES_ROLES_VIEW_PLUGIN_DESC",
"type": "array",
"value" : ["All"]
},
"birthday_roles_sql": {
"name": "PLG_BIRTHDAY_PREFERENCES_ROLES_SQL",
"description": "PLG_BIRTHDAY_PREFERENCES_ROLES_SQL_DESC",
"type": "array",
"value" : ["All"]
},
"birthday_sort_sql": {
"name": "PLG_BIRTHDAY_PREFERENCES_SORT_SQL",
"description": "PLG_BIRTHDAY_PREFERENCES_SORT_SQL_DESC",
"type": "string",
"value" : "DESC"
}
}
} ],
"defaultConfig": {
"birthday_plugin_enabled": {
"name": "ORG_ACCESS_TO_PLUGIN",
"description": "ORG_ACCESS_TO_PLUGIN_DESC",
"type": "integer",
"value": 1
},
"birthday_show_names_extern": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_EXTERN",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_EXTERN_DESC",
"type": "boolean",
"value": false
},
"birthday_show_names": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_DESC",
"type": "integer",
"value": 0
},
"birthday_show_age": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE_DESC",
"type": "boolean",
"value": false
},
"birthday_show_age_salutation": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE_SALUTATION",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE_SALUTATION_DESC",
"type": "integer",
"value": 18
},
"birthday_show_notice_none": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_NOTICE_NONE",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_NOTICE_NONE_DESC",
"type": "boolean",
"value": true
},
"birthday_show_past": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_PAST",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_PAST_DESC",
"type": "integer",
"value": 1
},
"birthday_show_future": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_FUTURE",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_FUTURE_DESC",
"type": "integer",
"value": 2
},
"birthday_show_display_limit": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_DISPLAY_LIMIT",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_DISPLAY_LIMIT_DESC",
"type": "integer",
"value": 200
},
"birthday_show_email_extern": {
"name": "PLG_BIRTHDAY_PREFERENCES_SHOW_EMAIL_EXTERN",
"description": "PLG_BIRTHDAY_PREFERENCES_SHOW_EMAIL_EXTERN_DESC",
"type": "integer",
"value": 0
},
"birthday_roles_view_plugin": {
"name": "PLG_BIRTHDAY_PREFERENCES_ROLES_VIEW_PLUGIN",
"description": "PLG_BIRTHDAY_PREFERENCES_ROLES_VIEW_PLUGIN_DESC",
"type": "array",
"value": ["All"]
},
"birthday_roles_sql": {
"name": "PLG_BIRTHDAY_PREFERENCES_ROLES_SQL",
"description": "PLG_BIRTHDAY_PREFERENCES_ROLES_SQL_DESC",
"type": "array",
"value": ["All"]
},
"birthday_sort_sql": {
"name": "PLG_BIRTHDAY_PREFERENCES_SORT_SQL",
"description": "PLG_BIRTHDAY_PREFERENCES_SORT_SQL_DESC",
"type": "string",
"value": "DESC"
}
}
}
Plugin class
The Plugin class extends the basic functionality provided by the abstract class PluginAbstract and implements the doRender method.
If there is nothing to render the doRender method can just return true:
namespace Birthday\classes; use Admidio\Infrastructure\Plugins\PluginAbstract; use Admidio\UI\Presenter\PagePresenter; class Birthday extends PluginAbstract { public static function doRender(?PagePresenter $page = null) : bool { return true; } }
In its simplest implementation for displaying something the doRender method can just call the PagePresenter show method:
namespace Birthday\classes; use Admidio\Infrastructure\Plugins\PluginAbstract; use Admidio\UI\Presenter\PagePresenter; class Birthday extends PluginAbstract { public static function doRender(?PagePresenter $page = null) : bool { if (!isset($page)) { throw new Exception("The page parameter must be set."); } $page->show(); return true; } }
All methods provided by PluginAbstract can be overridden in this plugin class and adapted to the plugin's needs. The following code shows an example override of the getPluginConfig() method in the “Birthday” overview plugin implementation:
public static function getPluginConfig() : array { // get the plugin config from the parent class $config = parent::getPluginConfig(); // if the key equals 'birthday_roles_view_plugin' and the value is still the default value, retrieve the categories from the database if (array_key_exists('birthday_roles_view_plugin', $config) && $config['birthday_roles_view_plugin']['value'] === self::$defaultConfig['birthday_roles_view_plugin']['value']) { $config['birthday_roles_view_plugin']['value'] = self::getAvailableRoles(1, true); } if (array_key_exists('birthday_roles_sql', $config) && $config['birthday_roles_sql']['value'] === self::$defaultConfig['birthday_roles_sql']['value']) { $config['birthday_roles_sql']['value'] = self::getAvailableRoles(1, true); } return $config; }
PluginAbstract class
methods documentation
The PluginAbstract class is the base class for all plugins usable with the Plugin Manager.
Provides:
- installation / uninstallation
- updates
- configuration handling
- dependency checks
- autoload registration
- visibility + activation control
All custom plugins should extend this class.
Singleton / Basic Handling
| Method | Description | Return |
|---|---|---|
| getInstance() | Returns the singleton instance of the plugin class | PluginAbstract |
| __construct() | Protected constructor (singleton pattern) | void |
| __clone() | Prevents cloning of the singleton | void |
| __wakeup() | Prevents unserializing | void |
Menu Integration / Preferences
| Method | Description | Return |
|---|---|---|
| addMenuEntry() | Adds the plugin menu entry to the database | void |
| removeMenuEntry() | Removes the plugin menu entry from the database | void |
| initPreferencePanelCallback() | Initializes plugin preference panel integration | void |
Metadata / Identity
| Method | Description | Return |
|---|---|---|
| getName() | Returns the plugin name | string |
| getIcon() | Returns the plugin icon from metadata | string |
| getVersion() | Returns the plugin version | string |
| getMetadata() | Returns the complete metadata definition | array |
| getDependencies() | Returns declared dependencies | array |
| getSupportedLanguages() | Returns supported languages | array |
Static Files
| Method | Description | Return |
|---|---|---|
| getStaticFiles(?string $type = null, string $path = '') | Returns plugin static files (css/js/images/etc.) | array |
Example:
Plugin::getStaticFiles('css');
Configuration & Component Information
| Method | Description | Return |
|---|---|---|
| getPluginConfigValues() | Returns stored config values only (key ⇒ value) | array |
| getPluginConfig() | Returns merged configuration (defaults + DB) | array |
| getPluginPath() | Absolute filesystem path | string |
| getComponentId() | Database component ID | int |
| getComponentName() | Plugin folder name | string |
| getPluginSequence() | Overview sorting sequence | int |
Dependency Handling
| Method | Description | Return |
|---|---|---|
| checkDependencies() | Verifies all dependencies are available | bool |
Internal helper:
private static function findAdmidioClass(string $shortName): ?string
Installation State / Visibility
| Method | Description | Return |
|---|---|---|
| isInstalled() | Plugin exists in database | bool |
| isActivated() | Installed and activated | bool |
| isVisible() | Visible depending on config and login state | bool |
| isOverviewPlugin() | Registered as overview plugin | bool |
| isAdmidioPlugin() | Built-in overview plugin | bool |
| isUpdateAvailable() | Installed version differs from metadata | bool |
Autoloading
| Method | Description | Return |
|---|---|---|
| doClassAutoload(string $class) | Registers PSR-4 autoload mappings | bool |
Example metadata:
"autoload": {
"psr-4": {
"Vendor\\Plugin\\": "classes/"
}
}
Lifecycle Methods
doInstall(bool $addMenuEntry = true)
Installs the plugin.
Steps:
- store default config values
- execute install SQL scripts
- register component
- run update steps
- set version
- optionally create menu entry
Returns: bool
doUninstall(bool $removeMenuEntry = true, array $options = array())
Removes the plugin completely.
Steps:
- execute uninstall SQL scripts
- delete config values
- remove menu entries
- delete component
- reset version
Returns: bool
doUpdate()
Updates an installed plugin.
Steps:
- add missing config defaults
- run update classes
- update stored version
Returns: bool
initParams(array $params = array())
Optional initialization hook for plugins.
Returns: bool
Internal Helpers (private)
| Method | Description |
|---|---|
| readPluginMetadata() | Loads and parses metadata file |
| getClassNameFromFile(string $file) | Extracts class name from PHP file |
| toggleForeignKeyChecks(bool $enable) | Enables/disables MySQL foreign key checks during install/uninstall |