VOOZH about

URL: https://deepwiki.com/mathsgod/light/3.6-configuration-and-feature-flags

⇱ Configuration and Feature Flags | mathsgod/light | DeepWiki


Loading...
Last indexed: 31 January 2026 (cf9511)
Menu

Configuration and Feature Flags

Purpose and Scope

The Light\App class manages application configuration through three primary sources: environment variables (.env file), the database-stored Config model, and YAML files (menus.yml, permissions.yml). This multi-layered approach separates infrastructure credentials from runtime settings and default values. This document covers:

  1. Environment variables - Static configuration for database, JWT secrets, OAuth credentials, and cookies
  2. Config model - Dynamic database-stored settings for mode, feature flags, token expiration, and custom values
  3. YAML configuration files - Default menus and permissions loaded during App initialization
  4. App class methods - How configuration is accessed and utilized throughout the framework

For RBAC permission system details, see page 3.4. For menu filtering based on permissions, see page 8.3.


Configuration Architecture Overview

The framework uses a dual-layer configuration system to separate immutable infrastructure settings from dynamic application preferences.


Sources: src/App.php57-129 src/Model/Config.php1-24 src/Controller/AppController.php1-151


Environment Variables Configuration

Environment variables provide static configuration that cannot be changed at runtime. These are typically loaded from a .env file and accessed via the $_ENV superglobal.

Database Connection Configuration

The database connection requires the following environment variables:

VariablePurposeExample
DATABASE_HOSTNAMEMySQL server hostnamelocalhost
DATABASE_DATABASEDatabase namelightapp
DATABASE_USERNAMEDatabase userroot
DATABASE_PASSWORDDatabase passwordsecret
DATABASE_PORTMySQL port3306
DATABASE_CHARSETCharacter setutf8mb4

These are consumed by the mathsgod/light-db package for database connection initialization.

Security and Authentication Configuration

VariablePurposeUsage Location
JWT_SECRETSecret key for JWT signingsrc/App.php615
GOOGLE_CLIENT_IDGoogle OAuth client IDOAuth integration
RP_IDWebAuthn relying party IDsrc/App.php764-766

Timezone Configuration

The timezone can be set via the TZ environment variable:


Sources: src/App.php62-64 README.md9-17 README.md24-27

Cookie Configuration

Cookie behavior can be customized through environment variables used in the JWT token handling:

VariablePurposeDefault
COOKIE_SAMESITESameSite attributeLax
COOKIE_DOMAINCookie domainEmpty
COOKIE_SECURESecure flagfalse
COOKIE_PARTITIONEDPartitioned flag for HTTPSNot set

Sources: src/App.php627-640


Database-Stored Configuration (Config Model)

The Config model provides persistent, runtime-changeable configuration stored in a MySQL table.

Config Model Structure


Sources: src/Model/Config.php1-24

The Config model exposes three fields through GraphQL:

  • config_id: Integer primary key
  • name: String configuration key (acts as unique identifier)
  • value: String configuration value

Static Value() Lookup Method

The most common way to access configuration is through the static Config::Value() method:


This method:

  1. Queries the database for a config with the specified name
  2. Returns the value if found
  3. Returns the default parameter if not found
  4. Returns null if not found and no default is provided

Sources: src/Model/Config.php15-23


Configuration Loading

Configuration is loaded at two distinct phases: application initialization and on-demand during request processing.

Initialization-Time Loading

During App::__construct(), the following configuration is loaded:


Sources: src/App.php59-147

Runtime Configuration Access

Configuration can be accessed during request processing through two methods:

  1. Static lookup: Config::Value(name, default)
  2. Instance lookup: Config::Get(['name' => name])

Sources: src/Model/Config.php15-22 src/App.php233-284

Configuration Reading Sequence

The typical sequence for reading configuration values:

  1. Call Config::Value(name, default) or Config::Get(['name' => name])
  2. Query executed: SELECT * FROM Config WHERE name = ?
  3. If found: return config->value
  4. If not found: return default parameter or null

Sources: src/Model/Config.php15-22

Mode Determination

The application mode controls debug output, cache lifetime, and GraphQL error verbosity. Mode is determined during App::__construct() by reading the mode configuration from the database.

Mode Loading Logic


Sources: src/App.php104-119

Mode Effects on System Behavior

AspectDevelopment ModeProduction Mode
Config ValueAny value except "prod""prod"
Debug Flagtruefalse
Cache Lifetime15 seconds0 (disabled)
GraphQL Error DetailsIncludes traces and debug messagesMinimal error information
Response FormatDebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::INCLUDE_TRACEStandard format

Implementation:


Sources: src/App.php104-121

Mode Checking at Runtime

The isDevMode() method determines whether to include debug information in responses:


Used in response formatting:


Sources: src/App.php581-584 src/App.php160-164

Mode Fallback Strategy

If the database is not yet initialized or the Config table doesn't exist, the system falls back to development mode. This ensures the application can start even during initial setup or database migration.

Sources: src/App.php116-119

Mail Configuration

The getMailer() method demonstrates complex configuration reading with multiple related settings:

Config NamePurposeType
mail_driverTransport typesmtp, gmail, sendmail, qmail
mail_hostSMTP serverString
mail_usernameSMTP usernameString
mail_passwordSMTP passwordString
mail_portSMTP portInteger
mail_encryptionEncryption typetls, ssl
mail_fromSender emailString
mail_from_nameSender display nameString
mail_reply_toReply-to emailString
mail_reply_to_nameReply-to display nameString

Sources: src/App.php212-264

Feature Flags

Feature flags are boolean or list-based configuration values that enable or disable system capabilities. Unlike mode, which affects global behavior, feature flags control specific subsystems.

Core Feature Flags

Config KeyTypePurposeCheck MethodDefault
two_factor_authenticationBooleanEnable TOTP 2FA requirementisTwoFactorAuthentication()false
file_managerBooleanShow file manager in menuisFileManagerEnabled()false
revisionCSV ListModels with audit trailisRevisionEnabled(model)Empty

Sources: src/App.php476-478 src/App.php594-600 src/App.php789-802

Feature Flag Implementation Patterns

Boolean Feature Flags

Two-factor authentication feature flag:


File manager feature flag:


Sources: src/App.php476-478 src/App.php594-600

List-Based Feature Flags

The revision feature flag stores a comma-separated list of model names:


Usage example: If revision config contains "User,Role,Config", then:

  • isRevisionEnabled("User") returns true
  • isRevisionEnabled("Session") returns false

Sources: src/App.php789-802

Feature Flag Effects


Sources: src/App.php174-190

Common Configuration Keys

The following table lists all configuration keys used throughout the framework:

Config KeyTypePurposeDefaultUsed In
modeStringApplication mode (dev/prod)"dev"src/App.php107
two_factor_authenticationBooleanEnable 2FA requirementfalsesrc/App.php477
file_managerBooleanEnable file manager UIfalsesrc/App.php596
revisionCSV StringModels with audit trailEmptysrc/App.php791
fsJSON ArrayFile system configurations[]src/App.php697
menusJSON ArrayCustom menu definitions[]src/App.php588
access_token_expireIntegerJWT access token seconds900src/App.php605
refresh_token_expireIntegerJWT refresh token seconds604800src/App.php611
mail_driverStringMail transport typeN/Asrc/App.php237
mail_hostStringSMTP hostnameN/Asrc/App.php260
mail_usernameStringSMTP usernameN/Asrc/App.php261
mail_passwordStringSMTP passwordN/Asrc/App.php262
mail_portIntegerSMTP portN/Asrc/App.php263
mail_encryptionStringSMTP encryption (tls/ssl)N/Asrc/App.php264
mail_fromStringSender email addressN/Asrc/App.php267
mail_from_nameStringSender display nameN/Asrc/App.php269
mail_reply_toStringReply-to email addressN/Asrc/App.php276
mail_reply_to_nameStringReply-to display nameN/Asrc/App.php277

Sources: src/App.php104-802


Configuration Updates via GraphQL

Configuration can be updated at runtime through GraphQL mutations in the AppController.

Single Configuration Update

The updateAppConfig mutation updates a single configuration value:


Implementation:


This method:

  1. Looks up existing config by name
  2. Creates new config if not found
  3. Updates the value
  4. Saves to database

Sources: src/Controller/AppController.php62-72

Bulk Configuration Updates

The updateAppConfigs mutation updates multiple configurations and invalidates the cache:


Implementation:


Key differences from single update:

  • Processes multiple configs in one transaction
  • Clears all caches after updates to ensure consistency

Sources: src/Controller/AppController.php41-57

Menu Configuration Update

Menus have a dedicated mutation that stores them as JSON:


Sources: src/Controller/AppController.php80-91

Configuration Update Flow


Sources: src/Controller/AppController.php41-57

Access Control for Configuration Updates

All configuration update mutations require:

  • Authentication via #[Logged] annotation
  • Permission config.update via #[Right('config.update')] annotation

The menu.update permission is required specifically for menu updates.

Sources: src/Controller/AppController.php37 src/Controller/AppController.php76


Cache Invalidation Strategy

Configuration changes may affect cached data throughout the application. The updateAppConfigs mutation handles this by clearing all caches:


This ensures:

  • GraphQL schema cache is regenerated with new config
  • RBAC permission cache reflects new settings
  • Any cached configuration values are reloaded

Individual config updates (updateAppConfig) do not automatically clear the cache. For immediate effect, use updateAppConfigs or manually restart the application.

Sources: src/Controller/AppController.php54


Configuration Reading Examples

Reading with Default Values


Reading Boolean Configuration


Sources: src/App.php454-457

Reading JSON Configuration


Sources: src/App.php651-671

Reading CSV Configuration


Sources: src/App.php743-756


Configuration Data Types

The Config model stores all values as strings in the database. Application code interprets these strings based on context:

TypeStorage FormatParsing PatternExample
StringPlain stringDirect usemode"prod"
IntegerNumeric stringintval(Config::Value())access_token_expire"900"900
BooleanTruthy stringConfig::Value() ? true : falsetwo_factor_authentication"1"true
JSON ObjectJSON-encodedjson_decode(value, true)fs'[{"name":"local"}]' → array
CSV ListComma-separatedexplode(",", value)revision"User,Role"["User","Role"]

Type Interpretation Examples

Integer parsing:


Boolean parsing:


JSON parsing:


CSV parsing:


No automatic type coercion occurs - each calling context is responsible for parsing the string value appropriately.

Sources: src/App.php602-612 src/App.php476-478 src/App.php696-715 src/App.php789-802


YAML Configuration Files

The Light framework uses YAML files to define default system configuration that is loaded during App::__construct(). These files provide baseline values that can be overridden by database configuration.

menus.yml - System Default Menus

The menus.yml file defines the default menu structure for the application. This file is located at the project root and is loaded during menu initialization:


Loading sequence:

  1. Yaml::parseFile(dirname(__DIR__) . '/menus.yml') loads the default menu structure
  2. getCustomMenus() loads additional menus from Config model with name "menus"
  3. Feature flags (e.g., file_manager) conditionally add system menus
  4. All menu arrays are merged into $this->menus

Each menu item can specify:

  • label - Display text
  • to - Route path
  • icon - Icon identifier
  • permission - Required permission(s) to view the menu item
  • children - Nested menu items

Sources: src/App.php174-191

permissions.yml - Default RBAC Permissions

The permissions.yml file defines the default permission assignments for system roles. This file is located at the project root and is loaded during RBAC initialization:


Loading sequence:

  1. System roles (Administrators, Power Users, Users, Everyone) are created with hierarchy
  2. Yaml::parseFile(dirname(__DIR__) . '/permissions.yml') loads default permission mappings
  3. Each role gets permissions via addRolePermissions(role, permissionsArray)
  4. Permission table records add additional permissions for roles and individual users
  5. UserRole table records associate users with their roles

YAML structure:


Sources: src/App.php306-365

YAML File Overrides

YAML files provide defaults, but runtime configuration can override or extend these values:

YAML FileOverride SourceOverride Method
menus.ymlConfig model name="menus"getCustomMenus() returns JSON array
permissions.ymlPermission tableDatabase records queried during loadRbac()

Database overrides are additive - they extend rather than replace YAML defaults. This allows system administrators to customize menus and permissions without modifying files.

Sources: src/App.php174-191 src/App.php338-365 src/App.php586-592


Integration with Other Systems

Configuration in Menu System

The menu system demonstrates the three-layer configuration approach:

Layer 1: YAML Defaults


Layer 2: Database Custom Menus


Layer 3: Feature Flag Conditional Menus


This layered approach allows default menus in version control, customization in the database, and feature-driven conditional menus.

Sources: src/App.php174-191

Configuration in RBAC Loading

The RBAC system loads from multiple configuration sources:

Default permissions from YAML:


Database overrides from Permission table:


User-role associations from UserRole table:


Sources: src/App.php306-365

Configuration in User Preferences

User-specific settings (preferences, styles, language, menu) are stored directly on the User model, not in the Config table. These are managed through separate mutations in AppController:

  • updateMyStyle() / updateMyStyles() - User UI preferences
  • updateMyLanguage() - User language preference
  • updateMyMenu() - User custom menu

Sources: src/Controller/AppController.php110-149


Summary

The Light framework configuration system provides:

  1. Two-layer architecture: Static environment variables for infrastructure, dynamic database configs for application settings
  2. Simple access pattern: Config::Value(name, default) for reading, GraphQL mutations for writing
  3. Type flexibility: String storage with contextual parsing for integers, booleans, JSON, CSV
  4. Cache management: Automatic cache invalidation on bulk updates
  5. Access control: RBAC-protected configuration updates
  6. Audit trail: All config changes logged via Light\Model base class

The system balances security (credentials in environment variables), flexibility (runtime config changes), and observability (automatic change logging).

Refresh this wiki

On this page