En vous promenant sur Beamreactor, nous stockons votre IP 48h pour des raisons de sécurité.

Lecteur Markdown

Knowledge Base › BEAMREACTOR_INCLUDES

BEAMREACTOR_INCLUDES

BeamReactor – Global Includes #

> Version: 1.0

> Audience: BeamReactor core developers and integrators

> Scope: Include system architecture, authoring rules, installation discipline

---

1. What Are Global Includes? #

Global includes are lightweight PHP files that run on every single request, regardless of which page or plugin is being loaded. They are not plugins. They have no URL, no UI, and no plugin lifecycle. They are pure execution hooks — tasks the engine must carry out unconditionally as it processes any incoming request.

Typical responsibilities:

  • Security enforcement — IP ban checking, anomaly detection, bot analysis
  • Session monitoring — authenticated session health, timeout warnings
  • Passive data collection — request statistics, geolocation, active users
  • Housekeeping — stale data cleanup (probabilistic via `rand()`)
  • UI injection — toast system initialization, informational banners

---

2. Engine Startup and Include Execution #

When a request enters the XDP engine (`index.php`), the engine starts by loading configuration (`user/conf/cog.php`), which defines all global variables including `$cfg`, `$headdata`, `$footdata`, and the `$inc_allowed` whitelist. The engine then iterates through `$inc_allowed` in declaration order:

// index.php
if(isset($inc_allowed))
{
	foreach($inc_allowed as $objINC)
	{
		$incfile = 'inc/'.$objINC;
		if(is_file($incfile)) include($incfile);
	}
	unset($objINC, $incfile);
}

This loop completes before any plugin, page, or HTML output is produced. At this point, no `<html>` has been echoed. Includes that append to `$headdata`, `$footdata`, or `$cfg['body']` do so safely because those buffers are rendered later by `HeaderHandler`.

Order matters. Includes that depend on a function set by an earlier include (e.g. `isBanned()`, defined by `ban.inc.php`) must appear after it in `$inc_allowed`. The canonical boot order is:

$inc_allowed = [
	'ban.inc.php',		   // 1. IP ban gate — must be first
	'geos.inc.php',		  // 2. Geolocation (depends on IP being clean)
	'hax.inc.php',		   // 3. Intrusion heuristics
	'stats.inc.php',		 // 4. Request statistics
	// ... subsequent includes may depend on all of the above
];

---

3. Authorization: Configuration Before Installation #

> � ️ This rule is mandatory and non-negotiable.

An include file that exists on disk but is not listed in `$inc_allowed` is never executed. Dropping a file into `inc/` does not activate it. Only the whitelist in `user/conf/cog.php` grants execution rights.

The required installation sequence is therefore:

Step 1 — Authorize (edit `user/conf/cog.php`):

$inc_allowed = [
	'ban.inc.php', 'geos.inc.php', /* ... existing entries ... */
	'my_include.inc.php'   // ← add the entry FIRST
];

Step 2 — Deploy (create `inc/my_include.inc.php`):

<?php
if(!function_exists('isBanned')) return;
// ... logic
?>

This order enforces a deliberate review step before any code runs. Authoring the file first and hoping the engine picks it up is not acceptable — it bypasses the authorization layer and makes the inclusion accidental rather than intentional.

If the file does not exist when the engine reaches its entry in `$inc_allowed`, it is silently skipped (`is_file()` check). This is a safety net, not the intended workflow.

---

4. Writing a Global Include #

4.1 Required Guard #

Every include must open with a dependency guard. Because includes run before most of the engine is initialized, a direct call (e.g. via the filesystem) would have no defined functions. The guard ensures the include is running inside the engine:

if(!function_exists('isBanned')) die('forbidden');

Use `die('forbidden')` for this specific guard — not `return`. On a shared hosting environment, a direct HTTP or filesystem call to an `inc/` file would silently pass through a `return`, potentially exposing partial logic or globals. `die()` makes out-of-context execution impossible.

`return` is correct for conditional early exits further down in the include, where the engine context is confirmed and you simply have nothing to do (e.g. wrong page type, user not authenticated, condition not met).

4.2 Error Page Exclusion #

Includes that have side effects on the UI or database should skip error pages:

if(stripos($cfg['obj'] ?? '', '.err') !== false) return;

4.3 Early Exit Conditions #

Return as early as possible. Condition-based early exit keeps execution fast for the majority of requests where the include has nothing to do:

// Example: only run for authenticated users
if(!secure(0)) return;

// Example: only run 1 in 40 requests (probabilistic housekeeping)
if(rand(0, 40) !== 0) return;

4.4 Complete skeleton #

<?php
/**
 * XDP [name] include
 *
 * [One-line description of what this include does.]
 *
 * @subpackage Includes
 * @author	 [Author]
 * @copyright  [Year] [Author]
 * @version	1.0.0
 * @since	  [Year]
 * @date	   [Date]
 */

// Security gate — die() is mandatory here, not return.
// Prevents any execution if the file is called directly (shared hosting, misconfiguration).
if(!function_exists('isBanned')) die('forbidden');

// Early exit conditions — return is correct from here on (engine context is confirmed).
// Skip error pages
if(stripos($cfg['obj'] ?? '', '.err') !== false) return;

// Early exit condition (example)
if(empty($cfg['dbtable'])) return;

// Logic
// ...
?>

---

5. Injection Points #

Includes have access to the three global output buffers that `HeaderHandler` will render later in the request. All three are plain strings — append with `.=`.

| Buffer | Rendered location | Typical use |

|---|---|---|

| `$headdata` | Inside `<head>` | `<style>`, `<script>`, `<link>` |

| `$cfg['body']` | Immediately after `<body>` | Visible HTML (banners, overlays) |

| `$footdata` | End of `<body>` | `<script src="...">`, deferred JS |

// Inject a stylesheet
$headdata .= '<link rel="stylesheet" href="path/to/style.css">';

// Inject a top-of-page banner
$cfg['body'] = ($cfg['body'] ?? '') . '<div id="my-banner">...</div>';

// Inject a deferred script
$footdata .= '<script src="javascript/my_module.js"></script>';

Note: `$cfg['body']` may not be initialized at the point the include runs. Always use the null-coalescing concatenation pattern shown above.

---

6. Available Globals #

At the time includes run, the following are guaranteed to be available:

| Variable | Description |

|---|---|

| `$cfg` | Full engine configuration array |

| `$cfg['obj']` | Requested object identifier (e.g. `home.php`, `403.err`) |

| `$cfg[0]` | Base URL |

| `$cfg[1]` | Site name |

| `$cfg['dbtable']` | Member table name (empty if membership disabled) |

| `$headdata` | HTML head buffer (string) |

| `$footdata` | HTML foot buffer (string) |

| `$cfg['skin']` | Active skin name |

| `$_SESSION` | PHP session |

| `$_COOKIE` | PHP cookies |

| `ipCheck()` | Returns the verified client IP |

| `isBanned()` | Checks whether an IP is banned |

| `secure()` | Checks user permission level by string constant name |

---

7. Existing Includes Reference #

| File | Purpose | Runs when |

|---|---|---|

| `ban.inc.php` | Enforces IP ban list; redirects to 403 | Always (first) |

| `geos.inc.php` | Geolocation lookup and logging | Always |

| `hax.inc.php` | Intrusion heuristics and attack detection | Always |

| `stats.inc.php` | Records request to stats table (deferred INSERT) | Always |

| `botsniffer.inc.php` | Bot and crawler identification | Always |

| `currentUsers.inc.php` | Active user count tracking | Always |

| `tidy.inc.php` | Probabilistic cleanup of unactivated accounts | ~1/40 requests |

| `defense_logs.inc.php` | Security event logging | Always |

| `rss_gc.inc.php` | RSS cache garbage collection | Probabilistic |

| `displayWarnings.inc.php` | Toast system injection (authenticated users) | Authenticated |

| `scattags.inc.php` | Tag scatter/scatter-cache operations | Always |

| `session_warning.inc.php` | Session timeout warning JS injection | Authenticated |

| `ip_notice.inc.php` | Top-of-page IP storage notice banner | Until cookie set |

---

8. Hard Rules #

  • ✅ Use `die('forbidden')` for the security guard at the top (out-of-context protection)
  • ✅ Use `return` for all conditional early exits below the guard
  • ❌ Never use `die()` for anything other than the security guard
  • ❌ Never assume `$cfg['body']` is initialized — always use `??` or `isset()`
  • ❌ Never produce output directly (`echo`, `print`) — use `$headdata`, `$footdata`, `$cfg['body']`
  • ❌ Never include plugin files or external libs from inside an include
  • ❌ Never deploy the file before updating `$inc_allowed`
  • ✅ Guard with `if(!function_exists(...)) return;`
  • ✅ Skip error pages with `.err` check when appropriate
  • ✅ Respect declaration order in `$inc_allowed` (dependencies first)
  • ✅ Keep execution cost minimal — includes run on every request

---

Includes are not plugins. They are responsibilities the engine carries on every request. That is why they require explicit authorization.

de en fr