PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / 2.4.7
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts v2.4.7
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
← All changes | includes/class.execute.snippet.php +198 -737 trunk2.4.7 View file →
@@ -1,12 +1,14 @@
1 1 <?php
2 2 /**
3 3 * Execute snippet
4 4 *
5 - * @package Woody_Code_Snippets
5 + * @author Artem Prihodko <webtemyk@yandex.ru>
6 + * @copyright (c) 2020, CreativeMotion
7 + * @version 2.4
6 8 */
7 9
8 -// Exit if accessed directly.
10 +// Exit if accessed directly
9 11 if ( ! defined( 'ABSPATH' ) ) {
10 12 exit;
11 13 }
12 14
@@ -26,29 +28,8 @@
26 28 * @var WINP_Insertion_Locations
27 29 */
28 30 public $snippets_locations;
29 31
30 - /**
31 - * Current snippet ID being executed.
32 - *
33 - * @var int Current snippet ID being executed (for error handling).
34 - */
35 - private static $current_snippet_id = 0;
36 -
37 - /**
38 - * Indicates whether shutdown handler has been registered.
39 - *
40 - * @var bool Whether shutdown handler has been registered.
41 - */
42 - private static $shutdown_registered = false;
43 -
44 - /**
45 - * Tracked executed snippets on current page.
46 - *
47 - * @var array<int, array{id: int, name: string, type: string, location: string, scope: string}>
48 - */
49 - private $executed_snippets = [];
50 -
51 32 public static function app() {
52 33 if ( self::$instance === null ) {
53 34 self::$instance = new self();
54 35 }
@@ -56,36 +37,12 @@
56 37 return self::$instance;
57 38 }
58 39
59 40 /**
60 - * Get executed snippets on current page.
61 - *
62 - * @return array<int, array{id: int, name: string, type: string, location: string, scope: string}>
63 - */
64 - public function get_executed_snippets() {
65 - return $this->executed_snippets;
66 - }
67 -
68 - /**
69 41 * WINP_Execute_Snippet constructor.
70 42 */
71 43 public function __construct() {
72 44 self::$instance = $this;
73 -
74 - // Check if this is an AJAX validation request and skip the snippet being validated.
75 - if ( wp_doing_ajax()
76 - && isset( $_POST['action'] ) && 'wbcr_inp_ajax_validate_snippet' === $_POST['action']
77 - && isset( $_POST['post_id'] ) ) {
78 - $validating_snippet_id = (int) $_POST['post_id'];
79 - add_filter(
80 - 'winp_skip_snippet_execution',
81 - function ( $should_skip, $snippet_id ) use ( $validating_snippet_id ) {
82 - return $should_skip || $snippet_id === $validating_snippet_id;
83 - },
84 - 1,
85 - 2
86 - );
87 - }
88 45
89 46 if ( ! defined( 'WINP_UPLOAD_DIR' ) ) {
90 47 $dir = wp_upload_dir();
91 48 define( 'WINP_UPLOAD_DIR', $dir['basedir'] . '/winp-css-js' );
@@ -96,18 +53,17 @@
96 53 define( 'WINP_UPLOAD_URL', $dir['baseurl'] . '/winp-css-js' );
97 54 }
98 55 global $wpdb;
99 56
100 - // todo: Simplify your request. Seems written ugly
101 57 $sql = "SELECT {$wpdb->posts}.ID, {$wpdb->posts}.post_content, p2.meta_value as priority
102 58 FROM {$wpdb->posts}
103 59 INNER JOIN {$wpdb->postmeta} p1 ON ({$wpdb->posts}.ID = p1.post_id)
104 60 INNER JOIN {$wpdb->postmeta} p2 ON ({$wpdb->posts}.ID = p2.post_id)
105 61 INNER JOIN {$wpdb->postmeta} p3 ON ({$wpdb->posts}.ID = p3.post_id)
106 - WHERE (( p1.meta_key = 'wbcr_inp_snippet_scope' AND p1.meta_value = '%s')
62 + WHERE (( p1.meta_key = '" . WINP_Plugin::app()->getPrefix() . "snippet_scope' AND p1.meta_value = '%s')
107 63 AND
108 - ( p3.meta_key = 'wbcr_inp_snippet_activate' AND p3.meta_value = '1')
109 - AND p2.meta_key = 'wbcr_inp_snippet_priority' )
64 + ( p3.meta_key = '" . WINP_Plugin::app()->getPrefix() . "snippet_activate' AND p3.meta_value = '1')
65 + AND p2.meta_key = '" . WINP_Plugin::app()->getPrefix() . "snippet_priority' )
110 66 AND {$wpdb->posts}.post_type = '" . WINP_SNIPPETS_POST_TYPE . "'
111 67 AND ({$wpdb->posts}.post_status = 'publish')
112 68 ORDER BY CAST(priority AS UNSIGNED) %s";
113 69
@@ -120,21 +76,21 @@
120 76
121 77 /**
122 78 * Register hooks
123 79 */
124 - public function register_hooks() {
125 - add_action( 'init', [ $this, 'execute_everywhere_snippets' ], 1 );
80 + public function registerHooks() {
81 + add_action( 'plugins_loaded', [ $this, 'executeEverywhereSnippets' ], 1 );
126 82
127 - if ( ! is_admin() ) { // issue PCS-45 fix bug with WPBPage Builder Frontend Editor
128 - add_action( 'wp_head', [ $this, 'execute_header_snippets' ] );
129 - add_action( 'wp_footer', [ $this, 'execute_footer_snippets' ] );
83 + if ( ! is_admin() ) { #issue PCS-45 fix bug with WPBPage Builder Frontend Editor
84 + add_action( 'wp_head', [ $this, 'executeHeaderSnippets' ] );
85 + add_action( 'wp_footer', [ $this, 'executeFooterSnippets' ] );
130 86 add_action( 'the_post', [ $this, 'executePostSnippets' ], 10, 2 );
131 87 add_filter( 'the_content', [ $this, 'executeContentSnippets' ] );
132 88 add_filter( 'the_excerpt', [ $this, 'executeExcerptSnippets' ] );
133 89 // Бесполезный хук, который вызывается на каждый комментарий. Если их много, увеличивается нагрузка
134 - // add_filter( 'wp_list_comments_args', [ $this, 'executeListCommentsSnippets' ] );
90 + //add_filter( 'wp_list_comments_args', [ $this, 'executeListCommentsSnippets' ] );
135 91
136 - // add_action( 'wp_head', [ $this, 'executeWoocommerceSnippets' ] );
92 + //add_action( 'wp_head', [ $this, 'executeWoocommerceSnippets' ] );
137 93
138 94 if ( ! empty( $this->snippets_locations->getInsertion( 'custom' ) ) ) {
139 95 add_action( 'wp_head', [ $this, 'executeCustomSnippets' ] );
140 96 }
@@ -143,30 +99,30 @@
143 99
144 100 /**
145 101 * Execute the everywhere snippets once the plugins are loaded
146 102 */
147 - public function execute_everywhere_snippets() {
148 - echo $this->execute_active_snippets( 'evrywhere' );
103 + public function executeEverywhereSnippets() {
104 + echo $this->executeActiveSnippets( 'evrywhere' );
149 105 }
150 106
151 107 /**
152 108 * Execute the snippets in header of page once the plugins are loaded
153 109 */
154 - public function execute_header_snippets() {
155 - echo $this->execute_active_snippets( 'auto', 'header' );
110 + public function executeHeaderSnippets() {
111 + echo $this->executeActiveSnippets( 'auto', 'header' );
156 112 }
157 113
158 114 /**
159 115 * Execute the snippets in footer of page once the plugins are loaded
160 116 */
161 - public function execute_footer_snippets() {
162 - echo $this->execute_active_snippets( 'auto', 'footer' );
117 + public function executeFooterSnippets() {
118 + echo $this->executeActiveSnippets( 'auto', 'footer' );
163 119 }
164 120
165 121 /**
166 122 * Execute the snippets before post
167 123 *
168 - * @param WP_Post $post
124 + * @param WP_Post $post
169 125 * @param WP_Query $query
170 126 */
171 127 public function executePostSnippets( $post, $query ) {
172 128 $content = '';
@@ -174,20 +130,22 @@
174 130 $post_type = ! empty( $post ) ? $post->post_type : get_post( $post->ID )->post_type;
175 131 if ( is_singular( [ $post_type ] ) ) {
176 132 if ( did_action( 'get_header' ) ) {
177 133 // Перед заголовком
178 - $content = $this->execute_active_snippets( 'auto', 'before_post' );
134 + $content = $this->executeActiveSnippets( 'auto', 'before_post' );
179 135 }
180 - } elseif ( $query->post_count > 0 ) {
181 - if ( $query->post_count > 1 && $query->current_post > 0 && $query->post_count > $query->current_post ) {
182 - // Между записями
183 - $content = $this->execute_active_snippets( 'auto', 'between_posts' );
184 - }
136 + } else {
137 + if ( $query->post_count > 0 ) {
138 + if ( $query->post_count > 1 && $query->current_post > 0 && $query->post_count > $query->current_post ) {
139 + // Между записями
140 + $content = $this->executeActiveSnippets( 'auto', 'between_posts' );
141 + }
185 142 // Перед записью
186 - $content .= $this->execute_active_snippets( 'auto', 'before_posts', '', $query );
143 + $content .= $this->executeActiveSnippets( 'auto', 'before_posts', '', $query );
187 144
188 145 // После записи
189 - $content .= $this->execute_active_snippets( 'auto', 'after_posts', '', $query );
146 + $content .= $this->executeActiveSnippets( 'auto', 'after_posts', '', $query );
147 + }
190 148 }
191 149
192 150 echo $content;
193 151 }
@@ -237,13 +195,13 @@
237 195
238 196 /**
239 197 * Handle posts content
240 198 *
241 - * @param string $content
242 - * @param string $snippet_content
199 + * @param string $content
200 + * @param string $snippet_content
243 201 * @param integer $post_number
244 - * @param string $type
245 - * @param object $query
202 + * @param string $type
203 + * @param object $query
246 204 *
247 205 * @return mixed
248 206 */
249 207 private function handlePostsContent( $content, $snippet_content, $post_number, $type, $query ) {
@@ -283,29 +241,29 @@
283 241 $post_type = ! empty( $post ) ? $post->post_type : false;
284 242
285 243 if ( is_category() || is_archive() || is_tag() || is_tax() || is_search() ) {
286 244 // Перед коротким описанием
287 - $content = $this->execute_active_snippets( 'auto', 'before_excerpt' ) . $content;
245 + $content = $this->executeActiveSnippets( 'auto', 'before_excerpt' ) . $content;
288 246
289 247 // После короткого описания
290 - $content .= $this->execute_active_snippets( 'auto', 'after_excerpt' );
248 + $content .= $this->executeActiveSnippets( 'auto', 'after_excerpt' );
291 249 }
292 250
293 251 if ( is_singular( [ $post_type ] ) ) {
294 252 // Перед параграфом
295 - $content = $this->execute_active_snippets( 'auto', 'before_paragraph', $content );
253 + $content = $this->executeActiveSnippets( 'auto', 'before_paragraph', $content );
296 254
297 255 // После параграфа
298 - $content = $this->execute_active_snippets( 'auto', 'after_paragraph', $content );
256 + $content = $this->executeActiveSnippets( 'auto', 'after_paragraph', $content );
299 257
300 258 // После заголовка
301 - $content = $this->execute_active_snippets( 'auto', 'before_content' ) . $content;
259 + $content = $this->executeActiveSnippets( 'auto', 'before_content' ) . $content;
302 260
303 261 // После текста
304 - $content .= $this->execute_active_snippets( 'auto', 'after_content' );
262 + $content .= $this->executeActiveSnippets( 'auto', 'after_content' );
305 263
306 264 // После поста
307 - $content .= $this->execute_active_snippets( 'auto', 'after_post' );
265 + $content .= $this->executeActiveSnippets( 'auto', 'after_post' );
308 266
309 267 if ( ! comments_open( $post->ID ) && ! get_comments_number( $post->ID ) ) {
310 268 remove_filter( 'wp_list_comments_args', [ $this, 'executeListCommentsSnippets' ] );
311 269 }
@@ -327,12 +285,12 @@
327 285 */
328 286 public function executeExcerptSnippets( $excerpt ) {
329 287 if ( is_category() || is_archive() || is_tag() || is_tax() || is_search() ) {
330 288 // Перед коротким описанием
331 - $excerpt = $this->execute_active_snippets( 'auto', 'before_excerpt' ) . $excerpt;
289 + $excerpt = $this->executeActiveSnippets( 'auto', 'before_excerpt' ) . $excerpt;
332 290
333 291 // После короткого описания
334 - $excerpt .= $this->execute_active_snippets( 'auto', 'after_excerpt' );
292 + $excerpt .= $this->executeActiveSnippets( 'auto', 'after_excerpt' );
335 293 }
336 294
337 295 return $excerpt;
338 296 }
@@ -371,9 +329,9 @@
371 329
372 330 $post_type = ! empty( $post ) ? $post->post_type : false;
373 331 if ( is_singular( [ $post_type ] ) ) {
374 332 // После комментариев
375 - $content = $this->execute_active_snippets( 'auto', 'after_post' );
333 + $content = $this->executeActiveSnippets( 'auto', 'after_post' );
376 334 }
377 335
378 336 echo $content;
379 337 }
@@ -385,9 +343,9 @@
385 343 */
386 344 public function executeCustomSnippets() {
387 345 $locations = $this->snippets_locations->getInsertion( 'custom' );
388 346 foreach ( $locations as $location => $data ) {
389 - $this->execute_active_snippets( 'auto', $location );
347 + $this->executeActiveSnippets( 'auto', $location );
390 348 }
391 349 }
392 350
393 351 /**
@@ -404,22 +362,16 @@
404 362 };
405 363
406 364 switch ( $location ) {
407 365 case 'woo_before_shop_loop':
408 - add_filter(
409 - 'woocommerce_product_loop_start',
410 - function ( $content ) use ( $snippet_content ) {
411 - return $snippet_content . $content;
412 - }
413 - );
366 + add_filter( 'woocommerce_product_loop_start', function ( $content ) use ( $snippet_content ) {
367 + return $snippet_content . $content;
368 + } );
414 369 break;
415 370 case 'woo_after_shop_loop':
416 - add_filter(
417 - 'woocommerce_product_loop_end',
418 - function ( $content ) use ( $snippet_content ) {
419 - return $content . $snippet_content;
420 - }
421 - );
371 + add_filter( 'woocommerce_product_loop_end', function ( $content ) use ( $snippet_content ) {
372 + return $content . $snippet_content;
373 + } );
422 374 break;
423 375 case 'woo_before_single_product':
424 376 add_action( 'woocommerce_before_single_product', $action, 10, 2 );
425 377 break;
@@ -473,143 +425,131 @@
473 425 *
474 426 * @param string $scope
475 427 * @param string $location
476 428 * @param string $content
477 - * @param array $custom_params
429 + * @param array $custom_params
478 430 *
479 431 * @return string
480 432 */
481 - public function execute_active_snippets( $scope = 'evrywhere', $location = '', $content = '', $custom_params = [] ) {
433 + public function executeActiveSnippets( $scope = 'evrywhere', $location = '', $content = '', $custom_params = [] ) {
434 + /*
435 + global $wpdb;
436 +
437 + if ( $scope == 'evrywhere' ) {
438 + $sort = 'DESC';
439 + } else {
440 + $sort = 'ASC';
441 + }
442 + $snippets = $wpdb->get_results( "SELECT {$wpdb->posts}.ID, {$wpdb->posts}.post_content, p2.meta_value as priority
443 + FROM {$wpdb->posts}
444 + INNER JOIN {$wpdb->postmeta} p1 ON ({$wpdb->posts}.ID = p1.post_id)
445 + INNER JOIN {$wpdb->postmeta} p2 ON ({$wpdb->posts}.ID = p2.post_id)
446 + INNER JOIN {$wpdb->postmeta} p3 ON ({$wpdb->posts}.ID = p3.post_id)
447 + WHERE (( p1.meta_key = '" . WINP_Plugin::app()->getPrefix() . "snippet_scope' AND p1.meta_value = '{$scope}')
448 + AND
449 + ( p3.meta_key = '" . WINP_Plugin::app()->getPrefix() . "snippet_activate' AND p3.meta_value = '1')
450 + AND p2.meta_key = '" . WINP_Plugin::app()->getPrefix() . "snippet_priority' )
451 + AND {$wpdb->posts}.post_type = '" . WINP_SNIPPETS_POST_TYPE . "'
452 + AND ({$wpdb->posts}.post_status = 'publish')
453 + ORDER BY CAST(priority AS UNSIGNED) {$sort}" );
454 + */
482 455 $snippets = $this->snippets[ $scope ] ?? [];
483 456
484 - if ( ! empty( $snippets ) ) {
485 - foreach ( (array) $snippets as $snippet ) {
486 - $id = (int) $snippet->ID;
487 -
488 - // Allow filtering to skip specific snippet IDs.
489 - $should_skip = apply_filters( 'winp_skip_snippet_execution', false, $id );
490 - if ( $should_skip ) {
491 - continue;
457 + if ( empty( $snippets ) ) {
458 + return $content;
459 + }
460 +
461 + foreach ( (array) $snippets as $snippet ) {
462 + $id = (int) $snippet->ID;
463 + //$is_active = (int) WINP_Helper::getMetaOption( $id, 'snippet_activate', 0 );
464 + // Если это сниппет с автовставкой и выбранное место подходит под активный action
465 + $avail_place = ( 'auto' == $scope ? $location == WINP_Helper::getMetaOption( $id, 'snippet_location', '' ) : true );
466 + // Если условие отображения сниппета выполняется
467 + $snippet_type = WINP_Helper::getMetaOption( $id, 'snippet_type', WINP_SNIPPET_TYPE_PHP );
468 + $is_condition = $snippet_type != WINP_SNIPPET_TYPE_PHP ? $this->checkCondition( $id ) : true;
469 +
470 + if ( $avail_place && $is_condition ) {
471 + $post_id = (int) WINP_Plugin::app()->request->post( 'post_ID', 0 );
472 +
473 + if ( isset( $_POST['wbcr_inp_snippet_scope'] ) && $post_id === $id && WINP_Plugin::app()->currentUserCan() ) {
474 + return $content;
492 475 }
493 -
494 - // $is_active = (int) WINP_Helper::getMetaOption( $id, 'snippet_activate', 0 );
495 - // Если это сниппет с автовставкой и выбранное место подходит под активный action
496 - $avail_place = ( 'auto' == $scope ? $location == WINP_Helper::getMetaOption( $id, 'snippet_location', '' ) : true );
497 - // Если условие отображения сниппета выполняется
498 - $snippet_type = WINP_Helper::getMetaOption( $id, 'snippet_type', WINP_SNIPPET_TYPE_PHP );
499 - $is_condition = $snippet_type != WINP_SNIPPET_TYPE_PHP ? $this->checkCondition( $id ) : true;
500 476
501 - if ( $avail_place && $is_condition ) {
502 - $post_id = (int) WINP_HTTP::post( 'post_ID', 0 );
477 + if ( WINP_Helper::is_safe_mode() ) {
478 + return $content;
479 + }
503 480
504 - if ( ( isset( $_POST['wbcr_inp_snippet_scope'] )
505 - && $post_id === $id
506 - && WINP_Plugin::app()->current_user_car() ) || WINP_Helper::is_safe_mode() ) {
507 - return $content;
508 - }
509 -
510 - // WPML Compatibility
511 - if ( defined( 'WPML_PLUGIN_FILE' ) ) {
512 - $wpml_langs = WINP_Helper::getMetaOption( $id, 'snippet_wpml_lang', '' );
513 - if ( $wpml_langs !== '' && defined( 'ICL_LANGUAGE_CODE' ) ) {
514 - if ( ! in_array( ICL_LANGUAGE_CODE, explode( ',', $wpml_langs ) ) ) {
515 - continue;
516 - }
481 + // WPML Compatibility
482 + if ( defined( 'WPML_PLUGIN_FILE' ) ) {
483 + $wpml_langs = WINP_Helper::getMetaOption( $id, 'snippet_wpml_lang', '' );
484 + if ( $wpml_langs !== '' && defined( 'ICL_LANGUAGE_CODE' ) ) {
485 + if ( ! in_array( ICL_LANGUAGE_CODE, explode( ',', $wpml_langs ) ) ) {
486 + continue;
517 487 }
518 488 }
489 + }
519 490
520 - $snippet_code = WINP_Helper::get_snippet_code( $snippet );
491 + $snippet_code = WINP_Helper::get_snippet_code( $snippet );
521 492
522 - /**
523 - * Filter snippet code before execute
524 - */
525 - $snippet_code = apply_filters( 'wbcr/inp/execute_snippet/snippet_code', $snippet_code, $id );
493 + /**
494 + * Filter snippet code before execute
495 + */
496 + $snippet_code = apply_filters( 'wbcr/inp/execute_snippet/snippet_code', $snippet_code, $id );
526 497
527 - // Track this snippet as executed.
528 - $this->track_executed_snippet( $id, $scope );
498 + if ( WINP_Plugin::app()->getOption( 'execute_shortcode' ) ) {
499 + $snippet_code = do_shortcode( $snippet_code );
500 + }
529 501
530 - if ( get_option( 'wbcr_inp_execute_shortcode' ) ) {
531 - $snippet_code = do_shortcode( $snippet_code );
532 - }
502 + if ( $snippet_type === WINP_SNIPPET_TYPE_TEXT || $snippet_type === WINP_SNIPPET_TYPE_AD ) {
503 + $snippet_content = '<div class="winp-text-snippet-container">' . $snippet_code . '</div>';
504 + } elseif ( $snippet_type === WINP_SNIPPET_TYPE_CSS || $snippet_type === WINP_SNIPPET_TYPE_JS ) {
505 + $snippet_content = self::getJsCssSnippetData( $id );
506 + } elseif ( $snippet_type === WINP_SNIPPET_TYPE_HTML ) {
507 + $snippet_content = $snippet_code;
508 + } else {
509 + $code = $this->prepareCode( $snippet_code, $id );
510 + ob_start();
511 + $this->executeSnippet( $code, $id, false );
512 + $snippet_content = ob_get_contents();
513 + ob_end_clean();
514 + }
533 515
534 - if ( $snippet_type === WINP_SNIPPET_TYPE_TEXT || $snippet_type === WINP_SNIPPET_TYPE_AD ) {
535 - $snippet_content = '<div class="winp-text-snippet-container">' . $snippet_code . '</div>';
536 - } elseif ( $snippet_type === WINP_SNIPPET_TYPE_CSS || $snippet_type === WINP_SNIPPET_TYPE_JS ) {
537 - $snippet_content = self::getJsCssSnippetData( $id );
538 - } elseif ( $snippet_type === WINP_SNIPPET_TYPE_HTML ) {
539 - $snippet_content = $snippet_code;
540 - } else {
541 - $code = $this->prepareCode( $snippet_code, $id );
542 - ob_start();
543 - $this->executeSnippet( $code, $id, false );
544 - $snippet_content = ob_get_contents();
545 - ob_end_clean();
516 + if ( 'auto' == $scope ) {
517 + switch ( $location ) {
518 + case 'before_paragraph': // Перед параграфом
519 + $location_number = WINP_Helper::getMetaOption( $id, 'snippet_p_number', 0 );
520 + $content = $this->handleParagraphContent( $content, $snippet_content, $location_number );
521 + break;
522 + case 'after_paragraph': // После параграфа
523 + $location_number = WINP_Helper::getMetaOption( $id, 'snippet_p_number', 0 );
524 + $content = $this->handleParagraphContent( $content, $snippet_content, $location_number, 'after' );
525 + break;
526 + case 'before_posts': // Перед записью
527 + $location_number = WINP_Helper::getMetaOption( $id, 'snippet_p_number', 0 );
528 + $content = $this->handlePostsContent( $content, $snippet_content, $location_number, 'before', $custom_params );
529 + break;
530 + case 'after_posts': // После записи
531 + $location_number = WINP_Helper::getMetaOption( $id, 'snippet_p_number', 0 );
532 + $content = $this->handlePostsContent( $content, $snippet_content, $location_number, 'after', $custom_params );
533 + break;
534 + default:
535 + $content = $snippet_content . $content;
546 536 }
547 537
548 - // If the user has prohibited the insertion of unfiltered HTML,
549 - // we prohibit the execution of snippets.
550 - if ( ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML )
551 - && ! in_array(
552 - $snippet_type,
553 - [
554 - WINP_SNIPPET_TYPE_TEXT,
555 - WINP_SNIPPET_TYPE_AD,
556 - WINP_SNIPPET_TYPE_CSS,
557 - ]
558 - ) ) {
559 - $snippet_content = '';
538 + /**
539 + * Action for woo actions
540 + *
541 + * @param array $location Slug of the location.
542 + * @param string $snippet_content Rendered snippet content
543 + *
544 + * @since 2.4
545 + */
546 + do_action( 'wbcr/woody/do_woocommerce_actions', $location, $snippet_content );
560 547
561 - if ( is_user_logged_in() && WINP_Plugin::app()->current_user_car() ) {
562 - $error_text = __( 'This Woody snippet cannot run because unfiltered HTML insertion is disabled.', 'insert-php' );
563 -
564 - switch ( $location ) {
565 - case 'header':
566 - case 'footer':
567 - $snippet_content = '<!-- ' . $error_text . '-->';
568 - break;
569 - default:
570 - $snippet_content = $error_text;
571 - }
572 - }
573 - }
574 -
575 - if ( 'auto' == $scope ) {
576 - switch ( $location ) {
577 - case 'before_paragraph': // Перед параграфом
578 - $location_number = WINP_Helper::getMetaOption( $id, 'snippet_p_number', 0 );
579 - $content = $this->handleParagraphContent( $content, $snippet_content, $location_number );
580 - break;
581 - case 'after_paragraph': // После параграфа
582 - $location_number = WINP_Helper::getMetaOption( $id, 'snippet_p_number', 0 );
583 - $content = $this->handleParagraphContent( $content, $snippet_content, $location_number, 'after' );
584 - break;
585 - case 'before_posts': // Перед записью
586 - $location_number = WINP_Helper::getMetaOption( $id, 'snippet_p_number', 0 );
587 - $content = $this->handlePostsContent( $content, $snippet_content, $location_number, 'before', $custom_params );
588 - break;
589 - case 'after_posts': // После записи
590 - $location_number = WINP_Helper::getMetaOption( $id, 'snippet_p_number', 0 );
591 - $content = $this->handlePostsContent( $content, $snippet_content, $location_number, 'after', $custom_params );
592 - break;
593 - default:
594 - $content = $snippet_content . $content;
595 - }
596 -
597 - /**
598 - * Action for woo actions
599 - *
600 - * @param array $location Slug of the location.
601 - * @param string $snippet_content Rendered snippet content
602 - *
603 - * @since 2.4
604 - */
605 - do_action( 'wbcr/woody/do_woocommerce_actions', $location, $snippet_content );
606 -
607 - // $this->woocommerce_actions( $location, $snippet_content );
608 - $this->custom_actions( $location, $snippet_content );
609 - } else {
610 - $content = $snippet_content . $content;
611 - }
548 + //$this->woocommerce_actions( $location, $snippet_content );
549 + $this->custom_actions( $location, $snippet_content );
550 + } else {
551 + $content = $snippet_content . $content;
612 552 }
613 553 }
614 554 }
615 555
@@ -616,107 +556,8 @@
616 556 return $content;
617 557 }
618 558
619 559 /**
620 - * Track shortcode snippet execution.
621 - *
622 - * Public method for shortcode classes to call.
623 - *
624 - * @param int $snippet_id Snippet ID.
625 - * @return void
626 - */
627 - public function track_shortcode_snippet( $snippet_id ) {
628 - $this->track_executed_snippet( $snippet_id, 'shortcode' );
629 - }
630 -
631 - /**
632 - * Track executed snippet.
633 - *
634 - * @param int $snippet_id Snippet ID.
635 - * @param string $scope Snippet scope.
636 - * @return void
637 - */
638 - private function track_executed_snippet( $snippet_id, $scope ) {
639 - if ( isset( $this->executed_snippets[ $snippet_id ] ) ) {
640 - return; // Already tracked.
641 - }
642 -
643 - $snippet = get_post( $snippet_id );
644 - if ( ! $snippet ) {
645 - return;
646 - }
647 -
648 - $snippet_type = WINP_Helper::getMetaOption( $snippet_id, 'snippet_type', WINP_SNIPPET_TYPE_PHP );
649 - $snippet_location = WINP_Helper::getMetaOption( $snippet_id, 'snippet_location', '' );
650 -
651 - // Map location to human-readable label.
652 - $location_label = $this->get_location_label( $scope, $snippet_location );
653 -
654 - $this->executed_snippets[ $snippet_id ] = [
655 - 'id' => $snippet_id,
656 - 'name' => $snippet->post_title,
657 - 'type' => $this->get_type_label( $snippet_type ),
658 - 'location' => $location_label,
659 - 'scope' => $scope,
660 - ];
661 - }
662 -
663 - /**
664 - * Get human-readable location label.
665 - *
666 - * @param string $scope Snippet scope.
667 - * @param string $location Snippet location.
668 - * @return string
669 - */
670 - private function get_location_label( $scope, $location ) {
671 - if ( 'evrywhere' === $scope ) {
672 - return __( 'Everywhere', 'insert-php' );
673 - }
674 -
675 - if ( 'shortcode' === $scope ) {
676 - return __( 'Shortcode', 'insert-php' );
677 - }
678 -
679 - $location_labels = [
680 - 'header' => __( 'Header', 'insert-php' ),
681 - 'footer' => __( 'Footer', 'insert-php' ),
682 - 'before_post' => __( 'Before Post', 'insert-php' ),
683 - 'before_content' => __( 'Before Content', 'insert-php' ),
684 - 'before_paragraph' => __( 'Before Paragraph', 'insert-php' ),
685 - 'after_paragraph' => __( 'After Paragraph', 'insert-php' ),
686 - 'after_content' => __( 'After Content', 'insert-php' ),
687 - 'after_post' => __( 'After Post', 'insert-php' ),
688 - 'before_excerpt' => __( 'Before Excerpt', 'insert-php' ),
689 - 'after_excerpt' => __( 'After Excerpt', 'insert-php' ),
690 - 'before_posts' => __( 'Before Posts', 'insert-php' ),
691 - 'after_posts' => __( 'After Posts', 'insert-php' ),
692 - 'after_comments' => __( 'After Comments', 'insert-php' ),
693 - ];
694 -
695 - return $location_labels[ $location ] ?? ucwords( str_replace( '_', ' ', $location ) );
696 - }
697 -
698 - /**
699 - * Get human-readable type label.
700 - *
701 - * @param string $type Snippet type.
702 - * @return string
703 - */
704 - private function get_type_label( $type ) {
705 - $type_labels = [
706 - WINP_SNIPPET_TYPE_PHP => 'PHP',
707 - WINP_SNIPPET_TYPE_UNIVERSAL => 'Universal',
708 - WINP_SNIPPET_TYPE_HTML => 'HTML',
709 - WINP_SNIPPET_TYPE_CSS => 'CSS',
710 - WINP_SNIPPET_TYPE_JS => 'JS',
711 - WINP_SNIPPET_TYPE_TEXT => 'TEXT',
712 - WINP_SNIPPET_TYPE_AD => 'AD',
713 - ];
714 -
715 - return $type_labels[ $type ] ?? 'PHP';
716 - }
717 -
718 - /**
719 560 * Get js or css snippet data
720 561 *
721 562 * @param $snippet_id
722 563 *
@@ -762,11 +603,11 @@
762 603 *
763 604 * Code must NOT be escaped, as
764 605 * it will be executed directly
765 606 *
766 - * @param string $code The snippet code to execute.
767 - * @param int $id The snippet ID.
768 - * @param bool $catch_output Whether to attempt to suppress the output of execution using buffers.
607 + * @param string $code The snippet code to execute
608 + * @param int $id The snippet ID
609 + * @param bool $catch_output Whether to attempt to suppress the output of execution using buffers
769 610 *
770 611 * @return mixed The result of the code execution
771 612 */
772 613 public function executeSnippet( $code, $id = 0, $catch_output = true ) {
@@ -785,24 +626,10 @@
785 626 if ( empty( $snippet ) || $snippet->post_type !== WINP_SNIPPETS_POST_TYPE ) {
786 627 return false;
787 628 }
788 629
789 - $snippet_type = WINP_Helper::getMetaOption( $id, 'snippet_type', true );
790 - $is_executable = in_array( $snippet_type, [ WINP_SNIPPET_TYPE_PHP, WINP_SNIPPET_TYPE_UNIVERSAL ], true );
630 + $snippet_type = WINP_Helper::getMetaOption( $id, 'snippet_type', true );
791 631
792 - if ( $is_executable ) {
793 - // Preserve the active snippet context if execution terminates the request.
794 - self::$current_snippet_id = $id;
795 - WINP_Error_Handler::init();
796 - WINP_Error_Handler::set_current_snippet( $id, $snippet->post_title );
797 -
798 - // Register shutdown function once to catch fatal errors.
799 - if ( ! self::$shutdown_registered ) {
800 - register_shutdown_function( [ $this, 'handle_snippet_shutdown' ] );
801 - self::$shutdown_registered = true;
802 - }
803 - }
804 -
805 632 if ( $snippet_type == WINP_SNIPPET_TYPE_UNIVERSAL ) {
806 633 $result = eval( '?>' . $code . '<?php ' );
807 634 } elseif ( $snippet_type == WINP_SNIPPET_TYPE_PHP ) {
808 635 $result = eval( $code );
@@ -809,13 +636,8 @@
809 636 } else {
810 637 $result = ! empty( $code );
811 638 }
812 639
813 - if ( $is_executable ) {
814 - self::$current_snippet_id = 0;
815 - WINP_Error_Handler::clear_current_snippet();
816 - }
817 -
818 640 if ( $catch_output ) {
819 641 ob_end_clean();
820 642 }
821 643
@@ -822,330 +644,8 @@
822 644 return $result;
823 645 }
824 646
825 647 /**
826 - * Handle fatal errors during snippet execution.
827 - *
828 - * @return void
829 - */
830 - public function handle_snippet_shutdown() {
831 - $error = error_get_last();
832 -
833 - // If there's a fatal error and a snippet was being executed, check if it's from the snippet.
834 - if ( self::$current_snippet_id && $error && in_array( $error['type'], [ E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR ] ) ) {
835 - // Only log if the error originated from the snippet code itself.
836 - if ( $this->is_error_from_snippet( $error ) ) {
837 - $this->log_snippet_error( self::$current_snippet_id, $error );
838 - }
839 - }
840 -
841 - // Clear the snippet ID after processing.
842 - self::$current_snippet_id = 0;
843 - }
844 -
845 - /**
846 - * Check if the error originated from the snippet code.
847 - *
848 - * @param array<string, mixed> $error Error details.
849 - *
850 - * @return bool True if error is from snippet, false otherwise.
851 - */
852 - private function is_error_from_snippet( $error ) {
853 - if ( ! isset( $error['file'] ) ) {
854 - return false;
855 - }
856 -
857 - $error_file = $error['file'];
858 -
859 - // Check if error is from eval'd code (PHP snippets executed via eval).
860 - if ( strpos( $error_file, "eval()'d code" ) !== false ) {
861 - return true;
862 - }
863 -
864 - return false;
865 - }
866 -
867 - /**
868 - * Log snippet error via admin notice
869 - *
870 - * @param int $snippet_id Snippet ID.
871 - * @param array<string, mixed> $error Error details.
872 - *
873 - * @return void
874 - */
875 - private function log_snippet_error( $snippet_id, $error ) {
876 - // Validate error array has required keys.
877 - if ( ! isset( $error['message'], $error['file'], $error['line'] ) ) {
878 - return;
879 - }
880 -
881 - // Generate unique notice ID based on snippet ID and error details.
882 - $error_signature = md5( $snippet_id . $error['message'] . $error['file'] . $error['line'] );
883 - $notice_id = 'snippet_error_' . $error_signature;
884 -
885 - // Get snippet title for better context.
886 - $snippet = get_post( $snippet_id );
887 - $snippet_title = $snippet ? $snippet->post_title : "ID {$snippet_id}";
888 -
889 - // Extract the main error message (before stack trace).
890 - $error_message = $error['message'];
891 - if ( strpos( $error_message, ' Stack trace:' ) !== false ) {
892 - $error_message = substr( $error_message, 0, strpos( $error_message, ' Stack trace:' ) );
893 - }
894 - $error_message = trim( $error_message );
895 -
896 - // Shorten file path for readability.
897 - $file_path = str_replace( ABSPATH, '', $error['file'] );
898 -
899 - // Get edit link for the snippet.
900 - $edit_link = admin_url( 'post.php?post=' . $snippet_id . '&action=edit' );
901 -
902 - // Build notice message.
903 - $message = sprintf(
904 - '<div class="winp-error-notice-header"><strong>%s</strong> %s <a href="%s" class="winp-snippet-edit-link" target="_blank">%s</a></div><details><summary>%s</summary><div class="winp-error-details"><div class="winp-error-message"><strong>%s:</strong><br><code>%s</code></div><div class="winp-error-location"><strong>%s:</strong><br>%s <span class="winp-line-number">%s %d</span></div></div></details><div class="winp-error-notice-footer"><p class="winp-dismiss-help">%s</p><button type="button" class="button winp-manual-dismiss-btn">%s</button></div>',
905 - __( 'Snippet Error Detected', 'insert-php' ),
906 - // Translators: 1: Snippet title.
907 - sprintf( __( 'Snippet "%s" caused a fatal error.', 'insert-php' ), esc_html( $snippet_title ) ),
908 - esc_url( $edit_link ),
909 - __( 'Edit Snippet', 'insert-php' ),
910 - __( 'Show error details', 'insert-php' ),
911 - __( 'Error', 'insert-php' ),
912 - esc_html( $error_message ),
913 - __( 'Location', 'insert-php' ),
914 - esc_html( $file_path ),
915 - __( 'line', 'insert-php' ),
916 - $error['line'],
917 - __( 'If you have fixed this error, you can dismiss this notice.', 'insert-php' ),
918 - __( 'Dismiss', 'insert-php' )
919 - );
920 -
921 - // Store error notice in option to be displayed on next admin page load.
922 - $pending_notices = get_option( 'winp_pending_error_notices', [] );
923 - if ( ! is_array( $pending_notices ) ) {
924 - $pending_notices = [];
925 - }
926 -
927 - // Only add if not already present (avoid race conditions).
928 - if ( ! isset( $pending_notices[ $notice_id ] ) ) {
929 - $pending_notices[ $notice_id ] = [
930 - 'message' => $message,
931 - 'type' => 'error',
932 - ];
933 -
934 - update_option( 'winp_pending_error_notices', $pending_notices, false );
935 -
936 - // Send email notification if enabled and this is a new error.
937 - $this->send_error_email( $notice_id, $snippet_id, $snippet_title, $error_message, $file_path, $error['line'], $edit_link );
938 - }
939 - }
940 -
941 - /**
942 - * Send email notification for snippet error
943 - *
944 - * @param string $error_signature Unique error identifier.
945 - * @param int $snippet_id The ID of the snippet.
946 - * @param string $snippet_title The title of the snippet.
947 - * @param string $error_message The error message.
948 - * @param string $file_path The file path where error occurred.
949 - * @param int $line_number The line number where error occurred.
950 - * @param string $edit_link Link to edit the snippet.
951 - *
952 - * @return void
953 - */
954 - private function send_error_email( $error_signature, $snippet_id, $snippet_title, $error_message, $file_path, $line_number, $edit_link ) {
955 - // Check if email notifications are enabled.
956 - $email_enabled = get_option( 'wbcr_inp_error_email_enabled' );
957 - if ( ! $email_enabled ) {
958 - return;
959 - }
960 -
961 - // Get email address.
962 - $email_address = get_option( 'wbcr_inp_error_email_address', get_option( 'admin_email' ) );
963 - if ( empty( $email_address ) || ! is_email( $email_address ) ) {
964 - return;
965 - }
966 -
967 - // Check if we've already emailed about this error.
968 - $emailed_errors = get_option( 'winp_emailed_errors', [] );
969 - if ( ! is_array( $emailed_errors ) ) {
970 - $emailed_errors = [];
971 - }
972 -
973 - // If we've already emailed about this error, skip.
974 - if ( isset( $emailed_errors[ $error_signature ] ) ) {
975 - return;
976 - }
977 -
978 - // Clean up old entries (older than 30 days).
979 - $thirty_days_ago = time() - ( 30 * DAY_IN_SECONDS );
980 - foreach ( $emailed_errors as $hash => $timestamp ) {
981 - if ( $timestamp < $thirty_days_ago ) {
982 - unset( $emailed_errors[ $hash ] );
983 - }
984 - }
985 -
986 - // Build email content.
987 - $site_name = get_bloginfo( 'name' );
988 - $admin_url = admin_url( 'edit.php?post_type=' . WINP_SNIPPETS_POST_TYPE );
989 - $subject = sprintf( '[%s] Snippet Error Detected: %s', $site_name, $snippet_title );
990 -
991 - $email_body = $this->get_error_email_template( $site_name, $snippet_id, $snippet_title, $error_message, $file_path, $line_number, $edit_link, $admin_url );
992 -
993 - // Set email headers for HTML.
994 - $headers = [
995 - 'Content-Type: text/html; charset=UTF-8',
996 - ];
997 -
998 - // Send email.
999 - $sent = wp_mail( $email_address, $subject, $email_body, $headers );
1000 -
1001 - // If email sent successfully, mark this error as emailed.
1002 - if ( $sent ) {
1003 - $emailed_errors[ $error_signature ] = time();
1004 - update_option( 'winp_emailed_errors', $emailed_errors, false );
1005 - }
1006 - }
1007 -
1008 - /**
1009 - * Get HTML email template for error notification
1010 - *
1011 - * @param string $site_name Site name.
1012 - * @param int $snippet_id Snippet ID.
1013 - * @param string $snippet_title Snippet title.
1014 - * @param string $error_message Error message.
1015 - * @param string $file_path File path.
1016 - * @param int $line_number Line number.
1017 - * @param string $edit_link Edit link.
1018 - * @param string $admin_url Admin URL.
1019 - *
1020 - * @return string HTML email template.
1021 - */
1022 - private function get_error_email_template( $site_name, $snippet_id, $snippet_title, $error_message, $file_path, $line_number, $edit_link, $admin_url ) {
1023 - ob_start();
1024 - ?>
1025 - <!DOCTYPE html>
1026 - <html>
1027 - <head>
1028 - <meta charset="UTF-8">
1029 - <meta name="viewport" content="width=device-width, initial-scale=1.0">
1030 - <title><?php echo esc_html( __( 'Snippet Error Notification', 'insert-php' ) ); ?></title>
1031 - </head>
1032 - <body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; background-color: #f0f0f1;">
1033 - <table role="presentation" style="width: 100%; border-collapse: collapse;">
1034 - <tr>
1035 - <td align="center" style="padding: 40px 20px;">
1036 - <table role="presentation" style="width: 100%; max-width: 600px; border-collapse: collapse; background-color: #ffffff; border: 1px solid #c3c4c7; border-radius: 2px;">
1037 - <!-- Header -->
1038 - <tr>
1039 - <td style="padding: 24px 30px; background-color: #2271b1; border-bottom: 1px solid #135e96;">
1040 - <h1 style="margin: 0; color: #ffffff; font-size: 20px; font-weight: 600;">
1041 - ⚠️ <?php echo esc_html( __( 'Snippet Error Detected', 'insert-php' ) ); ?>
1042 - </h1>
1043 - </td>
1044 - </tr>
1045 -
1046 - <!-- Content -->
1047 - <tr>
1048 - <td style="padding: 30px;">
1049 - <p style="margin: 0 0 16px; color: #1d2327; font-size: 14px; line-height: 1.6;">
1050 - <?php echo esc_html( __( 'Hello,', 'insert-php' ) ); ?>
1051 - </p>
1052 -
1053 - <p style="margin: 0 0 20px; color: #1d2327; font-size: 14px; line-height: 1.6;">
1054 - <?php
1055 - printf(
1056 - // translators: 1: snippet title, 2: site name.
1057 - esc_html( __( 'A fatal error has been detected in the snippet "%1$s" on your site %2$s.', 'insert-php' ) ),
1058 - '<strong>' . esc_html( $snippet_title ) . '</strong>',
1059 - '<strong>' . esc_html( $site_name ) . '</strong>'
1060 - );
1061 - ?>
1062 - </p>
1063 -
1064 - <!-- Error Details Box -->
1065 - <table role="presentation" style="width: 100%; border-collapse: collapse; margin: 24px 0; background-color: #fcf0f1; border-left: 4px solid #d63638; border-radius: 0;">
1066 - <tr>
1067 - <td style="padding: 16px 20px;">
1068 - <p style="margin: 0 0 12px; color: #8c1c13; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px;">
1069 - <?php echo esc_html( __( 'Error Details', 'insert-php' ) ); ?>
1070 - </p>
1071 -
1072 - <div style="margin-bottom: 12px;">
1073 - <p style="margin: 0 0 6px; color: #3c434a; font-size: 13px; font-weight: 600;">
1074 - <?php echo esc_html( __( 'Error Message:', 'insert-php' ) ); ?>
1075 - </p>
1076 - <p style="margin: 0; padding: 8px 12px; background-color: #ffffff; border: 1px solid #dcdcde; color: #1d2327; font-size: 13px; font-family: Consolas, Monaco, monospace; word-break: break-word; line-height: 1.5;">
1077 - <?php echo esc_html( $error_message ); ?>
1078 - </p>
1079 - </div>
1080 -
1081 - <div style="margin-bottom: 12px;">
1082 - <p style="margin: 0 0 6px; color: #3c434a; font-size: 13px; font-weight: 600;">
1083 - <?php echo esc_html( __( 'Location:', 'insert-php' ) ); ?>
1084 - </p>
1085 - <p style="margin: 0; padding: 8px 12px; background-color: #ffffff; border: 1px solid #dcdcde; color: #1d2327; font-size: 13px; font-family: Consolas, Monaco, monospace; line-height: 1.5;">
1086 - <?php echo esc_html( $file_path ); ?> <span style="color: #646970;"><?php echo esc_html( __( 'line', 'insert-php' ) ); ?> <?php echo intval( $line_number ); ?></span>
1087 - </p>
1088 - </div>
1089 -
1090 - <div>
1091 - <p style="margin: 0 0 6px; color: #3c434a; font-size: 13px; font-weight: 600;">
1092 - <?php echo esc_html( __( 'Snippet:', 'insert-php' ) ); ?>
1093 - </p>
1094 - <p style="margin: 0; padding: 8px 12px; background-color: #ffffff; border: 1px solid #dcdcde; color: #1d2327; font-size: 13px; line-height: 1.5;">
1095 - <?php echo esc_html( $snippet_title ); ?> <span style="color: #646970;">(ID: <?php echo intval( $snippet_id ); ?>)</span>
1096 - </p>
1097 - </div>
1098 - </td>
1099 - </tr>
1100 - </table>
1101 -
1102 - <!-- Action Buttons -->
1103 - <table role="presentation" style="width: 100%; border-collapse: collapse; margin: 24px 0;">
1104 - <tr>
1105 - <td style="padding: 0;">
1106 - <a href="<?php echo esc_url( $edit_link ); ?>" style="display: inline-block; padding: 10px 20px; background-color: #2271b1; color: #ffffff; text-decoration: none; border-radius: 3px; font-weight: 500; font-size: 13px; margin-right: 8px; border: 1px solid #2271b1;">
1107 - <?php echo esc_html( __( 'Edit Snippet', 'insert-php' ) ); ?>
1108 - </a>
1109 - <a href="<?php echo esc_url( $admin_url ); ?>" style="display: inline-block; padding: 10px 20px; background-color: #f6f7f7; color: #2c3338; text-decoration: none; border-radius: 3px; font-weight: 500; font-size: 13px; border: 1px solid #c3c4c7;">
1110 - <?php echo esc_html( __( 'View All Snippets', 'insert-php' ) ); ?>
1111 - </a>
1112 - </td>
1113 - </tr>
1114 - </table>
1115 -
1116 - <p style="margin: 20px 0 0; color: #646970; font-size: 13px; line-height: 1.6;">
1117 - <?php echo esc_html( __( 'This notification is sent only once per unique error. You can disable these notifications in the plugin settings.', 'insert-php' ) ); ?>
1118 - </p>
1119 - </td>
1120 - </tr>
1121 -
1122 - <!-- Footer -->
1123 - <tr>
1124 - <td style="padding: 16px 30px; background-color: #f6f7f7; border-top: 1px solid #dcdcde;">
1125 - <p style="margin: 0; color: #646970; font-size: 12px; text-align: center;">
1126 - <?php
1127 - printf(
1128 - // translators: %s: site name.
1129 - esc_html( __( 'This email was sent by Woody Code Snippets on %s', 'insert-php' ) ),
1130 - '<strong>' . esc_html( $site_name ) . '</strong>'
1131 - );
1132 - ?>
1133 - </p>
1134 - </td>
1135 - </tr>
1136 - </table>
1137 - </td>
1138 - </tr>
1139 - </table>
1140 - </body>
1141 - </html>
1142 - <?php
1143 - $output = ob_get_clean();
1144 - return false !== $output ? $output : '';
1145 - }
1146 -
1147 - /**
1148 648 * Get property value
1149 649 *
1150 650 * @param $value
1151 651 * @param $property
@@ -1172,9 +672,9 @@
1172 672 public function checkCondition( $snippet_id ) {
1173 673 // Итоговый результат условий
1174 674 $result = true;
1175 675 // Получаем сохранённые параметры условий
1176 - $filters = get_post_meta( $snippet_id, 'wbcr_inp_snippet_filters' );
676 + $filters = get_post_meta( $snippet_id, WINP_Plugin::app()->getPrefix() . 'snippet_filters' );
1177 677 // Если условия указаны
1178 678 if ( ! ( empty( $filters ) || isset( $filters[0] ) && empty( $filters[0] ) ) ) {
1179 679 foreach ( $filters[0] as $filter ) {
1180 680 $conditions = $this->getPropertyValue( $filter, 'conditions' );
@@ -1267,9 +767,9 @@
1267 767
1268 768 /**
1269 769 * Prepare the code by removing php tags from beginning and end
1270 770 *
1271 - * @param string $code
771 + * @param string $code
1272 772 * @param integer $snippet_id
1273 773 *
1274 774 * @return string
1275 775 */
@@ -1274,14 +774,9 @@
1274 774 * @return string
1275 775 */
1276 776 public function prepareCode( $code, $snippet_id ) {
1277 777 $snippet_type = WINP_Helper::get_snippet_type( $snippet_id );
1278 -
1279 - if ( $snippet_type != WINP_SNIPPET_TYPE_UNIVERSAL
1280 - && $snippet_type != WINP_SNIPPET_TYPE_CSS
1281 - && $snippet_type != WINP_SNIPPET_TYPE_JS
1282 - && $snippet_type != WINP_SNIPPET_TYPE_HTML ) {
1283 -
778 + if ( $snippet_type != WINP_SNIPPET_TYPE_UNIVERSAL && $snippet_type != WINP_SNIPPET_TYPE_CSS && $snippet_type != WINP_SNIPPET_TYPE_JS && $snippet_type != WINP_SNIPPET_TYPE_HTML ) {
1284 779 /* Remove <?php and <? from beginning of snippet */
1285 780 $code = preg_replace( '|^[\s]*<\?(php)?|', '', $code );
1286 781
1287 782 /* Remove ?> from end of snippet */
@@ -1323,16 +818,16 @@
1323 818
1324 819 /**
1325 820 * Check by operator
1326 821 *
1327 - * @param string $operation Comparison operator.
1328 - * @param mixed $first First value.
1329 - * @param mixed $second Second value.
1330 - * @param bool $third Third value.
822 + * @param $operation
823 + * @param $first
824 + * @param $second
825 + * @param $third
1331 826 *
1332 827 * @return bool
1333 828 */
1334 - public function check_by_operator( $operation, $first, $second, $third = false ) {
829 + public function checkByOperator( $operation, $first, $second, $third = false ) {
1335 830 switch ( $operation ) {
1336 831 case 'equals':
1337 832 if ( is_array( $second ) ) {
1338 833 return in_array( $first, $second );
@@ -1372,9 +867,9 @@
1372 867 * @return boolean
1373 868 */
1374 869 private function user_role( $operator, $value ) {
1375 870 if ( ! is_user_logged_in() ) {
1376 - return $this->check_by_operator( $operator, $value, 'guest' );
871 + return $this->checkByOperator( $operator, $value, 'guest' );
1377 872 } else {
1378 873 $current_user = wp_get_current_user();
1379 874 if ( ! ( $current_user instanceof WP_User ) ) {
1380 875 return false;
@@ -1379,9 +874,9 @@
1379 874 if ( ! ( $current_user instanceof WP_User ) ) {
1380 875 return false;
1381 876 }
1382 877
1383 - return $this->check_by_operator( $operator, $value, $current_user->roles[0] );
878 + return $this->checkByOperator( $operator, $value, $current_user->roles[0] );
1384 879 }
1385 880 }
1386 881
1387 882 /**
@@ -1386,20 +881,14 @@
1386 881
1387 882 /**
1388 883 * Get timestamp
1389 884 *
1390 - * @param string $units Time units.
1391 - * @param mixed $count Count of units.
885 + * @param $units
886 + * @param $count
1392 887 *
1393 888 * @return integer
1394 889 */
1395 - private function get_timestamp( $units, $count ) {
1396 - if ( ! is_numeric( $count ) ) {
1397 - return 0;
1398 - }
1399 -
1400 - $count = (int) $count;
1401 -
890 + private function getTimestamp( $units, $count ) {
1402 891 switch ( $units ) {
1403 892 case 'seconds':
1404 893 return $count;
1405 894 case 'minutes':
@@ -1422,19 +911,15 @@
1422 911
1423 912 /**
1424 913 * Get date timestamp
1425 914 *
1426 - * @param mixed $value Date value.
915 + * @param $value
1427 916 *
1428 - * @return int|mixed Returns 0 on validation failure, timestamp calculation, or the original value
917 + * @return integer
1429 918 */
1430 - public function get_date_timestamp( $value ) {
919 + public function getDateTimestamp( $value ) {
1431 920 if ( is_object( $value ) ) {
1432 - if ( ! isset( $value->units ) || ! isset( $value->unitsCount ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
1433 - return 0;
1434 - }
1435 - $current_timestamp = current_datetime()->getTimestamp();
1436 - return ( $current_timestamp - $this->get_timestamp( $value->units, $value->unitsCount ) ) * 1000; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
921 + return ( current_time( 'timestamp' ) - $this->getTimestamp( $value->units, $value->unitsCount ) ) * 1000;
1437 922 } else {
1438 923 return $value;
1439 924 }
1440 925 }
@@ -1442,10 +927,10 @@
1442 927 /**
1443 928 * The date when the user who views your website was registered.
1444 929 * For unregistered users this date always equals to 1 Jan 1970.
1445 930 *
1446 - * @param string $operator Comparison operator.
1447 - * @param mixed $value Comparison value (object for 'between', mixed otherwise).
931 + * @param string $operator
932 + * @param string $value
1448 933 *
1449 934 * @return boolean
1450 935 */
1451 936 private function user_registered( $operator, $value ) {
@@ -1452,48 +937,24 @@
1452 937 if ( ! is_user_logged_in() ) {
1453 938 return false;
1454 939 } else {
1455 940 $user = wp_get_current_user();
1456 - $registered = strtotime( $user->data->user_registered );
1457 -
1458 - // Validate that we have a valid registration timestamp.
1459 - if ( false === $registered ) {
1460 - return false;
1461 - }
1462 -
1463 - $registered = $registered * 1000;
941 + $registered = strtotime( $user->data->user_registered ) * 1000;
1464 942
1465 - if ( 'equals' === $operator || 'notequal' === $operator ) {
943 + if ( $operator == 'equals' || $operator == 'notequal' ) {
1466 944 $registered = $registered / 1000;
1467 - $timestamp = $this->get_date_timestamp( $value );
1468 -
1469 - if ( ! $timestamp || $timestamp <= 0 ) {
1470 - return false;
1471 - }
1472 -
1473 - $timestamp = round( $timestamp / 1000 );
945 + $timestamp = round( $this->getDateTimestamp( $value ) / 1000 );
1474 946
1475 - return $this->check_by_operator( $operator, gmdate( 'Y-m-d', (int) $timestamp ), gmdate( 'Y-m-d', (int) $registered ) );
1476 - } elseif ( 'between' === $operator ) {
1477 - if ( ! is_object( $value ) || ! isset( $value->start ) || ! isset( $value->end ) ) {
1478 - return false;
1479 - }
1480 - $start_timestamp = $this->get_date_timestamp( $value->start );
1481 - $end_timestamp = $this->get_date_timestamp( $value->end );
1482 -
1483 - if ( ! $start_timestamp || $start_timestamp <= 0 || ! $end_timestamp || $end_timestamp <= 0 ) {
1484 - return false;
1485 - }
947 + return $this->checkByOperator( $operator, date( 'Y-m-d', $timestamp ), date( 'Y-m-d', $registered ) );
948 + } elseif ( $operator == 'between' ) {
949 + $start_timestamp = $this->getDateTimestamp( $value->start );
950 + $end_timestamp = $this->getDateTimestamp( $value->end );
1486 951
1487 - return $this->check_by_operator( $operator, $start_timestamp, $registered, $end_timestamp );
952 + return $this->checkByOperator( $operator, $start_timestamp, $registered, $end_timestamp );
1488 953 } else {
1489 - $timestamp = $this->get_date_timestamp( $value );
1490 -
1491 - if ( ! $timestamp || $timestamp <= 0 ) {
1492 - return false;
1493 - }
954 + $timestamp = $this->getDateTimestamp( $value );
1494 955
1495 - return $this->check_by_operator( $operator, $timestamp, $registered );
956 + return $this->checkByOperator( $operator, $timestamp, $registered );
1496 957 }
1497 958 }
1498 959 }
1499 960
@@ -1499,10 +960,10 @@
1499 960
1500 961 /**
1501 962 * Check the user views your website from mobile device or not
1502 963 *
1503 - * @param string $operator Comparison operator.
1504 - * @param string $value Comparison value.
964 + * @param string $operator
965 + * @param string $value
1505 966 *
1506 967 * @return boolean
1507 968 *
1508 969 * @link https://stackoverflow.com/a/4117597
@@ -1635,9 +1096,9 @@
1635 1096 break;
1636 1097 }
1637 1098 }
1638 1099
1639 - return $this->check_by_operator( $operator, $result, true );
1100 + return $this->checkByOperator( $operator, $result, true );
1640 1101 }
1641 1102
1642 1103 /**
1643 1104 * An URL of the current page where a user who views your website is located
@@ -1649,9 +1110,9 @@
1649 1110 */
1650 1111 private function location_page( $operator, $value ) {
1651 1112 $url = $this->getCurrentUrl();
1652 1113
1653 - return $url ? $this->check_by_operator( $operator, trim( $url, '/' ), trim( $value, '/' ) ) : false;
1114 + return $url ? $this->checkByOperator( $operator, trim( $url, '/' ), trim( $value, '/' ) ) : false;
1654 1115 }
1655 1116
1656 1117 /**
1657 1118 * A referrer URL which has brought a user to the current page
@@ -1663,9 +1124,9 @@
1663 1124 */
1664 1125 private function location_referrer( $operator, $value ) {
1665 1126 $url = $this->getRefererUrl();
1666 1127
1667 - return $url ? $this->check_by_operator( $operator, trim( $url, '/' ), trim( $value, '/' ) ) : false;
1128 + return $url ? $this->checkByOperator( $operator, trim( $url, '/' ), trim( $value, '/' ) ) : false;
1668 1129 }
1669 1130
1670 1131 /**
1671 1132 * A post type of the current page
@@ -1676,9 +1137,9 @@
1676 1137 * @return boolean
1677 1138 */
1678 1139 private function location_post_type( $operator, $value ) {
1679 1140 if ( is_singular() ) {
1680 - return $this->check_by_operator( $operator, $value, get_post_type() );
1141 + return $this->checkByOperator( $operator, $value, get_post_type() );
1681 1142 }
1682 1143
1683 1144 return false;
1684 1145 }
@@ -1699,9 +1160,9 @@
1699 1160 if ( is_tax() || is_tag() || is_category() ) {
1700 1161 $term_id = get_queried_object()->term_id;
1701 1162
1702 1163 if ( $term_id ) {
1703 - return $this->check_by_operator( $operator, intval( $value ), $term_id );
1164 + return $this->checkByOperator( $operator, intval( $value ), $term_id );
1704 1165 }
1705 1166 }
1706 1167
1707 1168 return false;
@@ -1728,9 +1189,9 @@
1728 1189 }
1729 1190 }
1730 1191
1731 1192 if ( $term_id ) {
1732 - return $this->check_by_operator( $operator, intval( $value ), $term_id );
1193 + return $this->checkByOperator( $operator, intval( $value ), $term_id );
1733 1194 }
1734 1195
1735 1196 return false;
1736 1197 }