Lecteur Markdown

Knowledge Base › BEAMREACTOR_PLUGINS

Beamreactor Plugins

BeamReactor – Plugin Development Documentation #

> Version: 1.0

> Audience: Plugin developers for the BeamReactor CMS

> Scope: Architecture, conventions, security rules, APIs, SQL, JS, i18n

1. Philosophy & Core Principles

BeamReactor is a centralized CMS developed and maintained for more than 22 years.

Fundamental rules:

  • No PHP script can ever be called directly. Everything goes through the XDP engine (index.php).
  • Plugins are isolated, non-colliding, and auto-loaded.
  • Predictability, security, and performance outweigh convenience.

Coding Conventions (Mandatory) #

  • Allman indentation style
  • Boolean logic uses !!0 and !!1
  • Strict typing for functions and methods whenever possible
  • Prefer single quotes
  • Avoid constant PHP context switching (performance cost)
  • Always close PHP tags (?>) unless outputting raw text/HTML/JSON/JS
  • Plugins must never use exit() or die()

- Only return / control flow

2. Plugin Packaging & Lifecycle

Plugins are:

  • Managed by the BeamReactor package manager
  • Loaded automatically by the engine
  • Designed so multiple plugins may coexist on the same page without conflict

Naming discipline is therefore critical.

3. Standard Plugin Directory Structure

text
/plugins/myplugin/
├── myplugin.php
├── conf/
│   ├── myplugin.conf.inc.php
│   └── myplugin.sitemap.json
├── doc/
│   ├── myplugin.md
│   └── myplugin.help.json
├── lib/
│   └── myplugin.lib.inc.php
├── locale/
│   ├── myplugin.en.inc.php
│   ├── myplugin.fr.inc.php
│   └── myplugin.de.inc.php
├── handlers/
│   └── myplugin.mod.php
├── css/
│   └── myplugin.css
├── js/
│   └── myplugin.js
├── ui/
│   └── button.png
├── sql/
│   └── myplugin.sql
├── tests/
│   └── myplugin.test.php
└── data/
	└── cache/

4. Auto-loading Behavior (Engine)

When a plugin is called via:

text
index.php?obj=oneliner.php

The engine automatically loads:

  • Configuration
  • Library
  • Locale
php
/plugins/oneliner/conf/oneliner.conf.inc.php
/plugins/oneliner/oneliner.lib.inc.php
getlocale('oneliner')
?>

⚠️ Manual includes are forbidden for configs and libs.

The only allowed include:

php
include_once(getlocale('nom_du_plugin'));
?>

5. Plugin Main File (`myplugin.php`)

Every plugin must begin with the BeamReactor guard (the only exit allowed):

php
// Ceci vérifie que nous sommes bien en contexte BeamReactor.
// C'est le SEUL exit autorisé dans le code d'un plugin.
if(!function_exists('frameheader')) die('forbidden');

Then, standard pattern:

php
if($obj=='plugin.php') frameheader($dialplugindisplay);

Notes:

  • Locale must be loaded before frameheader() to avoid missing variable errors
  • frameheader('title', $headingLevel='h3', $noheader=false) structures the UI

- H1 = page title (one per page)

- H2 = main sections

- H3+ = frames/widgets

  • framefooter() closes a frame; not needed at page bottom (auto-close)
  • Do not use ob_flush(); flush(); without a preceding ob_start()

6. Configuration File (`conf/*.conf.inc.php`)

php
if(!function_exists('frameheader')) return;

$basedatadisplay = 'yes';
$basedisplevel   = MYPLUGIN_LEVEL_HIGHUSER;
$ftype		   = 1;
$is_public	   = 0;
?>

Security Levels #

  • Levels are constants only
  • Never hardcode numeric values

Standard suffixes:

  • _LEVEL_USER
  • _LEVEL_HIGHUSER
  • _LEVEL_MODERATOR
  • _LEVEL_ADMIN
  • _LEVEL_OVERMIND

7. Internationalization (Locale Files)

Location:

text
/plugins/myplugin/locale/myplugin.fr.inc.php

Example:

php
if(!function_exists('frameheader')) return;
$dialplugindisplay = 'Fabrique de spaghetti';
$dialplugincall	= 'Spaghettisation';
$dialspaghetti[1]  = 'Suivez le spaghetti';
?>

8. Global Runtime Configuration (`$cfg`)

php
$cfg[0]   // Base URL
$cfg[1]   // Site name
$cfg[3]   // Skins path
$cfg[4]   // Data path
$cfg[17]  // Max upload size
$cfg['obj']
$cfg['request_method']
?>

Use BEAM_BASE_URL in JavaScript instead of $cfg[0].

9. CSS Rules

  • Plugins rely on core.css
  • Never invent colors
  • If a style is missing → propose adding it to core.css

10. Modules / Handlers (`*.mod.php`)

  • Endpoints only (JSON / XML / text)
  • No UI
  • Called as:
text
?obj=myplugin.mod

❌ Forbidden:

text
?obj=plugins/myplugin/handlers/myplugin.mod.php

11. Toast System

Levels:

text
DEBUG, INFO, SUCCESS, WARNING, ERROR, CRITICAL

Example:

php
$toastId = Toast::add(
	Toast::LEVEL_WARNING,
	'Sécurisez votre compte',
	'Activez la 2FA',
	BASE_LEVEL_USER
);
?>

Broadcast toasts are persistent and reserved for emergencies.

12. Sanitizer (Critical)

Replaces:

  • filter_var
  • intval
  • cleanhtml

Allowed datatypes:

Bool, Date, Email, Name, HTML, XML, UUID, URL, String, IP, Float, Arithmetic, Path, PHPsession, ...

Usage:

php
use Beamreactor\Sanitizer\Parser;
$email = Parser::sanitize($_POST['email'], 'email');
$page  = Parser::sanitize($_GET['page'], 'int') ?: 1;
?>

13. SQL Layer

Rules:

  • Always sanitize before SQL
  • Never concatenate
  • Always check results
php
use Beamreactor\Database\SQL;
$users = SQL::query(
	"SELECT * FROM users WHERE level >= ?",
	[$level]
);
?>

If SQL fails → empty array, no exception.

14. JavaScript Integration

Global:

js
BEAM_BASE_URL

Dialogs:

js
alertWindow('Title', 'Message');
confirmWindow('Title', 'Question', {}, callback);

Inject JS via PHP:

php
$headdata .= "<script>...</script>";
$footdata .= "doSomething();";
?>

15. JS Translations

php
$js_translations = [
	'plugin' => [
		'reply' => $dialemail[16]
	]
];
setJavascriptLocale($js_translations);
?>

16. WYSIWYG Editor Example

js
initRTE("javascript/images/", "javascript/includes/", "", true, "<?php echo $uniqueid; ?>");
var rte1 = new richTextEditor("htmlfeed");
rte1.html = <?php echo json_encode($content); ?>;
rte1.width = 800;
rte1.height = 400;
rte1.build();

17. Final Hard Rules (Read Twice)

  • ❌ No require, include, require_once for plugin internals
  • ❌ No exit/die except BeamReactor guard at top
  • ❌ No direct file calls
  • ✅ Locale before header
  • ✅ Sanitizer before SQL
  • ✅ One archive = one plugin

BeamReactor is not permissive by accident. It is strict by design.