Modules, themes, hooks and the API explained, plus practical examples with action, filter and gate hooks, so your WiseCP extensions survive every update.
What a hosting company wants from WiseCP is usually small: “Tell accounting when an order comes in”, “Stop the payment step in this case”, “Send an SMS when an invoice is created”. The biggest trap with small requests is opening a core file and adding two lines there. Two lines do the job, right up until the next update overwrites that file.
Four doors
There are four supported ways to extend WiseCP:
| Door | What it’s for |
|---|---|
| Module | A capability the platform doesn’t have: a new panel, payment provider, registrar, SMS service |
| Theme | The entire website and client area |
| Hook | Reacting to existing behaviour, changing a value, stopping an operation |
| API | An outside system reading and writing clients, orders and services |
Most real work uses more than one door. But for “do something that already exists a little differently”, the answer is usually a hook.
Hook families
Hook names tell you what they do with their prefix:
action:something happened, just so you know. The return value is ignored.filter:you’re allowed to change a value.gate:you can stop the operation. Return a non-empty string and the operation stops, showing that text to the user.ui:you can print HTML at a specific spot on the page.
Example 1: notify on every new invoice
The listener file goes in the coremio/hooks folder or in a module’s hooks.php.
<?php
// coremio/hooks/invoice-notify.php
Hook::add('action:invoice.created.any', 10, function ($invoice_id, $data) {
// If the write failed the id arrives as 0; check that first.
if (!$invoice_id) return;
// For example, send a short notice to the accounting system.
});
Example 2: add a rule at checkout
gate:order.checkout runs as the customer moves to the payment step. Returning a non-empty string stops it:
<?php
// coremio/hooks/cart-limit.php
Hook::add('gate:order.checkout', 10, function ($member, $cart) {
if (count($cart) > 20) {
return 'You can order at most 20 items at once.';
}
return null;
});
The docs carry an important warning: at this point the cart lines are not priced yet. If your rule depends on an amount, you have to work out the prices yourself or use the filter at the summary stage. Details like this are why reading a hook’s documentation before writing it is a must.
Three golden rules
- Don’t edit the core. An update brings its own core; your work should live in theme, module and hook files.
- Don’t do slow work in a hook. If you call an outside service, keep the timeout short; a user may be waiting.
- Log everything. When something goes wrong, the hook’s log is the first place you’ll look.
If you need themes and addons for WiseCP, the WiseCP service page covers what can be built.