PluginProbe
WindPress – Tailwind CSS integration for WordPress / 3.2.87
WindPress – Tailwind CSS integration for WordPress v3.2.87
3.2.88 3.2.87 3.2.86 3.2.85 3.2.84 3.2.83 3.2.82 3.2.81 trunk 3.0.0 3.0.1 3.0.10 3.0.11 3.0.12 3.0.13 3.0.14 3.0.15 3.0.16 3.0.17 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 All 142 releases
windpress / src / Abilities / Loader.php

Loader.php in WindPress – Tailwind CSS integration for WordPress 3.2.87, at src/Abilities/Loader.php

184 lines 15.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of the WindPress package.
5 *
6 * (c) Joshua Gugun Siagian <suabahasa@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 declare (strict_types=1);
12 namespace WindPress\WindPress\Abilities;
13
14 use Exception;
15 /**
16 * Abilities API Loader
17 *
18 * Registers WindPress abilities with the WordPress Abilities API.
19 * Abilities provide a standardized way to expose plugin functionality
20 * to AI agents, automation tools, and other developers.
21 *
22 * @since 3.2.0
23 */
24 class Loader
25 {
26 /**
27 * Stores the instance, implementing a Singleton pattern.
28 */
29 private static self $instance;
30 /**
31 * The Singleton's constructor should always be private to prevent direct
32 * construction calls with the `new` operator.
33 */
34 private function __construct()
35 {
36 }
37 /**
38 * Singletons should not be cloneable.
39 */
40 private function __clone()
41 {
42 }
43 /**
44 * Singletons should not be restorable from strings.
45 *
46 * @throws Exception Cannot unserialize a singleton.
47 */
48 public function __wakeup()
49 {
50 throw new Exception('Cannot unserialize a singleton.');
51 }
52 /**
53 * This is the static method that controls the access to the singleton
54 * instance. On the first run, it creates a singleton object and places it
55 * into the static property. On subsequent runs, it returns the client existing
56 * object stored in the static property.
57 */
58 public static function get_instance(): self
59 {
60 if (!isset(self::$instance)) {
61 self::$instance = new self();
62 }
63 return self::$instance;
64 }
65 /**
66 * Initialize the Abilities API integration
67 *
68 * This method checks if the Abilities API is available (WordPress 6.9+ or via composer package)
69 * and registers the appropriate hooks for categories and abilities.
70 */
71 public function init(): void
72 {
73 // Check if Abilities API is available
74 if (!function_exists('wp_register_ability_category') || !function_exists('wp_register_ability')) {
75 return;
76 }
77 do_action('a!windpress/abilities/loader:init.start');
78 // Register ability categories on the categories init hook
79 add_action('wp_abilities_api_categories_init', fn() => $this->register_categories());
80 // Register abilities on the abilities init hook
81 add_action('wp_abilities_api_init', fn() => $this->register_abilities());
82 do_action('a!windpress/abilities/loader:init.end');
83 }
84 /**
85 * Register ability categories for WindPress
86 */
87 public function register_categories(): void
88 {
89 do_action('a!windpress/abilities/loader:register_categories.start');
90 // Configuration category
91 wp_register_ability_category('configuration', ['label' => __('Configuration', 'windpress'), 'description' => __('Abilities for retrieving and managing WindPress configuration.', 'windpress')]);
92 // Volume Management category (Simple File System)
93 wp_register_ability_category('volume-management', ['label' => __('Volume Management', 'windpress'), 'description' => __('Abilities for managing CSS/JS files in the WindPress Simple File System.', 'windpress')]);
94 /**
95 * Allow other plugins/themes to register additional ability categories.
96 *
97 * @since 3.2.0
98 */
99 do_action('a!windpress/abilities/loader:register_categories.end');
100 }
101 /**
102 * Register all WindPress abilities
103 */
104 public function register_abilities(): void
105 {
106 do_action('a!windpress/abilities/loader:register_abilities.start');
107 // Configuration
108 $this->register_get_config();
109 // Volume - Read operations
110 $this->register_get_volume_entries();
111 $this->register_get_volume_entry();
112 $this->register_get_volume_handlers();
113 // Volume - Write operations
114 $this->register_save_volume_entries();
115 $this->register_save_volume_entry();
116 // Volume - Delete operations
117 $this->register_delete_volume_entry();
118 // Volume - Utility operations
119 $this->register_reset_volume_entry();
120 /**
121 * Allow other plugins/themes to register additional abilities.
122 *
123 * @since 3.2.0
124 */
125 do_action('a!windpress/abilities/loader:register_abilities.end');
126 }
127 /**
128 * Register the get-config ability
129 */
130 private function register_get_config(): void
131 {
132 wp_register_ability('windpress/get-config', ['label' => __('Get Configuration', 'windpress'), 'description' => __('Retrieves the current WindPress configuration including Tailwind version, plugin settings, and enabled features.', 'windpress'), 'category' => 'configuration', 'input_schema' => [], 'output_schema' => ['type' => 'object', 'properties' => ['version' => ['type' => 'string', 'description' => __('WindPress plugin version.', 'windpress')], 'tailwind_version' => ['type' => 'integer', 'description' => __('Tailwind CSS version (3 or 4).', 'windpress')], 'settings' => ['type' => 'object', 'description' => __('Plugin settings and configuration options.', 'windpress')], 'data_dir' => ['type' => 'object', 'description' => __('WindPress data directory details.', 'windpress'), 'properties' => ['path' => ['type' => 'string', 'description' => __('Absolute path to the WindPress data directory.', 'windpress')], 'url' => ['type' => 'string', 'description' => __('URL to the WindPress data directory.', 'windpress')]]], 'cache_dir' => ['type' => 'object', 'description' => __('WindPress cache directory details.', 'windpress'), 'properties' => ['path' => ['type' => 'string', 'description' => __('Absolute path to the WindPress cache directory.', 'windpress')], 'url' => ['type' => 'string', 'description' => __('URL to the WindPress cache directory.', 'windpress')]]]]], 'execute_callback' => [\WindPress\WindPress\Abilities\Abilities\GetConfig::class, 'execute'], 'permission_callback' => fn() => current_user_can('manage_options'), 'meta' => ['annotations' => ['readonly' => \true, 'destructive' => \false, 'idempotent' => \true], 'show_in_rest' => \true]]);
133 }
134 /**
135 * Register the get-volume-entries ability
136 */
137 private function register_get_volume_entries(): void
138 {
139 wp_register_ability('windpress/get-volume-entries', ['label' => __('Get Volume Entries', 'windpress'), 'description' => __('Retrieves all files in the WindPress Simple File System including main.css, config files, and custom CSS/JS files.', 'windpress'), 'category' => 'volume-management', 'input_schema' => [], 'output_schema' => ['type' => 'array', 'items' => ['type' => 'object', 'properties' => ['name' => ['type' => 'string', 'description' => __('File name.', 'windpress')], 'relative_path' => ['type' => 'string', 'description' => __('Relative path from data directory.', 'windpress')], 'content' => ['type' => 'string', 'description' => __('File content.', 'windpress')], 'handler' => ['type' => 'string', 'description' => __('Handler type (internal or custom).', 'windpress')], 'signature' => ['type' => 'string', 'description' => __('Security signature for file operations.', 'windpress')], 'readonly' => ['type' => 'boolean', 'description' => __('Whether the file is read-only.', 'windpress')]]]], 'execute_callback' => [\WindPress\WindPress\Abilities\Abilities\GetVolumeEntries::class, 'execute'], 'permission_callback' => fn() => current_user_can('manage_options'), 'meta' => ['annotations' => ['readonly' => \true, 'destructive' => \false, 'idempotent' => \true], 'show_in_rest' => \true]]);
140 }
141 /**
142 * Register the get-volume-entry ability
143 */
144 private function register_get_volume_entry(): void
145 {
146 wp_register_ability('windpress/get-volume-entry', ['label' => __('Get Volume Entry', 'windpress'), 'description' => __('Retrieves a single file from the WindPress Simple File System by its relative path.', 'windpress'), 'category' => 'volume-management', 'input_schema' => ['type' => 'object', 'properties' => ['relative_path' => ['type' => 'string', 'description' => __('Relative path of the file to retrieve.', 'windpress')]], 'required' => ['relative_path']], 'output_schema' => ['type' => 'object', 'properties' => ['name' => ['type' => 'string', 'description' => __('File name.', 'windpress')], 'relative_path' => ['type' => 'string', 'description' => __('Relative path from data directory.', 'windpress')], 'content' => ['type' => 'string', 'description' => __('File content.', 'windpress')], 'handler' => ['type' => 'string', 'description' => __('Handler type (internal or custom).', 'windpress')], 'signature' => ['type' => 'string', 'description' => __('Security signature for file operations.', 'windpress')], 'readonly' => ['type' => 'boolean', 'description' => __('Whether the file is read-only.', 'windpress')]]], 'execute_callback' => [\WindPress\WindPress\Abilities\Abilities\GetVolumeEntry::class, 'execute'], 'permission_callback' => fn() => current_user_can('manage_options'), 'meta' => ['annotations' => ['readonly' => \true, 'destructive' => \false, 'idempotent' => \true], 'show_in_rest' => \true]]);
147 }
148 /**
149 * Register the get-volume-handlers ability
150 */
151 private function register_get_volume_handlers(): void
152 {
153 wp_register_ability('windpress/get-volume-handlers', ['label' => __('Get Volume Handlers', 'windpress'), 'description' => __('Retrieves available custom handlers for the WindPress Simple File System.', 'windpress'), 'category' => 'volume-management', 'input_schema' => [], 'output_schema' => ['type' => 'array', 'items' => ['type' => 'string'], 'description' => __('Array of available handler names.', 'windpress')], 'execute_callback' => [\WindPress\WindPress\Abilities\Abilities\GetVolumeHandlers::class, 'execute'], 'permission_callback' => fn() => current_user_can('manage_options'), 'meta' => ['annotations' => ['readonly' => \true, 'destructive' => \false, 'idempotent' => \true], 'show_in_rest' => \true]]);
154 }
155 /**
156 * Register the save-volume-entries ability
157 */
158 private function register_save_volume_entries(): void
159 {
160 wp_register_ability('windpress/save-volume-entries', ['label' => __('Save Volume Entries', 'windpress'), 'description' => __('Saves or updates multiple files in the WindPress Simple File System at once.', 'windpress'), 'category' => 'volume-management', 'input_schema' => ['type' => 'object', 'properties' => ['entries' => ['type' => 'array', 'items' => ['type' => 'object', 'properties' => ['name' => ['type' => 'string', 'description' => __('File name.', 'windpress')], 'relative_path' => ['type' => 'string', 'description' => __('Relative path from data directory.', 'windpress')], 'content' => ['type' => 'string', 'minLength' => 1, 'description' => __('File content.', 'windpress')], 'handler' => ['type' => 'string', 'description' => __('Handler type (internal or custom).', 'windpress')], 'signature' => ['type' => 'string', 'description' => __('Security signature for existing files.', 'windpress')]], 'required' => ['name', 'relative_path', 'content', 'handler']]]], 'required' => ['entries']], 'output_schema' => ['type' => 'object', 'properties' => ['success' => ['type' => 'boolean', 'description' => __('Whether the operation was successful.', 'windpress')], 'message' => ['type' => 'string', 'description' => __('Result message.', 'windpress')]]], 'execute_callback' => [\WindPress\WindPress\Abilities\Abilities\SaveVolumeEntries::class, 'execute'], 'permission_callback' => fn() => current_user_can('manage_options'), 'meta' => ['annotations' => ['readonly' => \false, 'destructive' => \true, 'idempotent' => \false], 'show_in_rest' => \true]]);
161 }
162 /**
163 * Register the save-volume-entry ability
164 */
165 private function register_save_volume_entry(): void
166 {
167 wp_register_ability('windpress/save-volume-entry', ['label' => __('Save Volume Entry', 'windpress'), 'description' => __('Saves or updates a single file in the WindPress Simple File System.', 'windpress'), 'category' => 'volume-management', 'input_schema' => ['type' => 'object', 'properties' => ['name' => ['type' => 'string', 'description' => __('File name.', 'windpress')], 'relative_path' => ['type' => 'string', 'description' => __('Relative path from data directory.', 'windpress')], 'content' => ['type' => 'string', 'minLength' => 1, 'description' => __('File content.', 'windpress')], 'handler' => ['type' => 'string', 'description' => __('Handler type (internal or custom).', 'windpress'), 'default' => 'internal'], 'signature' => ['type' => 'string', 'description' => __('Security signature for existing files.', 'windpress')]], 'required' => ['name', 'relative_path', 'content']], 'output_schema' => ['type' => 'object', 'properties' => ['success' => ['type' => 'boolean', 'description' => __('Whether the operation was successful.', 'windpress')], 'message' => ['type' => 'string', 'description' => __('Result message.', 'windpress')], 'entry' => ['type' => 'object', 'description' => __('The saved entry data.', 'windpress')]]], 'execute_callback' => [\WindPress\WindPress\Abilities\Abilities\SaveVolumeEntry::class, 'execute'], 'permission_callback' => fn() => current_user_can('manage_options'), 'meta' => ['annotations' => ['readonly' => \false, 'destructive' => \true, 'idempotent' => \false], 'show_in_rest' => \true]]);
168 }
169 /**
170 * Register the delete-volume-entry ability
171 */
172 private function register_delete_volume_entry(): void
173 {
174 wp_register_ability('windpress/delete-volume-entry', ['label' => __('Delete Volume Entry', 'windpress'), 'description' => __('Deletes a file from the WindPress Simple File System.', 'windpress'), 'category' => 'volume-management', 'input_schema' => ['type' => 'object', 'properties' => ['relative_path' => ['type' => 'string', 'description' => __('Relative path of the file to delete.', 'windpress')], 'signature' => ['type' => 'string', 'description' => __('Security signature for verification.', 'windpress')]], 'required' => ['relative_path', 'signature']], 'output_schema' => ['type' => 'object', 'properties' => ['success' => ['type' => 'boolean', 'description' => __('Whether the operation was successful.', 'windpress')], 'message' => ['type' => 'string', 'description' => __('Result message.', 'windpress')]]], 'execute_callback' => [\WindPress\WindPress\Abilities\Abilities\DeleteVolumeEntry::class, 'execute'], 'permission_callback' => fn() => current_user_can('manage_options'), 'meta' => ['annotations' => ['readonly' => \false, 'destructive' => \true, 'idempotent' => \true], 'show_in_rest' => \true]]);
175 }
176 /**
177 * Register the reset-volume-entry ability
178 */
179 private function register_reset_volume_entry(): void
180 {
181 wp_register_ability('windpress/reset-volume-entry', ['label' => __('Reset Volume Entry', 'windpress'), 'description' => __('Resets main.css or tailwind.config.js to their default content based on the current Tailwind version.', 'windpress'), 'category' => 'volume-management', 'input_schema' => ['type' => 'object', 'properties' => ['relative_path' => ['type' => 'string', 'enum' => ['main.css', 'tailwind.config.js', 'wizard.js', 'wizard.css'], 'description' => __('File to reset (main.css, tailwind.config.js, wizard.js, or wizard.css).', 'windpress')]], 'required' => ['relative_path']], 'output_schema' => ['type' => 'object', 'properties' => ['success' => ['type' => 'boolean', 'description' => __('Whether the operation was successful.', 'windpress')], 'message' => ['type' => 'string', 'description' => __('Result message.', 'windpress')], 'content' => ['type' => 'string', 'description' => __('The default file content.', 'windpress')]]], 'execute_callback' => [\WindPress\WindPress\Abilities\Abilities\ResetVolumeEntry::class, 'execute'], 'permission_callback' => fn() => current_user_can('manage_options'), 'meta' => ['annotations' => ['readonly' => \false, 'destructive' => \true, 'idempotent' => \true], 'show_in_rest' => \true]]);
182 }
183 }
184