arraypress/wp-option-utils

A lean WordPress library for working with options and settings

dev-main 2025-07-02 17:13 UTC

This package is auto-updated.

Last update: 2025-09-02 14:44:20 UTC


README

A lightweight WordPress library for working with options and settings. Provides clean APIs for option operations, bulk management, pattern-based operations, and backup/restore functionality with advanced analysis tools.

Features

  • 🎯 Clean API: WordPress-style snake_case methods with consistent interfaces
  • 🚀 Advanced Operations: Array manipulation, type casting, nested access with dot notation
  • 📊 Bulk Management: Process multiple options efficiently with change detection
  • 🔍 Pattern Operations: Find, delete, or backup by prefix, suffix, or substring
  • 📈 Analysis Tools: Size calculation, type validation, comparison, and orphan detection
  • 💾 Backup & Restore: Safe option backup and restoration capabilities
  • 🔢 Numeric Operations: Increment/decrement values with atomic updates
  • 🔎 Type Safety: Built-in type checking and validation methods

Requirements

  • PHP 7.4 or later
  • WordPress 5.0 or later

Installation

composer require arraypress/wp-option-utils

Basic Usage

Single Option Operations

use ArrayPress\OptionUtils\Option;

// Basic operations
$exists = Option::exists( 'my_option' );
$value  = Option::get( 'my_option' );
$value  = Option::get_with_default( 'my_option', 'default' );

// Type casting
$int_value    = Option::get_cast( 'my_option', 'int', 0 );
$bool_value   = Option::get_cast( 'my_option', 'bool', false );
$array_value  = Option::get_cast( 'my_option', 'array', [] );
$float_value  = Option::get_cast( 'my_option', 'float', 0.0 );
$string_value = Option::get_cast( 'my_option', 'string', '' );

// Update/delete operations
Option::update( 'my_option', 'value' );
Option::update_if_changed( 'my_option', 'new_value' );
Option::delete( 'my_option' );

// Numeric operations
$new_value = Option::increment_value( 'counter', 1 );
$new_value = Option::decrement_value( 'counter', 1 );

// Array operations
Option::array_append( 'my_list', 'new_item' );
$contains = Option::array_contains( 'my_list', 'item' );
Option::array_remove_all( 'my_list', 'item' );
Option::array_remove_first( 'my_list', 'item' );
$count = Option::get_array_count( 'my_list' );

// Nested operations (dot notation)
$value = Option::get_nested( 'settings', 'theme.colors.primary', '#000' );
Option::set_nested( 'settings', 'theme.colors.primary', '#ff0000' );
Option::remove_nested( 'settings', 'theme.colors.primary' );

// Utility methods
$type    = Option::get_type( 'my_option' );
$size    = Option::get_size( 'my_option' );
$toggled = Option::toggle( 'boolean_option' );

// Type and size validation
if ( Option::is_type( 'my_option', 'array' ) ) {
	// Option is an array
}

if ( Option::is_large( 'my_option', 1024 ) ) {
	// Option exceeds 1KB
}

Multiple Option Operations

use ArrayPress\OptionUtils\Options;

// Bulk operations
$existing             = Options::exists( [ 'opt1', 'opt2', 'opt3' ] );
$values               = Options::get( [ 'opt1', 'opt2' ] );
$values_with_defaults = Options::get( [ 'opt1', 'opt2' ], true, 'default' );
$updated              = Options::update( [ 'key1' => 'value1', 'key2' => 'value2' ] );
$deleted_count        = Options::delete( [ 'opt1', 'opt2' ] );

// Backup and restore
$backup   = Options::backup( [ 'important_setting', 'api_key' ] );
$restored = Options::restore( $backup );

// Pattern-based operations
$pattern_options   = Options::get_by_pattern( 'my_plugin_', 'prefix' );
$prefix_options    = Options::get_by_prefix( 'my_plugin_' );
$suffix_options    = Options::get_by_suffix( '_cache' );
$substring_options = Options::get_by_substring( 'temp' );

// Pattern-based deletion
$deleted = Options::delete_by_prefix( 'my_plugin_' );
$deleted = Options::delete_by_suffix( '_cache' );
$deleted = Options::delete_by_substring( 'temp' );

// Analysis and comparison
$mismatches    = Options::compare_values( [ 'opt1' => 'expected' ] );
$filtered      = Options::filter_by_value( [ 'opt1', 'opt2' ], fn( $v ) => is_string( $v ) );
$total_size    = Options::get_size( [ 'opt1', 'opt2' ] );
$large_options = Options::find_large( [ 'opt1', 'opt2' ], 1024 );
$orphaned      = Options::find_orphaned( [ 'old_option1', 'old_option2' ] );

Advanced Examples

Complex Settings Management

// Initialize complex nested settings
$theme_config = [
	'colors'     => [
		'primary'   => '#007cba',
		'secondary' => '#50575e'
	],
	'typography' => [
		'font_size'   => 16,
		'line_height' => 1.5
	],
	'features'   => [
		'dark_mode'  => false,
		'animations' => true
	]
];

Option::update( 'theme_settings', $theme_config );

// Access and modify nested values
$primary_color = Option::get_nested( 'theme_settings', 'colors.primary', '#000000' );
$font_size     = Option::get_nested( 'theme_settings', 'typography.font_size', 14 );

// Update specific nested values
Option::set_nested( 'theme_settings', 'colors.primary', '#ff0000' );
Option::set_nested( 'theme_settings', 'features.dark_mode', true );

// Remove nested keys
Option::remove_nested( 'theme_settings', 'features.animations' );

// Toggle nested boolean values
$current_dark_mode = Option::get_nested( 'theme_settings', 'features.dark_mode', false );
Option::set_nested( 'theme_settings', 'features.dark_mode', ! $current_dark_mode );

Plugin Configuration Management

// Type-safe configuration with validation
class PluginConfig {
	private const PREFIX = 'my_plugin_';

	public static function get_api_key(): string {
		return Option::get_cast( self::PREFIX . 'api_key', 'string', '' );
	}

	public static function is_debug_enabled(): bool {
		return Option::get_cast( self::PREFIX . 'debug_mode', 'bool', false );
	}

	public static function get_cache_duration(): int {
		return Option::get_cast( self::PREFIX . 'cache_duration', 'int', 3600 );
	}

	public static function get_allowed_roles(): array {
		return Option::get_cast( self::PREFIX . 'allowed_roles', 'array', [ 'administrator' ] );
	}

	// Validate configuration
	public static function validate(): array {
		$errors = [];

		if ( ! Option::is_type( self::PREFIX . 'api_key', 'string' ) ) {
			$errors[] = 'API key must be a string';
		}

		if ( Option::is_large( self::PREFIX . 'allowed_roles', 1024 ) ) {
			$errors[] = 'Allowed roles configuration is too large';
		}

		return $errors;
	}
}

Bulk Operations and Cleanup

// Safe bulk updates with backup
$critical_options = [ 'siteurl', 'home', 'blogname', 'admin_email' ];
$backup           = Options::backup( $critical_options );

// Perform bulk update
$new_values = [
	'blogname'        => 'New Site Title',
	'blogdescription' => 'New tagline',
	'admin_email'     => 'new@example.com'
];
$updated    = Options::update( $new_values, true ); // Skip unchanged

// Restore if something went wrong
if ( count( $updated ) !== count( $new_values ) ) {
	Options::restore( $backup );
}

// Plugin cleanup with pattern matching
$plugin_options = Options::get_by_prefix( 'old_plugin_', false ); // Names only
$deleted_count  = Options::delete( $plugin_options );

// Find and clean large options
$all_options   = [ 'theme_options', 'plugin_cache', 'user_preferences' ];
$large_options = Options::find_large( $all_options, 50 * 1024 ); // > 50KB

foreach ( $large_options as $option => $size ) {
	error_log( "Large option found: {$option} ({$size} bytes)" );
	// Optionally compress or clean up
}

Performance Monitoring and Optimization

// Monitor option sizes for performance
function monitor_option_sizes() {
	$monitored_options = [
		'theme_options',
		'active_plugins',
		'wp_user_roles',
		'rewrite_rules'
	];

	$large_options = Options::find_large( $monitored_options, 10 * 1024 ); // > 10KB
	$total_size    = Options::get_size( $monitored_options );

	if ( $total_size > 100 * 1024 ) { // > 100KB total
		// Log warning or trigger optimization
		error_log( "Large options detected. Total size: {$total_size} bytes" );
	}

	return [
		'large_options' => $large_options,
		'total_size'    => $total_size
	];
}

// Configuration validation with type checking
function validate_plugin_config( $plugin_prefix ) {
	$config_options = Options::get_by_prefix( $plugin_prefix );
	$type_errors    = [];

	foreach ( $config_options as $option => $value ) {
		// Check for expected types based on option name
		if ( str_contains( $option, '_count' ) && ! Option::is_type( $option, 'integer' ) ) {
			$type_errors[] = "{$option} should be an integer";
		}

		if ( str_contains( $option, '_enabled' ) && ! Option::is_type( $option, 'boolean' ) ) {
			$type_errors[] = "{$option} should be a boolean";
		}

		if ( str_contains( $option, '_list' ) && ! Option::is_type( $option, 'array' ) ) {
			$type_errors[] = "{$option} should be an array";
		}
	}

	return $type_errors;
}

Array and List Management

// Feature flag management
Option::update( 'enabled_features', [] );

// Add features dynamically
Option::array_append( 'enabled_features', 'dark_mode' );
Option::array_append( 'enabled_features', 'advanced_search' );
Option::array_append( 'enabled_features', 'user_analytics' );

// Check if feature is enabled
if ( Option::array_contains( 'enabled_features', 'dark_mode' ) ) {
	// Enable dark mode functionality
}

// Remove specific features
Option::array_remove_first( 'enabled_features', 'user_analytics' );

// Get feature count
$feature_count = Option::get_array_count( 'enabled_features' );

// Manage user preferences as nested arrays
Option::set_nested( 'user_preferences', 'notifications.email', true );
Option::set_nested( 'user_preferences', 'notifications.sms', false );
Option::set_nested( 'user_preferences', 'display.theme', 'dark' );

$email_notifications = Option::get_nested( 'user_preferences', 'notifications.email', true );

API Reference

Option Class (Single Options)

Core Operations:

  • exists( string $option ): bool
  • get( string $option, $default = false )
  • get_with_default( string $option, $default )
  • get_cast( string $option, string $cast_type, $default = null )
  • update( string $option, $value ): bool
  • update_if_changed( string $option, $value ): bool
  • delete( string $option ): bool

Numeric Operations:

  • increment_value( string $option, int $amount = 1 )
  • decrement_value( string $option, int $amount = 1 )

Array Operations:

  • array_contains( string $option, $value ): bool
  • array_append( string $option, $value ): bool
  • array_remove_all( string $option, $value ): bool
  • array_remove_first( string $option, $value ): bool
  • get_array_count( string $option ): int

Nested Operations:

  • get_nested( string $option, string $key, $default = null )
  • set_nested( string $option, string $key, $value ): bool
  • remove_nested( string $option, string $key ): bool

Utility Methods:

  • get_type( string $option ): ?string
  • get_size( string $option ): int
  • toggle( string $option ): ?bool
  • is_type( string $option, string $type ): bool
  • is_large( string $option, int $size_limit = 1048576 ): bool

Options Class (Multiple Options)

Core Operations:

  • exists( array $option_names ): array
  • get( array $option_names, bool $include_nonexistent = false, $default = false ): array
  • update( array $options, bool $skip_unchanged = true ): array
  • delete( array $option_names ): int

Backup & Restore:

  • backup( array $option_names ): array
  • restore( array $backup ): array

Pattern Operations:

  • get_by_pattern( string $pattern, string $type = 'prefix' ): array
  • get_by_prefix( string $prefix, bool $include_values = true ): array
  • get_by_suffix( string $suffix, bool $include_values = true ): array
  • get_by_substring( string $substring, bool $include_values = true ): array
  • delete_by_pattern( string $pattern, string $type = 'exact' ): int
  • delete_by_prefix( string $prefix ): int
  • delete_by_suffix( string $suffix ): int
  • delete_by_substring( string $substring ): int

Analysis & Comparison:

  • compare_values( array $expected_values, bool $strict = true ): array
  • filter_by_value( array $option_names, callable $callback ): array
  • get_size( array $option_names ): int
  • find_large( array $option_names, int $size_limit = 1048576 ): array
  • find_orphaned( array $option_names, array $prefixes = [] ): array

Key Features

  • Type Safety: Robust type casting and validation with get_cast() and is_type() methods
  • Dot Notation: Access nested array values with simple string keys like 'settings.theme.color'
  • Atomic Updates: Change detection prevents unnecessary database writes
  • Pattern Matching: Flexible pattern-based operations for cleanup and discovery
  • Backup Safety: Built-in backup and restore capabilities for critical operations
  • Performance Monitoring: Size calculation and analysis tools with is_large() and find_large()
  • Bulk Efficiency: Optimized multi-option operations with minimal database queries
  • Comprehensive Analysis: Value comparison, type checking, and orphan detection tools

Requirements

  • PHP 7.4+
  • WordPress 5.0+

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the GPL-2.0-or-later License.

Support