FAQ · TICKETS · CONTACTO · CHANGELOG

¿Un problema?
Estamos aquí.

Consulte las preguntas frecuentes, abra un ticket de soporte o contacte directamente con nosotros. Sin chatbot, sin cola de espera: le responde una persona.

Antes de escribir, quizá la respuesta esté aquí

Funciones y arquitectura

Preguntas técnicas sobre el motor XDP, los plugins, la seguridad, el sistema de frames y las convenciones de desarrollo de BeamReactor.

¿Para qué sirve frameheader()?+
frameheader() abre una sección visual (frame) en la página. Muestra el título del plugin o de la sección y crea el contenedor HTML en el que se renderizará el contenido. Uso: frameheader('Mi título', 'h3', false). Los niveles de título siguen la jerarquía HTML: h1 para el título de la página (una sola vez), h2 para las secciones principales, h3 y siguientes para los frames y widgets. Un plugin llamado directamente debe empezar por: if($obj=='mi_plugin.php') frameheader($dialplugindisplay); — esta condición evita que la cabecera se muestre dos veces cuando el plugin se incluye desde otro script.
¿Cuándo usar framefooter()?+
framefooter() cierra el frame abierto por frameheader(). Es indispensable antes de abrir una nueva sección con frameheader(). No llame nunca a framefooter() sin un frameheader() a continuación, salvo al final de la página. El patrón clásico para estructurar una página en varios bloques: frameheader('Sección 1'); /* contenido */ framefooter(); frameheader('Sección 2'); /* contenido */. El motor se encarga automáticamente del cierre final.
¿Cómo estructurar una página en varias secciones?+
Use el par framefooter() / frameheader() para encadenar las secciones. Cada sección crea un bloque visual distinto con su propio título. Ejemplo: tras mostrar un formulario y recibir un error, cierre el frame actual con framefooter(), abra un frame nuevo y limpio con frameheader(''), vuelva a incluir el formulario y haga return. Así el usuario permanece en una página válida y enmarcada, sin redirección HTTP.
¿Cómo funciona secure()?+
secure() comprueba si el nivel del usuario conectado es suficiente para acceder a un recurso. Recibe como parámetro una constante de nivel (BASE_LEVEL_ADMIN, PLUGIN_LEVEL_MODERATOR, etc.) y devuelve true o false. El patrón habitual: frameheader($dialplugindisplay); if(!secure(PLUGIN_LEVEL_MODERATOR)) { forbids(); return; }. El frame se abre ANTES de la comprobación — forbids() se muestra dentro del frame; si no, el layout se rompe. El truco secure(0) comprueba simplemente si el usuario ha iniciado sesión.
¿Qué includes usar en un plugin?+
Ninguno para la configuración y las bibliotecas — el motor XDP las carga automáticamente. El único include autorizado es el de la locale: include(getlocale('nombre_del_plugin'));. El motor detecta y carga los archivos .conf.inc.php y .lib.inc.php. Hacer un require o include manual de la configuración o de las libs provocará un warning y una ruta rota. Del mismo modo, no incluya nunca un módulo (.mod.php) — se llaman exclusivamente mediante ?obj=nombre.mod.
¿Cómo funcionan las traducciones en un plugin?+
Cada plugin tiene sus archivos de traducción en /locale/nombre_del_plugin.XX.inc.php (XX = código de idioma ISO). La carga se hace mediante include(getlocale('nombre_del_plugin'));, que debe llamarse ANTES de frameheader() para evitar errores de variable ausente. Las traducciones usan un array $dialnombreplugin[]. $dialplugindisplay contiene el título mostrado del plugin, $dialplugincall el nombre en el centro de control. getAvailableLanguages() devuelve la lista de idiomas disponibles.
¿Cómo cargar CSS o JavaScript específico de un plugin?+
Use la variable global $headdata para inyectar en el <head>: $headdata .= '<link rel="stylesheet" type="text/css" href="plugins/mi_plugin/css/mi_plugin.css">'; Para el JavaScript, el principio es el mismo: $headdata .= '<script src="plugins/mi_plugin/js/mi_plugin.js"></script>'; Para ejecutar JS después del DOM, use $footdata con un heredoc. Las CSS deben usar las variables definidas en core.css — no invente nunca colores. Si falta una variable, proponga añadirla a core.css.
¿Cómo validar las entradas del usuario?+
Use el Sanitizer: use Beamreactor\Sanitizer\Parser; y después Parser::sanitize($input, 'type'). Los tipos disponibles incluyen: bool, date, email, name, html, xml, uuid, url, string, ip, float, int, path y otros. sanitize() limpia y valida el dato, y devuelve false si no es válido. check() comprueba el formato sin limpiar. Haga siempre la sanitización ANTES de cualquier operación SQL. No invente nunca un datatype — proponga uno si es necesario.
¿Cómo interactuar con la base de datos?+
Use la clase SQL: use Beamreactor\Database\SQL;. Métodos principales: SQL::query() para varias filas, SQL::queryFirst() para una sola fila, SQL::queryValue() para un valor único, SQL::insertRow() para insertar, SQL::updateRow() para actualizar, SQL::deleteRow() para eliminar. Use siempre consultas preparadas con parámetros ?. La concatenación directa de variables en el SQL está estrictamente prohibida. Compruebe que la BD está disponible con isset($cfg['dbtable']) y que su tabla existe con SQL::tableExists().
¿Cómo crear un endpoint AJAX?+
Los módulos (.mod.php) son los endpoints AJAX de BeamReactor. Responden en JSON, XML, HTML o texto. Se colocan en /handlers/nombre_plugin.mod.php y se llaman mediante ?obj=nombre_plugin.mod (sin el .php). No llame nunca a la ruta completa del archivo. Estructura mínima: comprobación de frameheader, seguridad con secure(), header Content-Type, tratamiento de la acción mediante Parser::sanitize(), respuesta JSON con ['success' => !!1] o ['success' => !!0]. En JavaScript, la llamada se hace con $.post(BEAM_BASE_URL + '?obj=nombre_plugin.mod', {...}).
¿Cómo funciona el enrutamiento de las páginas?+
En BeamReactor todo pasa por index.php. El parámetro ?obj= determina lo que se carga. Un plugin: ?obj=mi_plugin.php. Un módulo AJAX: ?obj=mi_plugin.mod. Un documento: ?obj=mi_pagina.dta. El motor XDP resuelve la ruta, carga automáticamente la configuración, las libs y la locale, y ejecuta el script en un entorno seguro. Ningún script PHP puede llamarse directamente — todo pasa por el motor.
¿Cómo mostrar notificaciones al usuario?+
BeamReactor dispone de un sistema de toasts con 6 niveles: debug (0), info (1), success (2), warning (3), error (4), critical (5). Uso rápido: Toast::info('Título', 'Mensaje', 5000); o Toast::add(Toast::LEVEL_WARNING, 'Título', 'Mensaje', BASE_LEVEL_USER, 0). El parámetro minUserLevel permite dirigir las notificaciones por nivel de acceso. La duración va en milisegundos, 0 para persistente.
¿Cuál es la estructura de un plugin de BeamReactor?+
Un plugin es una carpeta autónoma en /plugins/nombre_del_plugin/ que contiene: nombre_del_plugin.php (interfaz principal), /conf/ (configuración cargada automáticamente), /lib/ (bibliotecas cargadas automáticamente), /locale/ (traducciones por idioma), /handlers/ (endpoints AJAX .mod.php), /css/, /js/, /images/, /sql/ (instalación de las tablas), /tests/, /doc/ (documentación .md y ayuda .help.json) y /data/cache/ para los datos persistentes. La instalación consiste en dejar la carpeta. La eliminación, en retirarla.
¿Cómo mostrar diálogos JavaScript en BeamReactor?+
BeamReactor sustituye los alert/confirm/prompt nativos por diálogos personalizados definidos en javascript/dialogs.js.php. Cuatro funciones: alertWindow('Título', 'mensaje') para una alerta, confirmWindow('Título', '¿pregunta?', {}, callback) para una confirmación, promptWindow('Título', 'Etiqueta:', {}, callback) para una entrada de datos, infoWindow('Título', 'info') para una información. No use nunca alert(), confirm() ni prompt() nativos.
¿Cómo pasar las traducciones PHP al JavaScript?+
En el archivo de locale del plugin, defina un array $js_translations y llame a setJavascriptLocale($js_translations). Ejemplo: $js_translations = ['mi_plugin' => ['error_msg' => $dialmiplugin[5]], 'global' => ['error' => $dial[32]]]; setJavascriptLocale($js_translations);. En JavaScript, acceda a las traducciones mediante PLUGIN_TRANSLATION.mi_plugin.error_msg. Las traducciones se inyectan en el head como un objeto JavaScript global.
¿Puedo usar exit o die en un plugin?+
No. Los plugins no pueden usar nunca exit ni die. El único exit autorizado en todo el código de un plugin es if(!function_exists('frameheader')) die('forbidden'); en la primera línea, que comprueba el contexto BeamReactor. Para interrumpir la ejecución, use return. Para tratar un error, muestre el mensaje dentro del frame y haga return. Si un plugin usa exit o die, el motor no puede saber qué ha fallado y el diagnóstico se vuelve imposible.
¿Cómo funcionan los niveles de seguridad?+
BeamReactor usa una jerarquía fija: OVERMIND > ADMIN > MODERATOR > HIGHUSER > USER. Las constantes BASE_LEVEL_* se definen en cog.inc.php. Cada plugin puede definir sus propios niveles mediante NOMBRE_PLUGIN_LEVEL_* en su configuración. $basedisplevel usa siempre BASE_LEVEL_*, nunca PLUGIN_LEVEL_*. Los define() personalizados se hacen después de $basedisplevel. El sistema completa automáticamente los niveles que faltan mediante base_user_levels().
¿Cómo funciona la carga automática de las clases?+
El motor carga automáticamente los archivos .lib.inc.php y .conf.inc.php. Para clases adicionales, registre un autoloader PSR-4 en la configuración del plugin con spl_autoload_register(). El namespace sigue la convención Beamreactor\NombrePlugin\. Los archivos de clase van en /lib/ y se resuelven por la ruta relativa al namespace. Esto permite que varios plugins convivan sin colisión de nombres.

Autenticación de dos factores (2FA)

Añade una capa de protección indispensable al exigir una prueba de identidad adicional. Garantiza que, aunque le roben la contraseña, un tercero no pueda acceder a sus datos. Es la barrera más eficaz contra los intentos de suplantación de identidad y de pirateo de cuentas.

¿Cómo activar la autenticación de dos factores?+
Para proteger su cuenta, se necesitan dos pasos. Los usuarios registrados deben iniciar sesión en la interfaz principal de BeamReactor. Al hacer clic en el botón «Perfil», arriba a la izquierda, accederá a su perfil. En la parte inferior encontrará un código QR 2FA que debe escanear con una aplicación como Google Authenticator o Microsoft Authenticator. Se le proporcionarán códigos de recuperación: cópielos con cuidado para recuperar su cuenta en caso de pérdida o robo del teléfono.
¿Cómo inicio sesión con la autenticación de dos factores?+
Inicie sesión con su nombre de usuario y contraseña en el sitio BeamReactor. A continuación, el sistema le pedirá un código que encontrará en la aplicación Authenticator de su teléfono.
¿Cuáles son los requisitos?+
Actualice el sistema operativo de su teléfono y la aplicación Google o Microsoft Authenticator a sus últimas versiones. Si no puede iniciar sesión pero aún tiene acceso al correo electrónico de su cuenta, intente cambiar su contraseña. Sin acceso a su correo, contáctenos a través del formulario de soporte.
¿Y si he olvidado mi contraseña?+
Puede restablecerla en cualquier momento haciendo clic en el enlace «¿No puede acceder a su cuenta?» de la página de inicio de sesión.
¿Y si he perdido o roto mi teléfono?+
Utilice uno de los códigos de recuperación proporcionados al activar la 2FA. En la página de autenticación, haga clic en «Código de recuperación», introdúzcalo y, una vez conectado, actualice los ajustes 2FA de su perfil.
¿Y si cambio de teléfono o de sistema?+
Nuevo dispositivo, nuevo sistema, reinstalación tras un formateo: el procedimiento es el mismo que para un teléfono perdido. Utilice sus códigos de recuperación para iniciar sesión y, a continuación, sincronice su nuevo dispositivo desde su perfil de usuario.
¿Por qué se ha implantado la autenticación de dos factores?+
La autenticación de dos factores (2FA) añade una capa de protección indispensable al exigir una prueba de identidad adicional. Garantiza que, aunque le roben la contraseña, un tercero no pueda acceder a sus datos. Es la barrera más eficaz contra los intentos de suplantación de identidad y de pirateo de cuentas.

¿Necesita ayuda personalizada?

Tickets — Para los usuarios registrados. Cree un ticket, siga su avance, hable con el soporte técnico. Su historial se conserva.

Contacto directo — Para las solicitudes comerciales, las colaboraciones o las preguntas antes de la compra. No se necesita cuenta.
Formulario de contacto →

Changelog reciente

- October 3, 2026, 4:27 am: Mise à jour de l'outil MCP read_features, permettant de récuperer jusqu'a 50 tickets features par type, séverité. Correction des calls vers "level(" dans les outils MCP qui n'étaient pas tous en corrélation avec le plugin utilisé ou utilisaient des valeurs numériques (prohibées, patch de flemmasse). Introduction de l'outil MCP dump_schema.lib.inc.php.
- October 3, 2026, 3:34 am: Correction de l'outil MCP write_features (int/string) + ajout des points agile/fibonacci, de la catégorie
- October 1, 2026, 10:14 pm: Chaque lecture de fichier vérifie son résultat : un échec est signalé (trigger_error, message visible), jamais étouffé. is_readable() avant la lecture ne suffit pas (le fichier peut changer entre les deux, et il faut vérifier le retour de toute façon). Lot 1 fait le 30/09/2026 : les 18 @file_get_contents (audit, llm_rag, llmrag_ia, ClassMapScanner, CAPCache, VIES, VisionHelper). Reste : les ~110 autres lectures, plugin par plugin. — Texte d’origine (2004) : Ajouter is_readable() pour chaque fichier en lecture - DONE (features)
- October 1, 2026, 9:36 pm: Mettre la fonction de reconnaissance d'un bot dans la lib de securité. L'installer dans banna. Automatiser la function de reconnaissance de robots, en sql (harmless to harmful, spider, crawler, spam, stealer, etc) - DONE (features)
- October 1, 2026, 9:23 pm: Discard ou replace document si document deja present dans data - DONE (features)
- October 1, 2026, 3:46 pm: Limiter les acces a la BDD au strict minimum avec la fonction connection(); - DONE (features)
- October 1, 2026, 3:42 pm: Etudier la possibilité de faire un cache des plugins. - DONE (features)
- October 1, 2026, 3:26 pm: Multi currency pricing - DONE (features)
- October 1, 2026, 3:23 pm: newsletter/mailer-daemon html. - DONE (features)
- October 1, 2026, 2:51 pm: lib/sanitizer/Datatypes/wip/DatatypeHash.php : erreur de syntaxe (deux php de suite). Le scanner de classes parcourt wip/ (work in progress): Parser::sanitize($x, 'hash') chargerait ce fichier et pourrait potentiellement faire tomber le systeme même si personne ne l'appelle aujourd'hui. - DONE (features, 1 pts)
- October 1, 2026, 2:50 pm: #176 lot C : 19 scandir non vérifiés (liste dans la section 9 de l'audit) - foreach sur false = warning, array_diff(false) / [] + false = fatal en PHP 8 (diskmaster, edito.lib, login_success sont les fatals). - DONE (features, 3 pts)
- October 1, 2026, 1:57 pm: Silent failures hunted down (a 2005 request that was still relevant): every directory or file opening that could white-screen a page under PHP 8 is now checked, from the plugin list itself to the page cache, and settings that could not be read no longer fall back to defaults without a word. Two of them hid real damage: an unreadable database migration was recorded as applied without running, and adding a line to the history could overwrite the whole file. New event log: who banned, anonymized or exported whom, and who installed which plugin, kept one month and readable by site administrators in the Errors and events page. Moderation actions now require a security token: a booby-trapped image could make a moderator ban or anonymize someone, or make any member anonymize their own account. The error detail view no longer runs code hidden in an error message. The GDPR page buttons work again, and the GDPR export includes editorials and notepads again. The audit now finds files that no longer load and unchecked directory openings; its first run repaired the subscribers and quick links plugins.
- September 30, 2026, 6:02 pm: New imagesort plugin: sorts image folders with a local vision model (MiniCPM-V), recursively, from a source to a destination picked at each run under allowed roots. It classifies first and moves nothing, resumes where it stopped, and shows a review page with thumbnails where any category can be corrected; the categories are a base list plus a simple CSV. Moving is journaled and a whole batch can be undone; an identical file already at the destination (same MD5) counts as a duplicate, anything else gets a free name, a copy between drives is checked before the source is deleted, and no metadata is ever written. File reads that fail are no longer silent (first batch of an old 2004 request): the audit reports unreadable files as not audited instead of clean, and its check of the required member files finally reads the right path; the class map, the CAP cache, the VIES VAT check and the vision helper now report their failures. RAG sources given as a URL accept web addresses only (http/https): a local path could be read as a source by an administrator. JSON endpoints no longer get a warning printed into their response.
- September 30, 2026, 5:58 pm: Ajouter is readable a chaque opendir (cf versions.php 0.94 18.09.2005) - DONE (features)
- September 30, 2026, 3:25 pm: Location, for GMT values and hour relative listings and data supplying. - DONE (features)
- September 30, 2026, 3:23 pm: Add avatar - DONE (features)
- September 30, 2026, 3:23 pm: Gallery : target image inclusion within the current theme - DONE (features)
- September 30, 2026, 3:23 pm: base skin detection and creation - DONE (features)
- September 30, 2026, 3:05 pm: BeamReactor 3.0.0-alpha. Member panel diagnostics: each plugin reports from its own dashboard/ folder (counts by severity, "new since your last visit", filtered by level and group) - support tickets, orders, abuse, moderation, scheduler, error logs, calendar, LLM health, bans and reminders, and today the todo list (critical, due within 48 h, open) and the feature requests (blocking, never triaged, in progress). A single version source, core files flagged in the update manifest, and the updater opened to site owners. Foldable frames and title widgets are back without breaking older skins; skin translations move to skinlocale files. RTE 4.3: an emoji button, and a Versions button that reloads any of the last five saved versions of content, blogs, editorials and documents; embedding plugins is reserved to webmasters, with a recursion guard. MCP: the model keeps a notebook of its own (30 notes per user and per model), RAG excerpts name their source, the vector index was repaired, conversations are partitioned per user, the user's request never falls out of the context window, fake turns written by the model are cut and tool loops stop; web_fetch reads the main content in UTF-8, with an offset for long pages, and the sanitizer encodes non-ASCII URLs instead of truncating them. Feature requests gained categories, sortable headers, one-click unfeasible and cancelled states, Fibonacci complexity points with a WSJF sort, a Back link that returns where you were, and list views (blocking, never triaged, in progress) that the member panel opens directly; their write actions are now restricted to moderators (deletion to admins) and carry action tokens - marking a request as done was not checked at all. Cron handlers finally delivered for the defense-log and statistics purges, SQL Operations repairs tables according to their engine, a stored script injection in the oneliner is fixed, and a dozen lookups no longer crash on a missing row.
- September 27, 2026, 9:22 pm: URGENT aegis-ia : routeur user/data/tos.php sur le modèle de user/data/home.php de dev (include de tos_<langue>.html, erreur visible si la langue manque) ; le footer de la skin aegis pointe ensuite sur ?obj=tos.php au lieu de tos_php echo $cfg[22] .html (2 liens), et les og:url des CGU (cgv.html / tos.html, pages mortes) sur la vraie adresse. - DONE (features, 2 pts)
- September 24, 2026, 10:33 pm: Ajouter le niveau de complexité (barres de couleur dans la liste!) - delai necessaire dans features - DONE (features)
- September 24, 2026, 10:32 pm: Regrouper les listes d'ips bannies de chaque site SDP/XDP (export data) - DONE (features)
- September 24, 2026, 10:32 pm: Moteur de recherche HS si page >1 - DONE (features)
- September 24, 2026, 10:28 pm: <!--<a href=spider.php3>.</a>--> - DONE (features)
- September 24, 2026, 10:26 pm: plugin : pense bete - DONE (features)
- September 24, 2026, 10:25 pm: Notice: Undefined index: type in /home/artsonne/public_html/beamreactor.com/plugins/products_editor.php on line 173 Notice: Undefined variable: displaystatus in /home/artsonne/public_html/beamreactor.com/plugins/products_editor.php on line 173 - DONE (features)
- September 24, 2026, 10:23 pm: Laisser le user acceder au documents figés lorsque la base de données est down, mais afficher le 503 en cas d'acces a la BDD - DONE (features)
- September 24, 2026, 10:05 pm: Add repair table in the mysql operqtions plugin - DONE (features)
- September 24, 2026, 9:53 pm: in sponsors, entering a wrong web address ruins any UTF8 text typed in the comment field - DONE (features)
- September 24, 2026, 9:46 pm: feature: edit the request: buttons broken - DONE (features)

Historial completo →

¿No ha encontrado su respuesta?

Abra un ticket o contacte con nosotros.