Configuration

WPZylos uses a centralized configuration system that prevents hardcoded values and enables environment-specific settings.

Configuration Files

Configuration files live in the config/ directory:

config/
+-- app.php       # Application settings
+-- services.php  # Service providers
+-- database.php  # Database settings (optional)
+-- cache.php     # Cache settings (optional)

config/app.php

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Application Debug Mode
    |--------------------------------------------------------------------------
    */
    'debug' => defined('WP_DEBUG') && WP_DEBUG,

    /*
    |--------------------------------------------------------------------------
    | Application Timezone
    |--------------------------------------------------------------------------
    */
    'timezone' => wp_timezone_string(),

    /*
    |--------------------------------------------------------------------------
    | Autoloaded Service Providers
    |--------------------------------------------------------------------------
    */
    'providers' => [
        \Vendor\MyPlugin\Providers\AppServiceProvider::class,
        \Vendor\MyPlugin\Providers\RouteServiceProvider::class,
        \Vendor\MyPlugin\Providers\AdminServiceProvider::class,
    ],
];

Accessing Configuration

Use the ConfigRepository to access configuration values:

use WPZylos\Framework\Config\ConfigRepository;

// In a service provider or controller
public function __construct(private ConfigRepository $config)
{
}

public function handle(): void
{
    // Get a value
    $debug = $this->config->get('app.debug');

    // Get with default
    $timezone = $this->config->get('app.timezone', 'UTC');

    // Check if exists
    if ($this->config->has('database.connection')) {
        // ...
    }

    // Get entire section
    $appConfig = $this->config->get('app');
}

Dot Notation

Configuration supports dot notation for nested values:

// config/database.php
return [
    'connections' => [
        'default' => [
            'driver' => 'mysql',
            'charset' => 'utf8mb4',
        ],
    ],
];

// Access
$charset = $config->get('database.connections.default.charset');

Dynamic Configuration

Configuration values can reference WordPress functions:

<?php
// config/app.php
return [
    'url' => home_url(),
    'admin_url' => admin_url(),
    'uploads_path' => wp_upload_dir()['basedir'],
];

Environment-Specific Configuration

Use WordPress constants for environment detection:

<?php
// config/app.php
return [
    'debug' => defined('WP_DEBUG') && WP_DEBUG,

    'log_level' => match (true) {
        defined('WP_DEBUG') && WP_DEBUG => 'debug',
        defined('WP_ENV') && WP_ENV === 'staging' => 'info',
        default => 'error',
    },

    'cache_ttl' => defined('WP_DEBUG') && WP_DEBUG ? 0 : 3600,
];

Plugin Context vs Configuration

Plugin Context holds identity (slug, prefix, text domain) that never changes.

Configuration holds behavior that may vary by environment.

// Context: Identity (constant)
$context->slug();       // 'my-plugin'
$context->prefix();     // 'mp_'
$context->textDomain(); // 'my-plugin'

// Config: Behavior (variable)
$config->get('app.debug');     // true/false
$config->get('cache.ttl');     // 3600
$config->get('api.timeout');   // 30

Why We Did It This Way

Centralized Configuration

Problem: Hardcoded values scattered across plugin files make maintenance difficult and environment switching error-prone.

Solution: All configurable values live in config/ files, loaded once at boot.

Benefits:

  • Single source of truth for settings
  • Easy environment-specific overrides
  • No magic strings in business logic

No Global Constants for Configuration

Problem: Using define() for configuration pollutes the global namespace and can conflict with other plugins.

Solution: Configuration is container-bound and accessed via dependency injection.

// Bad: Avoid: Global constants
define('MY_PLUGIN_DEBUG', true);

// Good: Prefer: Container-bound configuration
class MyController {
    public function __construct(private ConfigRepository $config) {}

    public function handle() {
        if ($this->config->get('app.debug')) {
            // ...
        }
    }
}

WordPress Integration

Problem: Some settings depend on WordPress being fully loaded.

Solution: Configuration files are PHP and can call WordPress functions:

// Safe: WordPress is loaded when config is read
return [
    'site_url' => get_site_url(),
    'user_locale' => get_user_locale(),
];

Configuration Caching

In production, configuration can be cached for performance:

// Generate cached config
$config->cache($path);

// Load from cache
$config = ConfigRepository::loadCached($path);

Next Steps