Lecteur Markdown
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
> Version: 1.0
> Audience: Plugin developers for the BeamReactor CMS
> Scope: Architecture, conventions, security rules, APIs, SQL, JS, i18n
BeamReactor is a centralized CMS developed and maintained for more than 22 years.
Fundamental rules:
index.php).!!0 and !!1?>) unless outputting raw text/HTML/JSON/JSexit() or die() - Only return / control flow
Plugins are:
Naming discipline is therefore critical.
/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/
When a plugin is called via:
index.php?obj=oneliner.php
The engine automatically loads:
/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:
include_once(getlocale('nom_du_plugin'));
?>
Every plugin must begin with the BeamReactor guard (the only exit allowed):
// 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:
if($obj=='plugin.php') frameheader($dialplugindisplay);
Notes:
frameheader() to avoid missing variable errorsframeheader('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)ob_flush(); flush(); without a preceding ob_start()if(!function_exists('frameheader')) return;
$basedatadisplay = 'yes';
$basedisplevel = MYPLUGIN_LEVEL_HIGHUSER;
$ftype = 1;
$is_public = 0;
?>
Standard suffixes:
_LEVEL_USER_LEVEL_HIGHUSER_LEVEL_MODERATOR_LEVEL_ADMIN_LEVEL_OVERMINDLocation:
/plugins/myplugin/locale/myplugin.fr.inc.php
Example:
if(!function_exists('frameheader')) return;
$dialplugindisplay = 'Fabrique de spaghetti';
$dialplugincall = 'Spaghettisation';
$dialspaghetti[1] = 'Suivez le spaghetti';
?>
$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].
core.css?obj=myplugin.mod
❌ Forbidden:
?obj=plugins/myplugin/handlers/myplugin.mod.php
Levels:
DEBUG, INFO, SUCCESS, WARNING, ERROR, CRITICAL
Example:
$toastId = Toast::add(
Toast::LEVEL_WARNING,
'Sécurisez votre compte',
'Activez la 2FA',
BASE_LEVEL_USER
);
?>
Broadcast toasts are persistent and reserved for emergencies.
Replaces:
filter_varintvalcleanhtmlAllowed datatypes:
Bool, Date, Email, Name, HTML, XML, UUID, URL, String, IP, Float, Arithmetic, Path, PHPsession, ...
Usage:
use Beamreactor\Sanitizer\Parser;
$email = Parser::sanitize($_POST['email'], 'email');
$page = Parser::sanitize($_GET['page'], 'int') ?: 1;
?>
Rules:
use Beamreactor\Database\SQL;
$users = SQL::query(
"SELECT * FROM users WHERE level >= ?",
[$level]
);
?>
If SQL fails → empty array, no exception.
Global:
BEAM_BASE_URL
Dialogs:
alertWindow('Title', 'Message');
confirmWindow('Title', 'Question', {}, callback);
Inject JS via PHP:
$headdata .= "<script>...</script>";
$footdata .= "doSomething();";
?>
$js_translations = [
'plugin' => [
'reply' => $dialemail[16]
]
];
setJavascriptLocale($js_translations);
?>
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();
require, include, require_once for plugin internalsBeamReactor is not permissive by accident. It is strict by design.