|
| 1 | +--- |
| 2 | +name: addon-lifecycle |
| 3 | +description: Implements doEnable/doDisable lifecycle methods following the pattern in src/Plugin.php. Handles get_module_settings(), myadmin_log(), function_requirements(), vps_get_password(), run_event('parse_service_extra'), and admin email via \MyAdmin\Mail()->adminMail(). Use when user says 'add enable logic', 'implement disable', 'provision addon', or works on activation/deactivation. Do NOT use for hook registration or AddonHandler setup. |
| 4 | +--- |
| 5 | +# Addon Lifecycle |
| 6 | + |
| 7 | +## Critical |
| 8 | + |
| 9 | +- Always call `require_once __DIR__.'/../../../../include/licenses/license.functions.inc.php'` **before** any license or activation functions in both `doEnable` and `doDisable`. |
| 10 | +- Always resolve the service ID and customer ID through `$settings['PREFIX']` — never hardcode column names. |
| 11 | +- Call `myadmin_log()` immediately after `get_module_settings()` as the first observable action in both methods. |
| 12 | +- All external functions (`activate_*`, `deactivate_*`, `directadmin_get_best_type`) must be loaded via `function_requirements()`, not `require_once`. |
| 13 | + |
| 14 | +## Instructions |
| 15 | + |
| 16 | +1. **Declare the method signature** — both lifecycle methods share the same signature: |
| 17 | + ```php |
| 18 | + public static function doEnable(\ServiceHandler $serviceOrder, $repeatInvoiceId, $regexMatch = false) |
| 19 | + public static function doDisable(\ServiceHandler $serviceOrder, $repeatInvoiceId, $regexMatch = false) |
| 20 | + ``` |
| 21 | + Verify `$serviceOrder` is typed as `\ServiceHandler` before proceeding. |
| 22 | + |
| 23 | +2. **Extract service info and settings** — always the first two lines of the method body: |
| 24 | + ```php |
| 25 | + $serviceInfo = $serviceOrder->getServiceInfo(); |
| 26 | + $settings = get_module_settings(self::$module); |
| 27 | + ``` |
| 28 | + All subsequent column references use `$settings['PREFIX']` as the key prefix. |
| 29 | + |
| 30 | +3. **Load license functions** — immediately after step 2, before any other calls: |
| 31 | + ```php |
| 32 | + require_once __DIR__.'/../../../../include/licenses/license.functions.inc.php'; |
| 33 | + ``` |
| 34 | + |
| 35 | +4. **Log the lifecycle event:** |
| 36 | + ```php |
| 37 | + myadmin_log(self::$module, 'info', self::$name.' Activation', __LINE__, __FILE__, self::$module, $serviceInfo[$settings['PREFIX'].'_id']); |
| 38 | + // or '... Deactivation' for doDisable |
| 39 | + ``` |
| 40 | + Use `self::$name` (not a string literal) as the message prefix. |
| 41 | + |
| 42 | +5. **`doEnable` only — fetch password and parse extra:** |
| 43 | + ```php |
| 44 | + $pass = vps_get_password($serviceInfo[$settings['PREFIX'].'_id'], $serviceInfo[$settings['PREFIX'].'_custid']); |
| 45 | + function_requirements('directadmin_get_best_type'); |
| 46 | + function_requirements('activate_directadmin'); // replace with your activation function |
| 47 | + $serviceExtra = run_event('parse_service_extra', $serviceInfo[$settings['PREFIX'].'_extra'], self::$module); |
| 48 | + $ostype = directadmin_get_best_type(self::$module, $serviceInfo[$settings['PREFIX'].'_type'], $serviceInfo, $serviceExtra); |
| 49 | + ``` |
| 50 | + Verify `$pass` and `$ostype` are populated before calling the activation function. |
| 51 | + |
| 52 | +6. **`doEnable` only — call the provisioning function:** |
| 53 | + ```php |
| 54 | + activate_directadmin( |
| 55 | + $serviceInfo[$settings['PREFIX'].'_ip'], |
| 56 | + $ostype, |
| 57 | + $pass, |
| 58 | + $GLOBALS['tf']->accounts->cross_reference($serviceInfo[$settings['PREFIX'].'_custid']), |
| 59 | + self::$module.$serviceInfo[$settings['PREFIX'].'_id'] |
| 60 | + ); |
| 61 | + ``` |
| 62 | + |
| 63 | +7. **`doDisable` only — call the deprovisioning function then send admin email:** |
| 64 | + ```php |
| 65 | + function_requirements('deactivate_directadmin'); // replace with your deactivation function |
| 66 | + deactivate_directadmin($serviceInfo[$settings['PREFIX'].'_ip']); |
| 67 | + $email = $settings['TBLNAME'].' ID: '.$serviceInfo[$settings['PREFIX'].'_id'].'<br>' |
| 68 | + .$settings['TBLNAME'].' Hostname: '.$serviceInfo[$settings['PREFIX'].'_hostname'].'<br>' |
| 69 | + .'Repeat Invoice: '.$repeatInvoiceId.'<br>' |
| 70 | + .'Description: '.self::$name.'<br>'; |
| 71 | + $subject = $settings['TBLNAME'].' '.$serviceInfo[$settings['PREFIX'].'_id'].' Canceled '.self::$name; |
| 72 | + (new \MyAdmin\Mail())->adminMail($subject, $email, false, 'admin/vps_da_canceled.tpl'); |
| 73 | + ``` |
| 74 | + Verify the `.tpl` path exists under `include/templates/email/admin/` before committing. |
| 75 | + |
| 76 | +## Examples |
| 77 | + |
| 78 | +**User says:** "Implement doEnable and doDisable for a new Imunify addon" |
| 79 | + |
| 80 | +**Actions taken:** |
| 81 | +1. Add `public static $name = 'Imunify VPS Addon';` and `public static $module = 'vps';` to the Plugin class. |
| 82 | +2. Implement `doEnable` following steps 1–6, replacing `activate_directadmin` → `activate_imunify` and loading it via `function_requirements('activate_imunify')`. |
| 83 | +3. Implement `doDisable` following step 7, replacing `deactivate_directadmin` → `deactivate_imunify` and template `admin/vps_da_canceled.tpl` → `admin/vps_imunify_canceled.tpl`. |
| 84 | + |
| 85 | +**Result:** |
| 86 | +```php |
| 87 | +public static function doEnable(\ServiceHandler $serviceOrder, $repeatInvoiceId, $regexMatch = false) |
| 88 | +{ |
| 89 | + $serviceInfo = $serviceOrder->getServiceInfo(); |
| 90 | + $settings = get_module_settings(self::$module); |
| 91 | + require_once __DIR__.'/../../../../include/licenses/license.functions.inc.php'; |
| 92 | + myadmin_log(self::$module, 'info', self::$name.' Activation', __LINE__, __FILE__, self::$module, $serviceInfo[$settings['PREFIX'].'_id']); |
| 93 | + $pass = vps_get_password($serviceInfo[$settings['PREFIX'].'_id'], $serviceInfo[$settings['PREFIX'].'_custid']); |
| 94 | + function_requirements('activate_imunify'); |
| 95 | + $serviceExtra = run_event('parse_service_extra', $serviceInfo[$settings['PREFIX'].'_extra'], self::$module); |
| 96 | + activate_imunify($serviceInfo[$settings['PREFIX'].'_ip'], $pass, $GLOBALS['tf']->accounts->cross_reference($serviceInfo[$settings['PREFIX'].'_custid']), self::$module.$serviceInfo[$settings['PREFIX'].'_id']); |
| 97 | +} |
| 98 | +``` |
| 99 | + |
| 100 | +## Common Issues |
| 101 | + |
| 102 | +- **`Call to undefined function activate_*`**: You skipped `function_requirements('activate_*')` before calling it. Add the call immediately before the activation function call. |
| 103 | +- **`Undefined index: PREFIX_id`**: `get_module_settings()` was not called, or `self::$module` is wrong. Verify `public static $module = 'vps';` matches the registered module name. |
| 104 | +- **`require_once` path resolves to wrong location**: `__DIR__` is relative to `src/`. The path `__DIR__.'/../../../../include/licenses/license.functions.inc.php'` assumes four directory levels up to the MyAdmin root. If the plugin is not installed under `vendor/detain/myadmin-*/src/`, adjust the `../` count. |
| 105 | +- **Admin email not sent after disable**: Ensure `(new \MyAdmin\Mail())` is instantiated with `new` and the template path is relative to `include/templates/email/`. Missing template file will silently fail — confirm the `.tpl` exists. |
| 106 | +- **`vps_get_password` returns empty**: The VPS record may lack a stored password. Log `$pass` with `myadmin_log()` immediately after the call to confirm before passing to the activation function. |
0 commit comments