Skip to content

Commit a113fce

Browse files
committed
Add ConfigurationHelper for centralized config access
Introduces a ConfigurationHelper class to provide cached, singleton-based access to WPGraphQL Logging configuration. Refactors settings and config retrieval throughout the plugin to use this helper, improving performance, consistency, and cache management. Updates related classes and documentation to use the new approach and initializes automatic cache invalidation in the main plugin setup.
1 parent e3ab90e commit a113fce

File tree

8 files changed

+354
-37
lines changed

8 files changed

+354
-37
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Configuration Helper Usage Examples
2+
3+
The `ConfigurationHelper` class provides a centralized and cached way to access WPGraphQL Logging configuration. This class implements a singleton pattern to ensure configuration is only loaded once per request and provides convenient methods for accessing different configuration sections.
4+
5+
## Basic Usage
6+
7+
### Getting the Configuration Helper Instance
8+
9+
```php
10+
use WPGraphQL\Logging\Admin\Settings\ConfigurationHelper;
11+
12+
$config_helper = ConfigurationHelper::get_instance();
13+
```
14+
15+
### Getting Full Configuration
16+
17+
```php
18+
$config_helper = ConfigurationHelper::get_instance();
19+
$full_config = $config_helper->get_config();
20+
```
21+
22+
### Getting Configuration Sections
23+
24+
```php
25+
$config_helper = ConfigurationHelper::get_instance();
26+
27+
// Get basic configuration
28+
$basic_config = $config_helper->get_basic_config();
29+
30+
// Get data management configuration
31+
$data_management_config = $config_helper->get_data_management_config();
32+
33+
// Get any custom section
34+
$custom_section = $config_helper->get_section_config('custom_section', []);
35+
```
36+
37+
### Getting Specific Settings
38+
39+
```php
40+
$config_helper = ConfigurationHelper::get_instance();
41+
42+
// Get a specific setting from a section
43+
$log_level = $config_helper->get_setting('basic_configuration', 'log_level', 'info');
44+
45+
// Check if a feature is enabled
46+
$is_sanitization_enabled = $config_helper->is_enabled('data_management', 'data_sanitization_enabled');
47+
```
48+
49+
## Migration from Direct get_option() Usage
50+
51+
### Before (old approach):
52+
```php
53+
$full_config = get_option( WPGRAPHQL_LOGGING_SETTINGS_KEY, [] );
54+
$basic_config = $full_config['basic_configuration'] ?? [];
55+
$log_level = $basic_config['log_level'] ?? 'info';
56+
```
57+
58+
### After (using ConfigurationHelper):
59+
```php
60+
$config_helper = ConfigurationHelper::get_instance();
61+
$log_level = $config_helper->get_setting('basic_configuration', 'log_level', 'info');
62+
```
63+
64+
## Cache Management
65+
66+
### Clearing Cache
67+
```php
68+
$config_helper = ConfigurationHelper::get_instance();
69+
$config_helper->clear_cache(); // Clears cache, next access will reload from DB
70+
```
71+
72+
### Force Reload
73+
```php
74+
$config_helper = ConfigurationHelper::get_instance();
75+
$config_helper->reload_config(); // Clears cache and immediately reloads
76+
```
77+
78+
## Benefits
79+
80+
1. **Performance**: Configuration is cached in memory and only loaded once per request
81+
2. **Consistency**: Centralized access point prevents inconsistent configuration retrieval
82+
3. **Convenience**: Convenient methods for common access patterns
83+
4. **Cache Management**: Automatic cache invalidation when settings are updated
84+
5. **Type Safety**: Better type hints and documentation
85+
86+
## Automatic Cache Invalidation
87+
88+
The ConfigurationHelper automatically clears its cache when WordPress settings are updated. This is initialized in the main Plugin class:
89+
90+
```php
91+
// This is already set up in src/Plugin.php
92+
ConfigurationHelper::init_cache_hooks();
93+
```
94+
95+
The cache hooks listen for:
96+
- `update_option_{$option_key}`
97+
- `add_option_{$option_key}`
98+
- `delete_option_{$option_key}`
99+
100+
## Performance Notes
101+
102+
- Configuration is cached using WordPress's `wp_cache_*` functions
103+
- Multiple cache groups are used for optimal performance
104+
- Cache duration is set to 1 hour by default
105+
- In-memory caching ensures subsequent accesses within the same request are instant
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WPGraphQL\Logging\Admin\Settings;
6+
7+
/**
8+
* Configuration Helper class
9+
*
10+
* This class provides a centralized and cached way to access WPGraphQL Logging configuration.
11+
* It implements a singleton pattern to ensure configuration is only loaded once per request
12+
* and provides convenient methods for accessing different configuration sections.
13+
*
14+
* Usage Examples:
15+
* ```php
16+
* // Get the helper instance
17+
* $config = ConfigurationHelper::get_instance();
18+
*
19+
* // Get a specific setting
20+
* $log_level = $config->get_setting('basic_configuration', 'log_level', 'info');
21+
*
22+
* // Check if a feature is enabled
23+
* $is_enabled = $config->is_enabled('data_management', 'data_sanitization_enabled');
24+
*
25+
* // Get an entire configuration section
26+
* $basic_config = $config->get_basic_config();
27+
* ```
28+
*
29+
* @package WPGraphQL\Logging
30+
*
31+
* @since 0.0.1
32+
*/
33+
class ConfigurationHelper {
34+
/**
35+
* Cache group for configuration.
36+
*
37+
* @var string
38+
*/
39+
public const CACHE_GROUP = 'wpgraphql_logging_config';
40+
41+
/**
42+
* Cache duration in seconds (1 hour).
43+
*
44+
* @var int
45+
*/
46+
public const CACHE_DURATION = 3600;
47+
48+
/**
49+
* The cached configuration values.
50+
*
51+
* @var array<string, mixed>|null
52+
*/
53+
protected ?array $config = null;
54+
55+
/**
56+
* The single instance of this class.
57+
*
58+
* @var \WPGraphQL\Logging\Admin\Settings\ConfigurationHelper|null
59+
*/
60+
protected static ?ConfigurationHelper $instance = null;
61+
62+
/**
63+
* Get the singleton instance.
64+
*/
65+
public static function get_instance(): ConfigurationHelper {
66+
if ( null === self::$instance ) {
67+
self::$instance = new self();
68+
}
69+
70+
return self::$instance;
71+
}
72+
73+
/**
74+
* Get the full configuration array.
75+
*
76+
* @return array<string, mixed>
77+
*/
78+
public function get_config(): array {
79+
if ( null === $this->config ) {
80+
$this->load_config();
81+
}
82+
83+
return $this->config ?? [];
84+
}
85+
86+
/**
87+
* Get configuration for a specific section (tab).
88+
*
89+
* @param string $section The configuration section key.
90+
* @param array<string, mixed> $default_value Default value if section not found.
91+
*
92+
* @return array<string, mixed>
93+
*/
94+
public function get_section_config( string $section, array $default_value = [] ): array {
95+
$config = $this->get_config();
96+
return $config[ $section ] ?? $default_value;
97+
}
98+
99+
/**
100+
* Get a specific setting value from a configuration section.
101+
*
102+
* @param string $section The configuration section key.
103+
* @param string $setting_key The setting key within the section.
104+
* @param mixed $default_value Default value if setting not found.
105+
*/
106+
public function get_setting( string $section, string $setting_key, $default_value = null ): mixed {
107+
$section_config = $this->get_section_config( $section );
108+
return $section_config[ $setting_key ] ?? $default_value;
109+
}
110+
111+
/**
112+
* Get the basic configuration section.
113+
*
114+
* @return array<string, mixed>
115+
*/
116+
public function get_basic_config(): array {
117+
return $this->get_section_config( 'basic_configuration' );
118+
}
119+
120+
/**
121+
* Get the data management configuration section.
122+
*
123+
* @return array<string, mixed>
124+
*/
125+
public function get_data_management_config(): array {
126+
return $this->get_section_config( 'data_management' );
127+
}
128+
129+
/**
130+
* Check if a specific feature is enabled.
131+
*
132+
* @param string $section The configuration section.
133+
* @param string $setting_key The setting key for the feature.
134+
*/
135+
public function is_enabled( string $section, string $setting_key ): bool {
136+
return (bool) $this->get_setting( $section, $setting_key, false );
137+
}
138+
139+
/**
140+
* Clear the configuration cache.
141+
* This forces a reload of the configuration on the next access.
142+
*/
143+
public function clear_cache(): void {
144+
$this->config = null;
145+
$option_key = $this->get_option_key();
146+
wp_cache_delete( $option_key, self::CACHE_GROUP );
147+
wp_cache_delete( $option_key, $this->get_settings_group() );
148+
}
149+
150+
/**
151+
* Reload the configuration from the database.
152+
* This bypasses any cache and forces a fresh load.
153+
*/
154+
public function reload_config(): void {
155+
$this->clear_cache();
156+
$this->load_config();
157+
}
158+
159+
/**
160+
* Get the option key for the settings.
161+
*/
162+
public function get_option_key(): string {
163+
return (string) apply_filters( 'wpgraphql_logging_settings_group_option_key', WPGRAPHQL_LOGGING_SETTINGS_KEY );
164+
}
165+
166+
/**
167+
* Get the settings group for caching.
168+
*/
169+
public function get_settings_group(): string {
170+
return (string) apply_filters( 'wpgraphql_logging_settings_group_settings_group', WPGRAPHQL_LOGGING_SETTINGS_GROUP );
171+
}
172+
173+
/**
174+
* Hook into WordPress to clear cache when settings are updated.
175+
* This should be called during plugin initialization.
176+
*
177+
* @psalm-suppress PossiblyInvalidArgument
178+
*/
179+
public static function init_cache_hooks(): void {
180+
$instance = self::get_instance();
181+
$option_key = $instance->get_option_key();
182+
183+
// Clear cache when the option is updated.
184+
add_action( "update_option_{$option_key}", [ $instance, 'clear_cache' ] );
185+
add_action( "add_option_{$option_key}", [ $instance, 'clear_cache' ] );
186+
add_action( "delete_option_{$option_key}", [ $instance, 'clear_cache' ] );
187+
}
188+
189+
/**
190+
* Load the configuration from cache or database.
191+
*
192+
* @phpcs:disable WordPressVIPMinimum.Performance.LowExpiryCacheTime.CacheTimeUndetermined
193+
*/
194+
protected function load_config(): void {
195+
$option_key = $this->get_option_key();
196+
197+
$cache_duration = self::CACHE_DURATION;
198+
199+
// Try to get from wp_cache first (in-memory cache).
200+
$cached_config = wp_cache_get( $option_key, self::CACHE_GROUP );
201+
if ( is_array( $cached_config ) ) {
202+
$this->config = $cached_config;
203+
return;
204+
}
205+
206+
// Try to get from the WordPress object cache (could be Redis, Memcached, etc.).
207+
$cached_config = wp_cache_get( $option_key, $this->get_settings_group() );
208+
if ( is_array( $cached_config ) ) {
209+
$this->config = $cached_config;
210+
// Store in our custom cache group for faster access next time.
211+
wp_cache_set( $option_key, $cached_config, self::CACHE_GROUP, $cache_duration );
212+
return;
213+
}
214+
215+
// Load from database.
216+
$this->config = (array) get_option( $option_key, [] );
217+
218+
// Cache the result in both cache groups.
219+
wp_cache_set( $option_key, $this->config, self::CACHE_GROUP, $cache_duration );
220+
wp_cache_set( $option_key, $this->config, $this->get_settings_group(), $cache_duration );
221+
}
222+
}

plugins/wpgraphql-logging/src/Admin/Settings/Fields/Field/AbstractSettingsField.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace WPGraphQL\Logging\Admin\Settings\Fields\Field;
66

7+
use WPGraphQL\Logging\Admin\Settings\ConfigurationHelper;
78
use WPGraphQL\Logging\Admin\Settings\Fields\SettingsFieldInterface;
89

910
/**
@@ -84,7 +85,8 @@ public function render_field_callback( array $args ): void {
8485
$tab_key = (string) ( $args['tab_key'] ?? '' );
8586
$settings_key = (string) ( $args['settings_key'] ?? '' );
8687

87-
$option_value = (array) get_option( $settings_key, [] );
88+
$config_helper = ConfigurationHelper::get_instance();
89+
$option_value = $config_helper->get_config();
8890

8991
$id = $this->get_field_name( $settings_key, $tab_key, $this->get_id() );
9092

0 commit comments

Comments
 (0)