silverassist / wp-settings-hub
Centralized settings hub for Silver Assist WordPress plugins. Provides a unified Settings > Silver Assist menu with auto-registration and dynamic dashboard.
Installs: 1 763
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
pkg:composer/silverassist/wp-settings-hub
Requires
- php: ^8.2
Requires (Dev)
- dealerdirect/phpcodesniffer-composer-installer: ^1.0
- php-stubs/wordpress-stubs: ^6.6
- php-stubs/wp-cli-stubs: ^2.10
- phpcompatibility/phpcompatibility-wp: ^2.1
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.6
- slevomat/coding-standard: ^8.0
- squizlabs/php_codesniffer: ^3.7 || ^4.0
- szepeviktor/phpstan-wordpress: ^1.3 || ^2.0
- wp-coding-standards/wpcs: ^3.0
- yoast/phpunit-polyfills: ^1.1.0
README
Centralized settings hub for Silver Assist WordPress plugins. Provides a unified top-level "Silver Assist" menu with auto-registration, dynamic dashboard, and optional cross-plugin navigation tabs.
Features
- 🎯 Auto-Registration: Plugins register themselves without central configuration
- 📊 Dynamic Dashboard: Automatically generates overview of all installed Silver Assist plugins
- 🔗 Cross-Plugin Navigation: Optional tabs for seamless navigation between plugin settings
- 🎨 Beautiful UI: WordPress-native design with cards and tabs
- 🏢 Top-Level Menu: Professional menu structure with custom icon and submenus
- 🔒 Type-Safe: Full PHP 8.2+ type hints and PHPDocs
- ✅ Well-Tested: Comprehensive test suite with PHPUnit 10
- 📦 Composer-Ready: Easy integration via
composer require
Requirements
- PHP: 8.2 or higher
- WordPress: 6.5 or higher
- Composer: For package management
Installation
Install via Composer:
composer require silverassist/wp-settings-hub
Menu Structure
The hub creates a top-level menu in the WordPress admin:
WordPress Admin
├── Dashboard
├── Posts
├── Media
├── ...
├── Silver Assist 🛡️ ← Top-level menu
│ ├── Dashboard ← Hub overview
│ ├── Post Revalidate ← Your plugin
│ └── [More plugins...] ← More plugins
└── ...
Dashboard URL: admin.php?page=silver-assist
Plugin URLs: admin.php?page={your-plugin-slug}
Quick Start
1. Basic Integration
Add this to your plugin's main file or initialization class:
<?php use SilverAssist\SettingsHub\SettingsHub; // Register your plugin with the hub $hub = SettingsHub::get_instance(); $hub->register_plugin( 'my-plugin', // Unique slug 'My Plugin', // Display name [ $this, 'render_settings' ], // Callback to render settings [ 'description' => 'Description of my plugin', 'version' => '1.0.0', 'tab_title' => 'My Plugin', // Optional: custom tab title ] );
2. Render Your Settings Page
Your callback function receives no parameters and should render the settings content:
public function render_settings(): void { ?> <div class="silverassist-plugin-settings"> <p>Your plugin settings go here.</p> <form method="post" action="options.php"> <?php settings_fields( 'my_plugin_settings' ); do_settings_sections( 'my_plugin_settings' ); submit_button(); ?> </form> </div> <?php }
3. That's It!
Your plugin will now appear:
- A card on the dashboard showing name, description, and version
- A submenu item under "Silver Assist"
- Optional: in the tabs navigation if tabs are enabled
Complete Example
See integration-guide.php for a complete working example.
Advanced Usage
Disable Tabs Navigation
If you prefer not to show tabs for cross-plugin navigation:
$hub = SettingsHub::get_instance(); $hub->enable_tabs( false );
Check Plugin Registration
$hub = SettingsHub::get_instance(); if ( $hub->is_plugin_registered( 'my-plugin' ) ) { // Plugin is registered }
Get All Registered Plugins
$hub = SettingsHub::get_instance(); $plugins = $hub->get_plugins(); foreach ( $plugins as $slug => $plugin ) { echo $plugin['name'] . ' - ' . $plugin['version']; }
Get Parent Menu Slug
$hub = SettingsHub::get_instance(); $parent_slug = $hub->get_parent_slug(); // Returns 'silver-assist'
Add Custom Dashboard Actions
Add action buttons to your plugin's dashboard card:
$hub->register_plugin( 'my-plugin', 'My Plugin', [ $this, 'render_settings' ], [ 'description' => 'Plugin description', 'version' => '1.0.0', 'actions' => [ // URL-based action (direct link) [ 'label' => 'Documentation', 'url' => 'https://docs.example.com', 'class' => 'button', ], // Callback-based action (JavaScript) [ 'label' => 'Check Updates', 'callback' => function() { ?> alert('Checking for updates...'); <?php }, 'class' => 'button button-primary', ], ], ] );
Integration with wp-github-updater:
If you're using the silverassist/wp-github-updater package, you can add a "Check Updates" button:
⚠️ Important: When implementing update checks, you must properly synchronize both WordPress caches (plugin-specific and system-wide) to ensure the Updates page displays current information. See IMPLEMENTATION.md for the complete implementation with cache synchronization.
use SilverAssist\WpGithubUpdater\Updater; use SilverAssist\WpGithubUpdater\UpdaterConfig; class My_Plugin { private ?Updater $updater = null; public function init_updater(): void { if ( ! class_exists( UpdaterConfig::class ) ) { return; } $config = new UpdaterConfig( __FILE__, 'SilverAssist/my-plugin', array( 'text_domain' => 'my-plugin', 'ajax_action' => 'my_plugin_check_updates', 'ajax_nonce' => 'my_plugin_updates_nonce', ) ); $this->updater = new Updater( $config ); } public function register_with_hub(): void { $hub = SettingsHub::get_instance(); $actions = array(); // Add update checker if available if ( null !== $this->updater ) { $actions[] = array( 'label' => __( 'Check Updates', 'my-plugin' ), 'callback' => array( $this, 'render_update_check' ), 'class' => 'button', ); } $hub->register_plugin( 'my-plugin', 'My Plugin', array( $this, 'render_settings' ), array( 'description' => 'Plugin with GitHub updates', 'version' => '1.0.0', 'actions' => $actions, ) ); } // IMPORTANT: This is a simplified example. The complete implementation // requires proper cache clearing with delete_site_transient() and wp_update_plugins(). // See IMPLEMENTATION.md for the full code. public function render_update_check( string $slug ): void { ?> jQuery.post(ajaxurl, { action: 'my_plugin_check_updates', nonce: '<?php echo esc_js( wp_create_nonce( 'my_plugin_updates_nonce' ) ); ?>' }).done(function(response) { if (response.success && response.data.update_available) { alert('<?php esc_html_e( 'Update available!', 'my-plugin' ); ?>'); window.location.href = '<?php echo esc_js( admin_url( 'update-core.php' ) ); ?>'; } else { alert('<?php esc_html_e( 'Already up to date', 'my-plugin' ); ?>'); } }); <?php } }
Using WordPress Action Hooks
You can also add custom actions using the silverassist_settings_hub_plugin_actions hook:
add_action( 'silverassist_settings_hub_plugin_actions', function( $slug, $plugin ) { if ( $slug !== 'my-plugin' ) { return; } ?> <a href="<?php echo esc_url( admin_url( 'tools.php?page=diagnostics' ) ); ?>" class="button"> <?php esc_html_e( 'Run Diagnostics', 'my-plugin' ); ?> </a> <?php }, 10, 2 );
Hook Parameters:
$slug(string): The plugin slug$plugin(array): The plugin data including name, callback, description, version, etc.
Integration Examples
See integration-guide.php for complete working examples including:
- Basic plugin integration
- wp-github-updater integration with "Check Updates" button
- Custom action buttons
- WordPress action hook usage
API Reference
SettingsHub::get_instance()
Get singleton instance of the hub.
Returns: SettingsHub - Singleton instance
register_plugin( string $slug, string $name, callable $callback, array $args = [] )
Register a plugin with the settings hub.
Parameters:
$slug(string): Unique plugin slug (e.g.,'post-revalidate')$name(string): Display name for the plugin$callback(callable): Function to render the plugin's settings page$args(array, optional): Additional arguments:description(string): Short description shown on dashboard cardversion(string): Plugin version numbertab_title(string): Custom title for tab (defaults to$name)actions(array): Custom action buttons for the dashboard card
Action Button Structure:
Each action in the actions array should be an associative array with:
label(string, required): Button texturl(string, optional): Direct link URL (for navigation)callback(callable, optional): JavaScript code to execute (for interactive actions)class(string, optional): CSS classes for the button (default:'button')
Example with Actions:
$hub->register_plugin( 'my-plugin', 'My Plugin', [ $this, 'render_settings' ], [ 'description' => 'Plugin description', 'version' => '1.0.0', 'actions' => [ [ 'label' => 'Check Updates', 'callback' => [ $this, 'render_update_check_script' ], 'class' => 'button', ], [ 'label' => 'Documentation', 'url' => 'https://docs.example.com', 'class' => 'button', ], ], ] );
Returns: void
enable_tabs( bool $enable )
Enable or disable tabs navigation.
Parameters:
$enable(bool):trueto enable tabs,falseto disable
Returns: void
is_tabs_enabled()
Check if tabs are enabled.
Returns: bool - true if enabled, false otherwise
get_plugins()
Get all registered plugins.
Returns: array - Associative array of registered plugins keyed by slug
is_plugin_registered( string $slug )
Check if a plugin is registered.
Parameters:
$slug(string): Plugin slug to check
Returns: bool - true if registered, false otherwise
get_parent_slug()
Get the parent menu slug.
Returns: string - Parent menu slug ('silver-assist')
Development
Install Dependencies
composer install
WordPress Test Suite (Required)
This package requires WordPress Test Suite for testing:
# Install WordPress Test Suite bash scripts/install-wp-tests.sh wordpress_test root 'root' localhost latest true # Set environment variable (add to your ~/.zshrc or ~/.bashrc for persistence) export WP_TESTS_DIR=/tmp/wordpress-tests-lib
Important: Tests require the WordPress Test Suite to be installed. The installation script downloads and configures WordPress core test suite in /tmp/wordpress-tests-lib.
On macOS, you may need to set the WP_TESTS_DIR environment variable because sys_get_temp_dir() returns a user-specific path.
Run All Quality Checks
./scripts/run-quality-checks.sh all
This runs:
- PHPCBF: Auto-fix code standards
- PHPCS: Check code standards (WordPress-Extra)
- PHPStan: Static analysis (Level 8)
- PHPUnit: Test suite with WP_UnitTestCase
Running Tests
# Run all tests (unit + integration) composer test # Run only unit tests vendor/bin/phpunit --testsuite unit # Run only integration tests vendor/bin/phpunit --testsuite integration # Run with coverage composer test:coverage
Test Suites:
- Unit Tests: Test individual methods and logic in isolation (10 tests)
- Integration Tests: Test complete WordPress integration including admin menus, rendering, and multi-plugin scenarios (8 tests)
Individual Checks
# Auto-fix code standards
composer phpcbf
### WordPress Test Suite (Required)
This package requires WordPress Test Suite for testing:
```bash
# Install WordPress Test Suite
bash scripts/install-wp-tests.sh wordpress_test root 'root' localhost latest true
Important: Tests require the WordPress Test Suite to be installed. The installation script above will download and configure WordPress core test suite in /tmp/wordpress-tests-lib.
Run All Quality Checks
./scripts/run-quality-checks.sh all
This runs:
- PHPCBF: Auto-fix code standards
- PHPCS: Check code standards (WordPress-Extra)
- PHPStan: Static analysis (Level 8)
- PHPUnit: Test suite (with WP_UnitTestCase if available)
Individual Checks
# Auto-fix code standards composer phpcbf # Check code standards composer phpcs # Run static analysis composer phpstan # Run tests composer phpunit # Run all (without auto-fix) composer qa
Quality Standards
- ✅ PHP 8.2+ with strict types
- ✅ WordPress Coding Standards (WPCS)
- ✅ PHPStan Level 8 - no type errors
- ✅ 100% test coverage for new features
- ✅ Full PHPDoc for all classes and methods
See CONTRIBUTING.md for detailed contribution guidelines.
Architecture
Singleton Pattern
The SettingsHub class uses the singleton pattern to ensure only one instance exists. This prevents duplicate menu creation and maintains a single source of truth for registered plugins.
Auto-Discovery
Plugins register themselves by calling register_plugin(). The hub automatically:
- Creates the parent "Silver Assist" menu (once)
- Adds the plugin as a submenu item
- Generates a dashboard card for the plugin
- Updates the tabs navigation (if enabled)
Hooks
The hub uses WordPress's admin_menu hook with priority 5 to register menus early. This ensures the parent menu exists before any submenus are registered.
License
This package is licensed under the PolyForm Noncommercial License 1.0.0.
TL;DR: Free for personal and noncommercial use. Commercial use requires a separate license.
Support
For issues, feature requests, or questions:
- Email: support@silverassist.com
Contributing
See CONTRIBUTING.md for detailed contribution guidelines.
Changelog
See CHANGELOG.md for version history and changes.
Made with ❤️ by Silver Assist