+30.2152151245-8 abuse@cms39.com

Plugin development

A plugin is a folder in public/plugins/<name>/ with a <name>.plugin.php file. It is activated in the Plugins Manager and updated together with the core.

Header

<?php
/*
  Plugin Name: Booking
  Description: Table booking [booking]
  Version: 1.0.0
  Author: …
 */

cms39_i18n_domain('booking', __DIR__ . '/languages');
add_shortcode('booking', 'booking_render');

Every change bumps the Version and is recorded in the plugin CHANGELOG.md, so sites know what an update brought.

Admin page and ajax

// cp_loader?page=mod_admin_booking — only functions prefixed mod_admin_
function mod_admin_booking()
{
    check_authorise();
    check_level(8);
    return '<h1>Bookings</h1>…';
}

// cp_ajax?f=mod_ajax_booking_save — cp_ajax does not require login: the function checks it
function mod_ajax_booking_save()
{
    cms39_ajax_admin_only(8);
    cms39_csrf_check();
    // …
}

HookManager::addHook('cms39_admin_sidebar_menu', function (array $groups) {
    $groups['data']['items'][] = ['label' => 'Bookings', 'icon' => 'bi bi-calendar', 'url' => cp_URL . 'cp_loader?page=mod_admin_booking'];
    return $groups;
});

Settings

Plugin settings appear under Settings. The default goes into cms39_conf_defaults(), labels and help into the cms39_settings_ui filter. Code reads them with cms39_conf('booking.slots', 20).

Database tables

$p = ['v' => '1.1.0', 'slug' => 'booking', 'schema' => __DIR__ . '/schema.php'];
cms39_plugin_installation_check($p);

// schema.php
$plugin_schema = [
    'tables' => ['cms39_booking' => 'CREATE TABLE IF NOT EXISTS `cms39_booking` (…) ENGINE=InnoDB'],
    'migrations' => [
        '1.1.0' => ['ALTER TABLE `cms39_booking` ADD COLUMN IF NOT EXISTS `notes` TEXT NULL'],
    ],
];

Tables are created on the first request after installation. Each new version runs only the missing migrations. Always write IF NOT EXISTS so a step can run again without errors.

for more information contact us by
E-MAIL or by phone at (+30) +30.2152151245-8