PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / 2.7.0
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts v2.7.0
2.7.7 2.7.6 2.7.5 2.7.4 trunk 1.3 2.0.4 2.0.6 2.1.91 2.2.4 2.2.7 2.2.9 2.3.1 2.3.10 2.4.10 2.4.2 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.6.0 2.6.1 2.7.0 All 28 releases
insert-php / admin / ajax / ajax.php

ajax.php in Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts 2.7.0, at admin/ajax/ajax.php

411 lines 10.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Ajax requests handler
4 *
5 * @package Woody_Code_Snippets
6 */
7
8 // Exit if accessed directly
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Returns a list of available roles.
15 */
16 function wbcr_inp_ajax_get_user_roles() {
17 global $wp_roles;
18
19 if ( ! WINP_Plugin::app()->current_user_car() ) {
20 wp_die( - 1, 403 );
21 }
22
23 $snippet_id = WINP_HTTP::post( 'snippet_id', 0, 'intval' );
24
25 check_admin_referer( 'wbcr_inp_snippet_' . $snippet_id . '_conditions_metabox' );
26
27 $roles = $wp_roles->roles;
28
29 $values = [];
30 foreach ( $roles as $role_id => $role ) {
31 $values[] = [
32 'value' => $role_id,
33 'title' => $role['name'],
34 ];
35 }
36
37 $values[] = [
38 'value' => 'guest',
39 'title' => __( 'Guest', 'insert-php' ),
40 ];
41
42 $result = [
43 'values' => $values,
44 ];
45
46 echo json_encode( $result );
47 exit;
48 }
49
50 add_action( 'wp_ajax_wbcr_inp_ajax_get_user_roles', 'wbcr_inp_ajax_get_user_roles' );
51
52 /**
53 * Returns a list of public post types.
54 */
55 function wbcr_inp_ajax_get_post_types() {
56
57 if ( ! WINP_Plugin::app()->current_user_car() ) {
58 wp_die( - 1, 403 );
59 }
60
61 $snippet_id = WINP_HTTP::post( 'snippet_id', 0, 'intval' );
62
63 check_admin_referer( 'wbcr_inp_snippet_' . $snippet_id . '_conditions_metabox' );
64
65 $values = [];
66 $post_types = get_post_types( [ 'public' => true ], 'objects' );
67 if ( ! empty( $post_types ) ) {
68 foreach ( $post_types as $key => $value ) {
69 $values[] = [
70 'value' => $key,
71 'title' => $value->label,
72 ];
73 }
74 }
75
76 $result = [
77 'values' => $values,
78 ];
79
80 echo json_encode( $result );
81 exit;
82 }
83
84 add_action( 'wp_ajax_wbcr_inp_ajax_get_post_types', 'wbcr_inp_ajax_get_post_types' );
85
86 /**
87 * Returns a list of public taxonomies.
88 */
89 function wbcr_inp_ajax_get_taxonomies() {
90
91 if ( ! WINP_Plugin::app()->current_user_car() ) {
92 wp_die( - 1, 403 );
93 }
94
95 $snippet_id = WINP_HTTP::post( 'snippet_id', 0, 'intval' );
96
97 check_admin_referer( 'wbcr_inp_snippet_' . $snippet_id . '_conditions_metabox' );
98
99 $values = [];
100 $categories = get_categories( [ 'hide_empty' => false ] );
101
102 if ( ! empty( $categories ) ) {
103 foreach ( $categories as $cat ) {
104 $values[] = [
105 'value' => $cat->term_id,
106 'title' => $cat->name,
107 ];
108 }
109 }
110
111 $result = [
112 'values' => $values,
113 ];
114
115 echo json_encode( $result );
116 exit;
117 }
118
119 add_action( 'wp_ajax_wbcr_inp_ajax_get_taxonomies', 'wbcr_inp_ajax_get_taxonomies' );
120
121 /**
122 * Returns a list of page list values
123 */
124 function wbcr_inp_ajax_get_page_list() {
125
126 if ( ! WINP_Plugin::app()->current_user_car() ) {
127 wp_die( - 1, 403 );
128 }
129
130 $snippet_id = WINP_HTTP::post( 'snippet_id', 0, 'intval' );
131
132 check_admin_referer( 'wbcr_inp_snippet_' . $snippet_id . '_conditions_metabox' );
133
134 $is_woo = WINP_Helper::is_woo_active();
135 $woo_desc = $is_woo ? '' : __( '(not active)', 'insert-php' );
136
137 $result = [
138 'values' => [
139 __( 'Basic', 'insert-php' ) => [
140 [
141 'value' => 'base_web',
142 'title' => __( 'Entire Website', 'insert-php' ),
143 ],
144 [
145 'value' => 'base_sing',
146 'title' => __( 'All Single Posts & Pages', 'insert-php' ),
147 ],
148 [
149 'value' => 'base_arch',
150 'title' => __( 'All Archive Pages', 'insert-php' ),
151 ],
152 ],
153 __( 'Special Pages', 'insert-php' ) => [
154 [
155 'value' => 'spec_404',
156 'title' => __( '404 Page', 'insert-php' ),
157 ],
158 [
159 'value' => 'spec_search',
160 'title' => __( 'Search Page', 'insert-php' ),
161 ],
162 [
163 'value' => 'spec_blog',
164 'title' => __( 'Blog/Posts Page', 'insert-php' ),
165 ],
166 [
167 'value' => 'spec_front',
168 'title' => __( 'Front Page', 'insert-php' ),
169 ],
170 [
171 'value' => 'spec_date',
172 'title' => __( 'Date Archive', 'insert-php' ),
173 ],
174 [
175 'value' => 'spec_auth',
176 'title' => __( 'Author Archive', 'insert-php' ),
177 ],
178 ],
179 __( 'Posts', 'insert-php' ) => [
180 [
181 'value' => 'post_all',
182 'title' => __( 'All Posts', 'insert-php' ),
183 ],
184 [
185 'value' => 'post_arch',
186 'title' => __( 'All Posts Archive', 'insert-php' ),
187 ],
188 [
189 'value' => 'post_cat',
190 'title' => __( 'All Categories Archive', 'insert-php' ),
191 ],
192 [
193 'value' => 'post_tag',
194 'title' => __( 'All Tags Archive', 'insert-php' ),
195 ],
196 ],
197 __( 'Pages', 'insert-php' ) => [
198 [
199 'value' => 'page_all',
200 'title' => __( 'All Pages', 'insert-php' ),
201 ],
202 [
203 'value' => 'page_arch',
204 'title' => __( 'All Pages Archive', 'insert-php' ),
205 ],
206 ],
207 __( 'WooCommerce', 'insert-php' ) . $woo_desc => [
208 [
209 'value' => 'woo_product',
210 'title' => __( 'Product', 'insert-php' ),
211 'disabled' => ! $is_woo,
212 ],
213 [
214 'value' => 'woo_cart',
215 'title' => __( 'Cart Page', 'insert-php' ),
216 'disabled' => ! $is_woo,
217 ],
218 [
219 'value' => 'woo_checkout',
220 'title' => __( 'Checkout Page', 'insert-php' ),
221 'disabled' => ! $is_woo,
222 ],
223 [
224 'value' => 'woo_checkout_pay',
225 'title' => __( 'Checkout Payment Page', 'insert-php' ),
226 'disabled' => ! $is_woo,
227 ],
228 [
229 'value' => 'woo_arch',
230 'title' => __( 'All Products Page', 'insert-php' ),
231 'disabled' => ! $is_woo,
232 ],
233 [
234 'value' => 'woo_cat',
235 'title' => __( 'Product Category Page', 'insert-php' ),
236 'disabled' => ! $is_woo,
237 ],
238 [
239 'value' => 'woo_tag',
240 'title' => __( 'Product Tag Page', 'insert-php' ),
241 'disabled' => ! $is_woo,
242 ],
243 ],
244 ],
245 ];
246
247 echo json_encode( $result );
248 exit;
249 }
250
251 add_action( 'wp_ajax_wbcr_inp_ajax_get_page_list', 'wbcr_inp_ajax_get_page_list' );
252
253 /**
254 * Save the Permalink slug
255 */
256 function wbcr_inp_ajax_save_permalink() {
257
258 if ( ! WINP_Plugin::app()->current_user_car() ) {
259 wp_die( - 1, 403 );
260 }
261
262 check_ajax_referer( 'winp-permalink', 'winp_permalink_nonce' );
263
264 $code_id = WINP_HTTP::post( 'code_id', 0 );
265 $permalink = WINP_HTTP::post( 'permalink', null, true );
266 $slug = WINP_HTTP::post( 'new_slug', null, 'sanitize_file_name' );
267 $filetype = WINP_HTTP::post( 'filetype', 'css', true );
268
269 WINP_Helper::updateMetaOption( $code_id, 'filetype', $filetype );
270
271 if ( empty( $slug ) ) {
272 $slug = (string) $code_id;
273 WINP_Helper::updateMetaOption( $code_id, 'css_js_slug', '' );
274 } else {
275 WINP_Helper::updateMetaOption( $code_id, 'css_js_slug', $slug );
276 }
277 WINP_Plugin::app()->get_common_object()->edit_form_before_permalink( $slug, $permalink, $filetype );
278
279 wp_die();
280 }
281
282 add_action( 'wp_ajax_winp_permalink', 'wbcr_inp_ajax_save_permalink' );
283
284 /**
285 * Validate snippet code before saving (AJAX).
286 *
287 * @return void
288 */
289 function wbcr_inp_ajax_validate_snippet() {
290 if ( ! WINP_Plugin::app()->current_user_car() ) {
291 wp_send_json_error( [ 'message' => __( 'You don\'t have permission to perform this action. Contact your administrator.', 'insert-php' ) ], 403 );
292 }
293
294 $post_id = WINP_HTTP::post( 'post_id', 0, 'intval' );
295
296 check_ajax_referer( 'winp_validate_snippet_' . $post_id, 'nonce' );
297
298 $snippet_code = WINP_HTTP::post( 'snippet_code', '', false );
299 $snippet_type = WINP_HTTP::post( 'snippet_type', WINP_SNIPPET_TYPE_PHP, true );
300
301 // Only validate executable PHP snippets (not text, ad, css, js, html).
302 if ( WINP_SNIPPET_TYPE_TEXT !== $snippet_type &&
303 WINP_SNIPPET_TYPE_AD !== $snippet_type &&
304 WINP_SNIPPET_TYPE_CSS !== $snippet_type &&
305 WINP_SNIPPET_TYPE_JS !== $snippet_type &&
306 WINP_SNIPPET_TYPE_HTML !== $snippet_type ) {
307
308 $snippet_code = stripslashes( $snippet_code );
309
310 if ( empty( $snippet_code ) ) {
311 wp_send_json_success( [ 'valid' => true ] );
312 }
313
314 // Validate using the same logic as validate_code method.
315 $validation_errors = [];
316
317 // Set custom error handler to catch warnings and notices.
318 set_error_handler( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
319 function ( $errno, $errstr, $errfile, $errline ) use ( &$validation_errors ) {
320 // Extract line number from eval'd code if present.
321 if ( strpos( $errfile, "eval()'d code" ) !== false ) {
322 // translators: %1$d is the line number, %2$s is the error message.
323 $validation_errors[] = sprintf( __( 'Line %1$d: %2$s', 'insert-php' ), $errline, $errstr );
324 } else {
325 $validation_errors[] = $errstr;
326 }
327 return true; // Don't execute PHP internal error handler.
328 }
329 );
330
331 ob_start();
332
333 try {
334 $result = WINP_SNIPPET_TYPE_UNIVERSAL === $snippet_type
335 ? eval( '?> ' . $snippet_code . ' <?php ' )
336 : eval( $snippet_code );
337
338 // Discard any output (echo/print statements are normal for snippets).
339 ob_end_clean();
340
341 // Restore error handler.
342 restore_error_handler();
343
344 // Check if any errors were caught.
345 if ( ! empty( $validation_errors ) ) {
346 // Show all errors, separated by line breaks.
347 $error_message = implode( '<br>', $validation_errors );
348 wp_send_json_error(
349 [
350 'valid' => false,
351 'message' => $error_message,
352 ]
353 );
354 }
355
356 if ( false === $result ) {
357 wp_send_json_error(
358 [
359 'valid' => false,
360 'message' => __( 'The code contains syntax errors. Please review and fix them before saving.', 'insert-php' ),
361 ]
362 );
363 }
364
365 wp_send_json_success( [ 'valid' => true ] );
366
367 } catch ( ParseError $e ) {
368 ob_end_clean();
369 restore_error_handler();
370 wp_send_json_error(
371 [
372 'valid' => false,
373 // translators: %1$d is the line number, %2$s is the error message.
374 'message' => sprintf( __( 'Syntax error on line %1$d: %2$s', 'insert-php' ), $e->getLine(), $e->getMessage() ),
375 ]
376 );
377 } catch ( Throwable $e ) {
378 ob_end_clean();
379 restore_error_handler();
380
381 // Try to extract line number from the error message.
382 $error_message = $e->getMessage();
383 $line = $e->getLine();
384
385 // For fatal errors in eval'd code, extract the actual line number.
386 if ( strpos( $e->getFile(), "eval()'d code" ) !== false ) {
387 wp_send_json_error(
388 [
389 'valid' => false,
390 // translators: %1$d is the line number, %2$s is the error message.
391 'message' => sprintf( __( 'Error on line %1$d: %2$s', 'insert-php' ), $line, $error_message ),
392 ]
393 );
394 } else {
395 wp_send_json_error(
396 [
397 'valid' => false,
398 // translators: %s is the error message.
399 'message' => sprintf( __( 'Error: %s', 'insert-php' ), $error_message ),
400 ]
401 );
402 }
403 }
404 } else {
405 // No validation needed for this type.
406 wp_send_json_success( [ 'valid' => true ] );
407 }
408 }
409
410 add_action( 'wp_ajax_wbcr_inp_ajax_validate_snippet', 'wbcr_inp_ajax_validate_snippet' );
411