3
3
// Prevent direct access
4
4
defined ('ABSPATH ' ) || exit;
5
5
6
- class Site_Deploy_Manager {
7
-
6
+ class Site_Deploy_Manager
7
+ {
8
+
8
9
private static $ instance = null ;
9
10
10
11
/**
11
12
* Constructor
12
13
*/
13
- public function __construct () {
14
- add_action ('admin_menu ' , array ($ this , 'deploy_manager_menu ' ));
14
+ public function __construct ()
15
+ {
16
+ add_action ('admin_menu ' , array ($ this , 'setup_admin_menus ' ));
15
17
add_action ('admin_enqueue_scripts ' , array ($ this , 'deploy_manager_scripts ' ));
16
18
add_action ('wp_ajax_trigger_deployment ' , array ($ this , 'handle_deployment ' ));
17
19
add_action ('admin_init ' , array ($ this , 'register_settings ' ));
18
- add_action ('admin_menu ' , array ($ this , 'add_settings_page ' ));
19
20
}
20
21
21
- /**
22
- * Initialize the plugin
23
- */
24
- public function init () {
25
- register_activation_hook (__FILE__ , array ($ this , 'deploy_manager_install ' ));
26
- }
27
22
28
- public function add_settings_page () {
23
+ public function setup_admin_menus ()
24
+ {
25
+ // Add main menu
26
+ add_menu_page (
27
+ 'Deploy Site ' ,
28
+ 'Deploy ' ,
29
+ 'manage_options ' ,
30
+ 'deploy-manager ' ,
31
+ array ($ this , 'deploy_manager_page ' ),
32
+ 'dashicons-upload ' ,
33
+ 100
34
+ );
35
+
36
+ // Add settings submenu
29
37
add_submenu_page (
30
38
'deploy-manager ' ,
31
39
'Deploy Settings ' ,
@@ -36,9 +44,10 @@ public function add_settings_page() {
36
44
);
37
45
}
38
46
39
- public function register_settings () {
47
+ public function register_settings ()
48
+ {
40
49
register_setting ('deploy_manager_settings ' , 'site_deploy_webhook_url ' );
41
-
50
+
42
51
add_settings_section (
43
52
'deploy_manager_main ' ,
44
53
'Deployment Settings ' ,
@@ -55,13 +64,15 @@ public function register_settings() {
55
64
);
56
65
}
57
66
58
- public function webhook_url_callback () {
67
+ public function webhook_url_callback ()
68
+ {
59
69
$ webhook_url = get_option ('site_deploy_webhook_url ' );
60
70
echo '<input type="url" name="site_deploy_webhook_url" value=" ' . esc_attr ($ webhook_url ) . '" class="regular-text"> ' ;
61
71
}
62
72
63
- public function render_settings_page () {
64
- ?>
73
+ public function render_settings_page ()
74
+ {
75
+ ?>
65
76
<div class="wrap">
66
77
<h1>Deploy Settings</h1>
67
78
<form method="post" action="options.php">
@@ -72,48 +83,34 @@ public function render_settings_page() {
72
83
?>
73
84
</form>
74
85
</div>
75
- <?php
76
- }
77
-
78
- /**
79
- * Add admin menu item
80
- */
81
- public function deploy_manager_menu () {
82
- add_menu_page (
83
- 'Deploy Site ' ,
84
- 'Deploy ' ,
85
- 'manage_options ' ,
86
- 'deploy-manager ' ,
87
- array ($ this , 'deploy_manager_page ' ),
88
- 'dashicons-upload ' ,
89
- 100
90
- );
86
+ <?php
91
87
}
92
88
93
89
/**
94
90
* Create database table on activation
95
91
*/
96
- public function deploy_manager_install () {
92
+ public function deploy_manager_install ()
93
+ {
97
94
global $ wpdb ;
98
95
$ table_name = $ wpdb ->prefix . 'deployment_logs ' ;
99
-
96
+
100
97
// Check if table exists first
101
- if ($ wpdb ->get_var ("SHOW TABLES LIKE ' $ table_name' " ) != $ table_name ) {
98
+ if ($ wpdb ->get_var ("SHOW TABLES LIKE ' $ table_name' " ) != $ table_name ) {
102
99
$ charset_collate = $ wpdb ->get_charset_collate ();
103
-
100
+
104
101
$ sql = "CREATE TABLE $ table_name (
105
102
id mediumint(9) NOT NULL AUTO_INCREMENT,
106
103
deploy_time datetime DEFAULT CURRENT_TIMESTAMP,
107
104
status varchar(20) NOT NULL,
108
105
response_message text,
109
106
PRIMARY KEY (id)
110
107
) $ charset_collate; " ;
111
-
108
+
112
109
require_once (ABSPATH . 'wp-admin/includes/upgrade.php ' );
113
110
dbDelta ($ sql );
114
-
111
+
115
112
// Verify table was created
116
- if ($ wpdb ->get_var ("SHOW TABLES LIKE ' $ table_name' " ) != $ table_name ) {
113
+ if ($ wpdb ->get_var ("SHOW TABLES LIKE ' $ table_name' " ) != $ table_name ) {
117
114
error_log ('Failed to create deployment logs table ' );
118
115
}
119
116
}
@@ -122,22 +119,25 @@ public function deploy_manager_install() {
122
119
/**
123
120
* Enqueue scripts and styles
124
121
*/
125
- public function deploy_manager_scripts ($ hook ) {
126
- if ($ hook != 'toplevel_page_deploy-manager ' ) return ;
127
-
128
- wp_enqueue_script ('deploy-manager-js ' ,
129
- SITE_DEPLOY_PLUGIN_URL . 'assets/js/deploy-manager.js ' ,
130
- array (),
131
- SITE_DEPLOY_VERSION ,
122
+ public function deploy_manager_scripts ($ hook )
123
+ {
124
+ if ($ hook != 'toplevel_page_deploy-manager ' ) return ;
125
+
126
+ wp_enqueue_script (
127
+ 'deploy-manager-js ' ,
128
+ SITE_DEPLOY_PLUGIN_URL . 'assets/js/deploy-manager.js ' ,
129
+ array (),
130
+ SITE_DEPLOY_VERSION ,
132
131
true
133
132
);
134
-
133
+
135
134
wp_localize_script ('deploy-manager-js ' , 'deployManagerData ' , array (
136
135
'ajaxurl ' => admin_url ('admin-ajax.php ' ),
137
136
'nonce ' => wp_create_nonce ('deploy-manager-nonce ' )
138
137
));
139
-
140
- wp_enqueue_style ('deploy-manager-css ' ,
138
+
139
+ wp_enqueue_style (
140
+ 'deploy-manager-css ' ,
141
141
SITE_DEPLOY_PLUGIN_URL . 'assets/css/deploy-manager.css ' ,
142
142
array (),
143
143
SITE_DEPLOY_VERSION
@@ -147,62 +147,79 @@ public function deploy_manager_scripts($hook) {
147
147
/**
148
148
* Handle the deployment AJAX request
149
149
*/
150
- public function handle_deployment () {
151
- check_ajax_referer ('deploy-manager-nonce ' , 'nonce ' );
152
-
153
- if (!current_user_can ('manage_options ' )) {
154
- wp_send_json_error ('Unauthorized access ' );
155
- }
156
-
157
- $ webhook_url = get_option ('site_deploy_webhook_url ' , '' );
158
-
159
- if (empty ($ webhook_url )) {
160
- wp_send_json_error ('Webhook URL not configured ' );
150
+ public function handle_deployment ()
151
+ {
152
+ $ lock_key = 'deploy_request_lock ' ;
153
+
154
+ if (get_transient ($ lock_key )) {
155
+ wp_send_json_error ('Request already in progress ' );
156
+ return ;
161
157
}
162
-
163
- $ response = wp_remote_post ($ webhook_url , array (
164
- 'method ' => 'POST ' ,
165
- 'timeout ' => 45 ,
166
- 'headers ' => array ('Content-Type ' => 'application/json ' ),
167
- 'body ' => json_encode (array ('trigger ' => 'manual ' ))
168
- ));
169
-
170
- global $ wpdb ;
171
- $ table_name = $ wpdb ->prefix . 'deployment_logs ' ;
172
-
173
- if (is_wp_error ($ response )) {
174
- $ wpdb ->insert ($ table_name , array (
175
- 'status ' => 'failed ' ,
176
- 'response_message ' => $ response ->get_error_message ()
177
- ));
178
- wp_send_json_error ($ response ->get_error_message ());
179
- } else {
180
- $ wpdb ->insert ($ table_name , array (
181
- 'status ' => 'success ' ,
182
- 'response_message ' => wp_remote_retrieve_body ($ response )
158
+
159
+ // Set 60-second lock
160
+ set_transient ($ lock_key , true , 60 );
161
+
162
+ try {
163
+ check_ajax_referer ('deploy-manager-nonce ' , 'nonce ' );
164
+
165
+ if (!current_user_can ('manage_options ' )) {
166
+ wp_send_json_error ('Unauthorized access ' );
167
+ }
168
+
169
+ $ webhook_url = get_option ('site_deploy_webhook_url ' , '' );
170
+
171
+ if (empty ($ webhook_url )) {
172
+ wp_send_json_error ('Webhook URL not configured ' );
173
+ }
174
+
175
+ $ response = wp_remote_post ($ webhook_url , array (
176
+ 'method ' => 'POST ' ,
177
+ 'timeout ' => 45 ,
178
+ 'headers ' => array ('Content-Type ' => 'application/json ' ),
179
+ 'body ' => json_encode (array ('trigger ' => 'manual ' ))
183
180
));
184
- wp_send_json_success ('Deployment triggered successfully ' );
181
+
182
+ global $ wpdb ;
183
+ $ table_name = $ wpdb ->prefix . 'deployment_logs ' ;
184
+
185
+ if (is_wp_error ($ response )) {
186
+ $ wpdb ->insert ($ table_name , array (
187
+ 'status ' => 'failed ' ,
188
+ 'response_message ' => $ response ->get_error_message ()
189
+ ));
190
+ wp_send_json_error ($ response ->get_error_message ());
191
+ } else {
192
+ $ wpdb ->insert ($ table_name , array (
193
+ 'status ' => 'success ' ,
194
+ 'response_message ' => wp_remote_retrieve_body ($ response )
195
+ ));
196
+ wp_send_json_success ('Deployment triggered successfully ' );
197
+ }
198
+ } finally {
199
+ delete_transient ($ lock_key );
185
200
}
186
201
}
187
202
188
203
/**
189
204
* Render the admin page
190
205
*/
191
- public function deploy_manager_page () {
206
+ public function deploy_manager_page ()
207
+ {
192
208
global $ wpdb ;
193
209
$ table_name = $ wpdb ->prefix . 'deployment_logs ' ;
194
210
$ logs = $ wpdb ->get_results ("SELECT * FROM $ table_name ORDER BY deploy_time DESC LIMIT 10 " );
195
-
211
+
196
212
include SITE_DEPLOY_PLUGIN_DIR . 'admin/views/deploy-page.php ' ;
197
213
}
198
214
199
215
/**
200
216
* Get singleton instance
201
217
*/
202
- public static function get_instance () {
218
+ public static function get_instance ()
219
+ {
203
220
if (null === self ::$ instance ) {
204
221
self ::$ instance = new self ();
205
222
}
206
223
return self ::$ instance ;
207
224
}
208
- }
225
+ }
0 commit comments