@@ -41,38 +41,34 @@ class WebhooksAdmin {
41
41
*/
42
42
public function __construct ( WebhookRepositoryInterface $ repository ) {
43
43
$ this ->repository = $ repository ;
44
-
45
- add_action ( 'admin_menu ' , [ $ this , 'add_admin_menu ' ] );
46
- add_action ( 'admin_enqueue_scripts ' , [ $ this , 'enqueue_assets ' ] );
47
- add_action ( 'admin_post_graphql_webhook_save ' , [ $ this , 'handle_webhook_save ' ] );
48
- add_action ( 'admin_post_graphql_webhook_delete ' , [ $ this , 'handle_webhook_delete ' ] );
49
- add_action ( 'admin_init ' , [ $ this , 'handle_admin_actions ' ] );
50
- add_action ( 'wp_ajax_test_webhook ' , [ $ this , 'ajax_test_webhook ' ] );
51
44
}
52
45
53
46
/**
54
- * Optionally initialize additional admin hooks .
47
+ * Initialize the admin functionality .
55
48
*
56
49
* @return void
57
50
*/
58
51
public function init (): void {
52
+ add_action ( 'admin_menu ' , [ $ this , 'add_admin_menu ' ] );
53
+ add_action ( 'admin_enqueue_scripts ' , [ $ this , 'enqueue_assets ' ] );
59
54
add_action ( 'admin_init ' , [ $ this , 'handle_actions ' ] );
55
+ add_action ( 'wp_ajax_test_webhook ' , [ $ this , 'ajax_test_webhook ' ] );
60
56
}
61
57
62
58
/**
63
- * Registers the top-level "Webhooks" admin menu.
59
+ * Registers the webhooks submenu under the GraphQL admin menu.
64
60
*
65
61
* @return void
66
62
*/
67
63
public function add_admin_menu (): void {
68
- add_menu_page (
69
- __ ( 'Webhooks ' , 'wp-graphql-headless-webhooks ' ),
64
+ // Add submenu under GraphQL menu using the correct parent slug
65
+ add_submenu_page (
66
+ 'graphiql-ide ' ,
67
+ __ ( 'GraphQL Webhooks ' , 'wp-graphql-headless-webhooks ' ),
70
68
__ ( 'Webhooks ' , 'wp-graphql-headless-webhooks ' ),
71
69
'manage_options ' ,
72
70
self ::ADMIN_PAGE_SLUG ,
73
- [ $ this , 'render_admin_page ' ],
74
- 'dashicons-rss ' ,
75
- 25
71
+ [ $ this , 'render_admin_page ' ]
76
72
);
77
73
}
78
74
@@ -97,6 +93,11 @@ public function get_admin_url( array $args = [] ): string {
97
93
* @return void
98
94
*/
99
95
public function enqueue_assets ( string $ hook ): void {
96
+ // Only enqueue on our admin page
97
+ if ( false === strpos ( $ hook , self ::ADMIN_PAGE_SLUG ) ) {
98
+ return ;
99
+ }
100
+
100
101
wp_enqueue_style (
101
102
'graphql-webhooks-admin ' ,
102
103
WPGRAPHQL_HEADLESS_WEBHOOKS_PLUGIN_URL . 'assets/css/admin.css ' ,
@@ -136,24 +137,6 @@ private function get_header_row_template(): string {
136
137
return ob_get_clean ();
137
138
}
138
139
139
- /**
140
- * Handles admin actions from the webhooks page.
141
- *
142
- * @return void
143
- */
144
- public function handle_actions (): void {
145
- if ( ! isset ( $ _GET ['page ' ] ) || self ::ADMIN_PAGE_SLUG !== $ _GET ['page ' ] ) {
146
- return ;
147
- }
148
-
149
- if ( isset ( $ _POST ['action ' ] ) && 'save_webhook ' === $ _POST ['action ' ] ) {
150
- $ this ->handle_webhook_save ();
151
- }
152
-
153
- if ( isset ( $ _GET ['action ' ] ) && 'delete ' === $ _GET ['action ' ] && isset ( $ _GET ['webhook_id ' ] ) ) {
154
- $ this ->handle_webhook_delete ();
155
- }
156
- }
157
140
158
141
/**
159
142
* Checks if the current user has permission to manage options.
@@ -227,44 +210,55 @@ public function handle_webhook_save() {
227
210
}
228
211
229
212
/**
230
- * Handles deleting a webhook .
213
+ * Handles admin actions from the webhooks page .
231
214
*
232
215
* @return void
233
216
*/
234
- public function handle_webhook_delete () {
235
- // To be implemented: Individual deletes are handled through the list table's handle_row_actions.
217
+ public function handle_actions (): void {
218
+ if ( ! isset ( $ _REQUEST ['page ' ] ) || self ::ADMIN_PAGE_SLUG !== $ _REQUEST ['page ' ] ) {
219
+ return ;
220
+ }
221
+
222
+ // Handle save action
223
+ if ( isset ( $ _POST ['action ' ] ) && 'save_webhook ' === $ _POST ['action ' ] ) {
224
+ $ this ->handle_webhook_save ();
225
+ }
226
+
227
+ // Handle delete action
228
+ if ( isset ( $ _GET ['action ' ] ) && 'delete ' === $ _GET ['action ' ] && isset ( $ _GET ['webhook ' ] ) ) {
229
+ $ this ->handle_webhook_delete ();
230
+ }
236
231
}
237
232
238
233
/**
239
- * Handles bulk admin actions (such as bulk delete) .
234
+ * Handles single webhook deletion .
240
235
*
241
236
* @return void
242
237
*/
243
- public function handle_admin_actions () {
244
- if (
245
- ( isset ( $ _REQUEST ['action ' ] ) && 'delete ' === $ _REQUEST ['action ' ] ) ||
246
- ( isset ( $ _REQUEST ['action2 ' ] ) && 'delete ' === $ _REQUEST ['action2 ' ] )
247
- ) {
248
- if ( ! $ this ->verify_admin_permission () || ! $ this ->verify_nonce ( 'bulk-webhooks ' , '_wpnonce ' ) ) {
249
- return ;
250
- }
251
-
252
- $ webhook_ids = isset ( $ _REQUEST ['webhook ' ] ) ? array_map ( 'intval ' , (array ) $ _REQUEST ['webhook ' ] ) : [];
253
- $ deleted = 0 ;
254
-
255
- foreach ( $ webhook_ids as $ webhook_id ) {
256
- if ( $ this ->repository ->delete ( $ webhook_id ) ) {
257
- $ deleted ++;
258
- }
259
- }
238
+ private function handle_webhook_delete (): void {
239
+ // Verify permissions
240
+ if ( ! $ this ->verify_admin_permission () ) {
241
+ return ;
242
+ }
260
243
261
- if ( $ deleted > 0 ) {
262
- wp_redirect ( add_query_arg ( [ 'deleted ' => $ deleted ], $ this ->get_admin_url () ) );
263
- exit ;
264
- }
244
+ // Get webhook ID
245
+ $ webhook_id = intval ( $ _GET ['webhook ' ] );
246
+ $ nonce = isset ( $ _GET ['_wpnonce ' ] ) ? $ _GET ['_wpnonce ' ] : '' ;
247
+
248
+ // Verify nonce
249
+ if ( ! wp_verify_nonce ( $ nonce , 'delete-webhook- ' . $ webhook_id ) ) {
250
+ wp_die ( __ ( 'Security check failed. ' , 'wp-graphql-headless-webhooks ' ) );
265
251
}
252
+
253
+ // Delete webhook
254
+ $ deleted = $ this ->repository ->delete ( $ webhook_id ) ? 1 : 0 ;
255
+
256
+ // Redirect with result
257
+ wp_redirect ( add_query_arg ( [ 'deleted ' => $ deleted ], remove_query_arg ( [ 'action ' , 'webhook ' , '_wpnonce ' ], $ this ->get_admin_url () ) ) );
258
+ exit ;
266
259
}
267
260
261
+
268
262
/**
269
263
* Renders the webhooks admin page.
270
264
*
0 commit comments