@@ -41,38 +41,34 @@ class WebhooksAdmin {
4141 */
4242 public function __construct ( WebhookRepositoryInterface $ repository ) {
4343 $ 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 ' ] );
5144 }
5245
5346 /**
54- * Optionally initialize additional admin hooks .
47+ * Initialize the admin functionality .
5548 *
5649 * @return void
5750 */
5851 public function init (): void {
52+ add_action ( 'admin_menu ' , [ $ this , 'add_admin_menu ' ] );
53+ add_action ( 'admin_enqueue_scripts ' , [ $ this , 'enqueue_assets ' ] );
5954 add_action ( 'admin_init ' , [ $ this , 'handle_actions ' ] );
55+ add_action ( 'wp_ajax_test_webhook ' , [ $ this , 'ajax_test_webhook ' ] );
6056 }
6157
6258 /**
63- * Registers the top-level "Webhooks" admin menu.
59+ * Registers the webhooks submenu under the GraphQL admin menu.
6460 *
6561 * @return void
6662 */
6763 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 ' ),
7068 __ ( 'Webhooks ' , 'wp-graphql-headless-webhooks ' ),
7169 'manage_options ' ,
7270 self ::ADMIN_PAGE_SLUG ,
73- [ $ this , 'render_admin_page ' ],
74- 'dashicons-rss ' ,
75- 25
71+ [ $ this , 'render_admin_page ' ]
7672 );
7773 }
7874
@@ -97,6 +93,11 @@ public function get_admin_url( array $args = [] ): string {
9793 * @return void
9894 */
9995 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+
100101 wp_enqueue_style (
101102 'graphql-webhooks-admin ' ,
102103 WPGRAPHQL_HEADLESS_WEBHOOKS_PLUGIN_URL . 'assets/css/admin.css ' ,
@@ -136,24 +137,6 @@ private function get_header_row_template(): string {
136137 return ob_get_clean ();
137138 }
138139
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- }
157140
158141 /**
159142 * Checks if the current user has permission to manage options.
@@ -227,44 +210,55 @@ public function handle_webhook_save() {
227210 }
228211
229212 /**
230- * Handles deleting a webhook .
213+ * Handles admin actions from the webhooks page .
231214 *
232215 * @return void
233216 */
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+ }
236231 }
237232
238233 /**
239- * Handles bulk admin actions (such as bulk delete) .
234+ * Handles single webhook deletion .
240235 *
241236 * @return void
242237 */
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+ }
260243
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 ' ) );
265251 }
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 ;
266259 }
267260
261+
268262 /**
269263 * Renders the webhooks admin page.
270264 *
0 commit comments