Development Architecture

Core architectural concepts, conventions, and tools used within UNA. Its goal is to guide developers in building modules (apps), customizing templates, interacting with the core system, and contributing effectively to the platform.

Core Concepts

Developers working with UNA should be familiar with the following core concepts:

  • Modules (Apps): The fundamental building blocks of UNA functionality. Almost every feature (Profiles, Groups, Posts, Messenger, etc.) is implemented as a module. Modules are self-contained units typically including backend logic (PHP classes), database schemas, frontend templates, CSS, and JavaScript. Developers extend UNA primarily by creating new modules or customizing existing ones.
  • Templates: UNA utilizes a powerful template engine for rendering the user interface. Each site uses a single active template (e.g., artificer, lucid). Templates define the overall layout, styling, and provide default HTML structures. Developers can create custom templates or override specific parts of an existing template.
  • Studio: The administration backend of UNA. It's not just for site administrators; developers interact with Studio to manage modules, configure settings, use builders (like Forms, Navigation, Permissions), and access development tools. Modules often register their settings pages within Studio.
  • Injections & Hooks: UNA employs a system of "injections" and "hooks" to allow developers to modify or extend core behavior and the behavior of other modules without altering their original code.
    • Hooks: Allow executing custom code at specific points during the system's execution (e.g., before displaying a page, after a user registers). Hooks are registered using the BxDol땔 class.
    • Injections: Allow adding content or modifying data structures within specific predefined areas of the page or system, often managed via Studio's Polyglot or Pages builders.
  • Polyglot: The internationalization (i18n) and localization (l10n) engine. All user-facing text should use language keys managed through Polyglot (_t('_lang_key')). This allows sites to be translated easily via Studio.
  • Permissions: A granular permissions system controls what actions different member levels can perform. Modules define their own actions, which can then be configured in Studio > Permissions.
  • Database Abstraction: UNA uses a database abstraction layer (BxDolDb) to handle database interactions, primarily supporting MySQL/MariaDB. It encourages the use of prepared statements for security.

Directory Structure

Understanding the directory layout is crucial for navigation and development:

  • /inc/: Contains core system files, classes (BxDol...), and bootstrap processes (header.inc.php, footer.inc.php). Developers generally shouldn't modify core files directly but need to understand their role.
  • /modules/: The heart of UNA's functionality. Each subdirectory represents a module (e.g., /modules/boonex/posts/). Module development primarily happens here.
    • /modules/[vendor]/[module_name]/classes/: PHP classes for the module (Module class, Db, Template, etc.).
    • /modules/[vendor]/[module_name]/data/: Data files, often including SQL install/uninstall scripts, language files.
    • /modules/[vendor]/[module_name]/template/: Module-specific template files (.html), CSS, and JavaScript.
    • /modules/[vendor]/[module_name]/js/: Module-specific JavaScript files.
    • /modules/[vendor]/[module_name]/css/: Module-specific CSS files.
    • /modules/[vendor]/[module_name]/install/: Installation-related files (config, installer class).
    • /modules/[vendor]/[module_name]/config.php: The module's main configuration file, defining its properties, dependencies, and routes.
  • /template/: Contains the available site templates (e.g., /template/artificer/). Customizing a site's look and feel involves working within these directories or creating a new one.
  • /plugins/: Third-party libraries managed primarily via Composer.
  • /plugins_public/: Publicly accessible components (often JavaScript libraries) linked from /plugins/.
  • /studio/: Contains the code for the Studio backend interface.
  • /cache/, /cache_public/: System cache files. cache_public contains publicly accessible cached files like compiled CSS/JS (Mixes).
  • /logs/: System log files. Essential for debugging.

Request Lifecycle (Simplified Overview)

While server configuration plays a role, a typical web request within the UNA application follows this general flow:

  1. Entry Point: Request hits the web server, usually processed via .htaccess (Apache) or equivalent rules (Nginx) directing it to index.php or other specific entry points (like member.php, searchKeyword.php).
  2. Core Initialization: index.php includes inc/header.inc.php, which bootstraps the system:
    • Loads core configuration (inc/header.inc.php includes inc/profiles.inc.php).
    • Initializes the database connection (BxDolDb).
    • Loads essential classes (BxDol).
    • Initializes the session and user authentication.
    • Loads the active template engine (BxDolTemplate).
  3. Routing & Module Loading: UNA determines which module and page should handle the request based on the URL. This often involves parsing the URL and checking module config.php files for matching page URIs. The corresponding module's class is instantiated.
  4. Controller Execution: The responsible method within the module's class (often action... or service... methods) is executed. This method typically:
    • Fetches data using the module's Bx[Vendor][Module]Db class.
    • Performs business logic.
    • Prepares data for the template.
    • Calls the template engine to render output.
  5. Template Rendering: The template engine (BxTempl...) uses the module's template files (.html), base template files, and data provided by the controller to generate the HTML output. It processes template functions, includes CSS/JS (often via Mixes), and handles Polyglot keys. Hooks and injections may modify the output at this stage.
  6. Response: The generated HTML is sent back to the browser. inc/footer.inc.php may perform cleanup tasks.

Modules (Apps)

Modules are the cornerstone of UNA development.

  • Structure: Follow the directory structure outlined above.
  • Naming Conventions: Use CamelCase for class names. Standard module classes often follow the pattern Bx[Vendor][Module]Module, Bx[Vendor][Module]Db, Bx[Vendor][Module]Template, Bx[Vendor][Module]Config, Bx[Vendor][Module]Form. Vendor and Module names should also be CamelCase (e.g., BoonexPhotos).
  • config.php: Defines module metadata (title, version, vendor), dependencies, database prefix, pages/URIs, service calls, and settings categories for Studio.
  • Installation: Modules have install and uninstall methods in their Bx[Vendor][Module]Installer class, typically handling database schema changes and system settings registration.
  • Routing: Pages within a module are usually defined in config.php under the page_uri_to_role_action array, mapping a URI to a class method.
// Example structure in modules/boonex/posts/classes/BxPostsModule.php
class BxPostsModule extends BxBaseModTextModule
{
    function __construct($aModule)
    {
        parent::__construct($aModule);
    }

    // Example action method called for a specific page/route
    public function actionViewEntry($iEntryId = 0)
    {
        // ... logic to fetch and display a post ...
    }

    // Example service call method
    public function serviceEntityInfo($iContentId)
    {
        // ... logic to return information about a post ...
    }
}

Templating System

  • Engine: Uses custom classes like BxDolTemplate, BxTemplFunctions, BxTemplMenu, etc. Template files are primarily .html but contain special syntax for function calls (__function_name__), language keys (_t(...)), and includes.
  • Base Templates: Found in /template/[template_name]/. Files like base.html, header.html, footer.html define the main site structure.
  • Overrides: To customize a module's appearance without modifying the module itself, copy its template files (/modules/[vendor]/[module_name]/template/*) to /template/[your_template_name]/modules/[vendor]/[module_name]/. The system will prioritize files in the active template directory.
  • CSS & JS (Mixes): UNA uses "Mixes" to combine and minify CSS and JS files for performance. These are defined in the template's config.php or added dynamically via BxDolTemplate::addCss() / BxDolTemplate::addJs(). Compiled files are stored in /cache_public/. During development, disabling CSS/JS caching in Studio > Settings > Advanced Settings is helpful.
  • Tailwind CSS: Newer templates like Artificer heavily utilize Tailwind CSS. Customization often involves modifying Tailwind configuration and utility classes within the template files.

Database Interaction

  • Abstraction Layer: Use BxDolDb::getInstance() to get the database object.
  • Queries: Primarily use the query() method. Always use prepared statements to prevent SQL injection vulnerabilities. Placeholders (:placeholder) are bound using an array.
  • Module DB Classes: Modules should have their own database class (e.g., BxPostsDb) extending a base module DB class (e.g., BxBaseModTextDb). This encapsulates all SQL queries related to the module.
// Get DB instance
$oDb = BxDolDb::getInstance();

// Example: Fetching data using prepared statement
$sSql = "SELECT `title`, `author_id` FROM `bx_posts_posts` WHERE `id` = :id AND `status` = :status";
$aPost = $oDb->getRow($sSql, [
    'id' => $iPostId,
    'status' => 'active'
]);

if ($aPost) {
    $sTitle = $aPost['title'];
    // ...
}

// Example: Getting value directly
$sAuthorName = $oDb->getOne("SELECT `name` FROM `sys_profiles` WHERE `id` = :id", ['id' => $iAuthorId]);

API

UNA provides a RESTful API for interacting with the system programmatically.

  • Endpoints: Accessed typically via /api/[ModuleName]/[MethodName].
  • Implementation: Modules can expose API endpoints by implementing service call methods (usually prefixed with service...) in their module class and potentially registering them or relying on default routing via BxDolRequest.
  • Authentication: API requests usually require authentication, often using tokens or session cookies depending on the context.
  • Response Format: Typically JSON.

Studio

Studio is the administrative interface built as a UNA module itself (system). Developers interact with Studio in several ways:

  • Module Management: Installing, uninstalling, enabling, disabling modules.
  • Settings: Modules register their settings forms in their config.php, making them configurable via Studio > Settings > [Module Name].
  • Builders: Using visual builders for Forms, Permissions, Navigation Menus, Pages, Grids. Data for these builders is often stored in the database (sys_objects_... tables).
  • Developer Tools: Accessing cache management, database query logging (if enabled), Polyglot key management, etc.

Coding Standards & Conventions

  • PSR Compliance: Aim for compliance with PSR-1 (Basic Coding Standard), PSR-12 (Extended Coding Style), and PSR-4 (Autoloader). Use Composer for dependency management.
  • Naming Conventions:
    • Classes: PascalCase (e.g., BxPostsModule). UNA core classes use BxDol..., template classes use BxTempl.... Module classes use Bx[Vendor][Module]....
    • Methods: camelCase (e.g., actionViewEntry).
    • Variables: camelCase (e.g., $oModuleDb). Use descriptive names. Global variables often have a g... prefix (use sparingly). Pointers to objects often use o..., arrays a..., strings s..., integers i..., floats f..., booleans b... (Hungarian notation is common but not strictly enforced everywhere).
    • Database Tables: Use prefixes defined in the module's config.php (e.g., bx_posts_posts).
    • Language Keys: Lowercase with underscores (e.g., _bx_posts_form_add). Often prefixed with module identifier.
  • Comments: Use PHPDoc blocks for classes, methods, and properties. Add inline comments where necessary to clarify complex logic.
  • Security: Always validate and sanitize user input. Use prepared statements for database queries. Check permissions using BxDolACL::getInstance()->isAllowed(...). Be mindful of XSS vulnerabilities (use appropriate escaping functions in templates).

Development Workflow

  1. Setup: Install UNA, ideally using Git to clone the repository for easier updates and contributions. Use Composer to install dependencies (composer install).
  2. Enable Development Mode: In Studio > Settings > Advanced Settings, disable template/CSS/JS caches and consider enabling query logging if needed for debugging. Set BX_DEV_MODE to true in inc/header.inc.php (or via environment variables) for more detailed error reporting (do not do this on production).
  3. Module Creation/Customization: Use Studio's Developer app or manually create the necessary module directory structure and files.
  4. Version Control: Use Git for tracking changes. Follow branching strategies if collaborating.
  5. Debugging: Use bx_log() for logging to /logs/, PHP's built-in error_log, or a debugger like Xdebug. Check PHP error logs and UNA logs (/logs/).
  6. Testing: Test thoroughly across different user roles and scenarios. Write automated tests if contributing significantly.
On This Page