NAME coding_standards - RSX framework coding conventions and standards SYNOPSIS Naming conventions, code organization, and design philosophy for RSX development DESCRIPTION The RSX framework enforces specific coding standards to maintain consistency, readability, and framework compatibility. These standards ensure code is maintainable and follows the framework's architectural principles. NAMING CONVENTIONS Methods and Variables: - Use underscore_case for all methods and variables - Examples: user_name, calculate_total(), get_user_data() Constants: - Use UPPERCASE_WITH_UNDERSCORES - Examples: MAX_UPLOAD_SIZE, DEFAULT_TIMEOUT Classes in /rsx/ Directory: - Use Like_This_With_Underscores format - Examples: Index_Controller, User_Model, Frontend_Bundle - Matches RSX naming patterns for auto-discovery Classes in /system/app/RSpade/ (Framework): - Use Like_This_With_Underscores where appropriate - Exception: When extending Laravel classes, use Laravel's PascalCase - Default for framework internals: PascalCase (existing Laravel convention) Critical Rule - Case-Sensitive Files: NEVER create files with same name but different case in same directory. Examples to avoid: Helpers.php and helpers.php This breaks Windows/macOS compatibility and triggers critical errors. FILENAME CONVENTIONS Basic Rule: Filenames in rsx/ should match their class/ID name (case-insensitive). Example: class Frontend_Calendar → frontend_calendar.php Short Name Pattern (Preferred): When directory structure provides context, filenames can use "short names" that omit prefix parts represented by the directory path. Requirements for valid short names: - Class/ID must have 3+ segments (2-segment names must use full filename) - Short name must have 2+ segments minimum - Directory path must contain the omitted prefix parts as contiguous sequence Algorithm: Filename is valid if [directory parts] + [filename parts] = [class parts] Example 1 - Clean prefix removal: Class: Frontend_Calendar_Event Directory: rsx/app/frontend/calendar/ Valid filenames: - calendar_event.blade.php (removes 'frontend') - frontend_calendar_event.blade.php (full name also valid) Example 2 - Partial overlap pattern: Class: Frontend_Settings_Account Directory: rsx/app/frontend/settings/account/ Valid filenames: - settings_account.blade.php (removes 'frontend', overlaps 'settings') - frontend_settings_account.blade.php (full name also valid) Why settings_account is valid: - Directory contains: [rsx, app, frontend, settings, account] - Filename parts: [settings, account] - Can we reconstruct class from dir + filename? YES → Directory has 'frontend' prefix → Filename 'settings_account' matches remaining parts → frontend + settings_account = Frontend_Settings_Account ✓ Example 3 - Too short (invalid): Class: Frontend_Calendar Directory: rsx/app/frontend/calendar/ Invalid: calendar.blade.php (only 1 segment - not allowed) Required: frontend_calendar.blade.php (must use full name) Partial Overlap Rationale: Allows semantic redundancy when it improves clarity. In nested directories, repeating the immediate parent directory name in the filename provides essential context without requiring the full prefix chain. Example benefits: - settings/account/settings_account.php is clearer than account/account.php - Filename alone (settings_account) indicates it's account settings - Maintains file prefix grouping for related files FILENAME CONVENTION EXCEPTIONS @FILENAME-CONVENTION-EXCEPTION Marker: Add this marker anywhere in a file to exempt it from filename matching rules. The framework will skip all filename convention checks for that file. Use cases: - Legacy files being migrated that cannot be renamed yet - Special cases that require non-standard naming - Files with intentional naming that violates conventions Example: [ // Auto-rename files to match RSX naming conventions 'auto_rename_files' => false, // Set to true to enable // Globally disable all filename convention checks 'ignore_filename_convention' => false, // Set to true to disable ] Auto-Rename Behavior (auto_rename_files = true): - During manifest build, files in ./rsx are automatically renamed - Only renames if target filename doesn't already exist - Manifest rebuilds after rename to reflect new file paths - Files with @FILENAME-CONVENTION-EXCEPTION are never renamed Examples of auto-renaming: - TestComponent1.jqhtml → test_component_1.jqhtml - UserController.php → user_controller.php - MyView.blade.php → my_view.blade.php If target exists: Normal violation thrown (conflict detected) Global Disable (ignore_filename_convention = true): - Disables ALL filename convention checks - No violations thrown for any files - Useful for projects with existing non-standard naming - More aggressive than @FILENAME-CONVENTION-EXCEPTION marker RSPADE FRAMEWORK INTERNAL METHOD NAMING For files in /system/app/RSpade/ only: Private and Protected Methods: - MUST start with underscore: _internal_method() - Purpose: Immediately identifies framework-internal methods - Application code prohibition: Never call methods starting with _ Public API Methods: - Must NOT start with underscore - These are stable public API for applications - Safe for RSX applications to use Example: // In /system/app/RSpade/Core/Something.php public static function public_api_method() { } // OK for apps private static function _internal_helper() { } // Framework only protected static function _process_data() { } // Framework only Rationale: - Methods starting with _ may change without notice in updates - Clear separation between stable API and internal implementation - Prevents applications from depending on internal methods CLASS DESIGN PHILOSOPHY Static by Default: - All classes should be static unless specific reason to instantiate - Classes are namespacing tools, not OOP for the sake of OOP - Direct access from anywhere without instantiation Exceptions for Instances: - ORM/Model records (represent database rows) - Resource handles (file handles, connections) - Service connectors needing mocking (AWS, payment gateways) - Artisan commands Avoid Dependency Injection: - No DI patterns or factory classes - Exception: Service connectors that need mocking for tests - Utility classes, helpers, managers, processors should be static STRING MANIPULATION PHILOSOPHY For Source Code Analysis: NO REGEX - Never use regex to parse PHP, JavaScript, or any programming language - Why regex fails for source code: * Cannot distinguish code from comments * Cannot understand syntactic context (strings, blocks, nesting) * Breaks when code formatting changes * Creates unmaintainable parsing logic - Use AST parsers instead: Extend PHP/JS AST functionality in manifest system to generate metadata for runtime analysis For General String Operations: Prefer Verbose Clarity - Default approach: Use explicit string functions over regex - Prefer readable multi-line operations: // ✅ GOOD - Clear and maintainable $parts = explode('/', $path); $filename = end($parts); $extension = substr($filename, strrpos($filename, '.') + 1); // ❌ AVOID - Unreadable regex preg_match('/\/([^\/]+)\.([^.]+)$/', $path, $matches); When Simple Regex IS Appropriate: - Well-established validation patterns using proven libraries - Very simple matching: single character classes, basic patterns - Performance-critical operations where regex proven faster AND simple Implementation Process: 1. Always propose solution to user first before implementing regex 2. Justify why string functions aren't sufficient 3. Document regex purpose in plain English 4. Prefer library solutions over custom regex patterns Source Code Analysis Guidelines: - Extend manifest AST parsers to capture needed metadata - Add metadata to manifest cache for runtime analysis - Use reflection and AST data instead of pattern matching - Consult user before any source code parsing implementation FUNCTION ORGANIZATION PHILOSOPHY Prefer Inline Code with Comments: - Comment above a few lines better than separate methods - Readability from clear comments and logical flow - Not arbitrary function boundaries Long Functions Are Acceptable: - When steps are sequential and single-purpose - Clear comments explain the flow - Related logic stays together Create Sub-Functions Only When: - Code called from multiple places or multiple times - Operation is significantly complex logical subset - Code needs independent unit testing - Abstraction genuinely improves understanding Avoid Functions for the Sake of Functions: - Don't create method to wrap file_get_contents($file) - Don't split sequential operations arbitrarily - Goal: Keep related logic together, not create maze of methods Sequential Operations Belong Together: - If step B always follows step A, same function with comments - Not arbitrarily split across multiple methods FILE STRUCTURE RESTRICTIONS PHP Files Without Classes (in ./rsx directory): PHP utility files without classes may only contain at global scope: - Function definitions - define() calls for constants - namespace declarations - use statements - declare() directives - Comments NOT allowed at global scope: - Control structures (if, for, while, switch) - Function calls (except define()) - Variable assignments - Object instantiation (new) - Include/require statements - Echo/print statements - Exit/die statements Rationale: Classless files are loaded on every request and should only define functions/constants, not execute code. Code that runs on every request should be in Main::init(), pre_dispatch() methods, or implemented in Laravel outside RSX. Example Valid PHP Utility File: user_id); return view('profile', compact('user_data')); } private static function _get_user_info($user_id) { // Framework internal method } } String Processing: // Preferred approach $parts = explode('/', $path); $filename = end($parts); $extension = substr($filename, strrpos($filename, '.') + 1); // Avoid unless necessary preg_match('/\/([^\/]+)\.([^.]+)$/', $path, $matches); Function Organization: // Good: Related steps together with comments public static function process_upload($file) { // Validate file type and size if (!in_array($file->extension(), ['jpg', 'png'])) { throw new Exception('Invalid file type'); } // Generate unique filename $filename = uniqid() . '.' . $file->extension(); // Store file and create database record $path = $file->storeAs('uploads', $filename); Upload_Model::create(['filename' => $filename, 'path' => $path]); return $filename; } SEE ALSO error_handling - Error handling patterns and shouldnt_happen() config_rsx - Framework configuration standards