wp-config icon indicating copy to clipboard operation
wp-config copied to clipboard

💥 Introduce fluent config API

Open retlehs opened this issue 11 months ago • 3 comments

Replace the static Config class with a new fluent API for wp-config v2. This new API provides a more expressive and maintainable way to manage WordPress configuration while maintaining the same strong safety guarantees of v1.

Key changes:

  • Introduce instance-based Config class with fluent methods
  • Add when() helper for conditional configuration
  • Add env() helper for setting environment variables as constants
  • Add WordPress-style hook system for extensible configuration
  • Include built-in environment variable loading
  • Remove need for separate environment config files
  • Bump minimum PHP version to 8.1

Breaking changes:

  • Static Config methods are removed
  • Config directory structure is simplified

New config file example

<?php

use function Env\env;
use Roots\WPConfig\Config;

$rootDir = dirname(__DIR__);
$webrootDir = $rootDir . '/web';
$config = new Config($rootDir);
$config->bootstrapEnv()
       ->do_action('config_loaded');

$config
    /**
     * DB settings
     */
    ->env(['DB_NAME', 'DB_USER', 'DB_PASSWORD'])
    ->env('DB_HOST', 'localhost')
    ->when(env('DB_SSL'), fn ($config) => $config->set('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL))
    ->set([
        'DB_CHARSET' => 'utf8mb4',
        'DB_COLLATE' => '',
    ])
    ->do_action('database_configured')

    /**
     * URLs
     */
    ->env('WP_HOME')
    ->env('WP_SITEURL', $config->get('WP_HOME') . '/wp')
    ->do_action('urls_configured')

    /**
     * Environment
     */
    ->env('WP_ENV', 'production')
    ->env('WP_ENVIRONMENT_TYPE', $config->get('WP_ENV'))
    ->do_action('environment_loaded')

    /**
     * Content directory
     */
    ->set([
        'CONTENT_DIR' => '/app',
        'WP_CONTENT_DIR' => $webrootDir . '/app',
        'WP_CONTENT_URL' => $config->get('WP_HOME') . '/app',
    ])

    /**
     * Authentication unique keys and salts
     */
    ->env([
        'AUTH_KEY', 'SECURE_AUTH_KEY', 'LOGGED_IN_KEY', 'NONCE_KEY',
        'AUTH_SALT', 'SECURE_AUTH_SALT', 'LOGGED_IN_SALT', 'NONCE_SALT',
    ])

    /**
     * Custom settings
     */
    ->set('AUTOMATIC_UPDATER_DISABLED', true)
    ->env('DISABLE_WP_CRON', false)
    ->set('DISALLOW_FILE_EDIT', true)
    ->env('DISALLOW_FILE_MODS', true)
    ->env('WP_POST_REVISIONS', true)

    /**
     * Performance settings
     */
    ->set('CONCATENATE_SCRIPTS', false)

    /**
     * Default debug settings
     */
    ->set('WP_DEBUG', (bool) env('WP_DEBUG', false))
    ->set('WP_DEBUG_DISPLAY', false)
    ->set('WP_DEBUG_LOG', false)
    ->set('SCRIPT_DEBUG', false)

    /**
     * Development settings
     */
    ->when($config->get('WP_ENV') === 'development', function($config) {
        $config->env('WP_DEBUG_LOG', true)->set([
            'SAVEQUERIES' => true,
            'WP_DEBUG' => true,
            'WP_DEBUG_DISPLAY' => true,
            'WP_DISABLE_FATAL_ERROR_HANDLER' => true,
            'SCRIPT_DEBUG' => true,
            'DISALLOW_INDEXING' => true,
            'DISALLOW_FILE_MODS' => false,
        ]);
    })

    /**
     * Handle reverse proxy settings
     */
    ->when(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https', function() {
        $_SERVER['HTTPS'] = 'on';
    })

    ->do_action('before_apply')
    ->apply();

$config->do_action('after_apply');

$table_prefix = env('DB_PREFIX') ?: 'wp_';

if (!defined('ABSPATH')) {
    define('ABSPATH', $webrootDir . '/wp/');
}

require_once ABSPATH . 'wp-settings.php';

retlehs avatar Feb 16 '25 17:02 retlehs