PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / 0.4.2
Code Engine – PHP Snippets, AI Functions & Automation for WordPress v0.4.2
0.5.6 0.5.5 0.5.4 0.5.3 0.5.2 0.5.1 0.5.0 0.4.9 0.4.8 0.4.7 0.4.6 trunk 0.0.1 0.0.2 0.2.8 0.2.9 0.3.0 0.3.1 0.3.2 0.3.3 0.3.4 0.3.5 0.3.6 0.3.7 0.3.8 All 32 releases
← All changes | classes/core.php +85 -32 0.3.20.4.2 View file →
@@ -12,8 +12,9 @@
12 12 public $is_rest = false;
13 13 public $is_cli = false;
14 14 public $site_url = null;
15 15 public $mwcode = null;
16 + public $licenser = null;
16 17
17 18 private $option_name = 'mwcode_options';
18 19
19 20 public function __construct() {
@@ -19,9 +20,9 @@
19 20 public function __construct() {
20 21 global $mwcode;
21 22
22 23 $this->site_url = get_site_url();
23 - $this->is_rest = MeowCommon_Helpers::is_rest();
24 + $this->is_rest = MeowKit_MWCODE_Helpers::is_rest();
24 25 $this->is_cli = defined( 'WP_CLI' ) && WP_CLI;
25 26
26 27 // Snippets
27 28 $snippet = new Meow_MWCODE_Modules_Snippet( $this );
@@ -37,8 +38,13 @@
37 38 add_action( 'plugins_loaded', array( $this, 'init' ) );
38 39 }
39 40
40 41 function init() {
42 + // Initialize the licenser for Pro version
43 + if ( class_exists( 'MeowKitPro_MWCODE_Licenser' ) ) {
44 + $this->licenser = new MeowKitPro_MWCODE_Licenser( MWCODE_PREFIX, MWCODE_ENTRY, MWCODE_DOMAIN, MWCODE_ITEM_ID, MWCODE_VERSION );
45 + }
46 +
41 47 // Part of the core, settings and stuff
42 48 $this->admin = new Meow_MWCODE_Admin( $this );
43 49
44 50 // Only for REST
@@ -83,14 +89,17 @@
83 89 return [
84 90 //Safemode
85 91 "safe_mode_status" => "on", // on, off, whitelist
86 92 "safe_mode_whitelist" => [],
93 + //"disallow_block_php" => true, // Do not allow PHP code to be execute through Blocks "code" parameter
94 + "code_blocks" => false,
95 + "code_blocks_whitelist" => [], // Whitelist for code blocks, if empty, all code blocks are allowed
87 96
88 97 //LOGS
89 98 "server_debug_mode" => false,
90 99
91 100 //UI
92 - "ui_show_preview" => true,
101 + "ui_show_preview" => false,
93 102
94 103 //AI
95 104 "ai_suggestions" => false,
96 105 "ai_engine_status"=> false,
@@ -101,8 +110,11 @@
101 110 "api_token" => md5( time() . rand() ),
102 111
103 112 //MCP
104 113 "mcp_support" => false,
114 +
115 + //MAINTENANCE
116 + "clean_uninstall" => false,
105 117 ];
106 118 }
107 119
108 120 function get_all_options( ) {
@@ -116,19 +128,15 @@
116 128 return $options;
117 129 }
118 130
119 131 function update_options( $options ) {
120 - $current_options = get_option($this->option_name);
121 132
122 - if ($current_options === $options) {
123 - // $this->log('💾 The options are already the expected value.');
124 - } else {
125 - if ( !update_option( $this->option_name, $options, false ) ) {
126 - $this->log( '💾 There was an issue updating the options.' );
127 - }
133 + $options = $this->sanitize_options( $options );
134 +
135 + if ( !update_option( $this->option_name, $options, false ) ) {
136 + $this->log( '💾 There was an issue updating the options.' );
128 137 }
129 -
130 - $options = $this->sanitize_options( $options );
138 +
131 139 return $options;
132 140 }
133 141
134 142 function update_option( $option, $value ) {
@@ -171,12 +179,8 @@
171 179 // Note: We don't disable MCP support here anymore
172 180 // It will be checked at runtime in the MCP class
173 181 }
174 182
175 - if ( $options_modified ) {
176 - update_option( $this->option_name, $options, false );
177 - }
178 -
179 183 return $options;
180 184 }
181 185
182 186 private function updateAIEngineStatus( &$options ) {
@@ -276,16 +280,16 @@
276 280 $value = array_map( 'trim', $value );
277 281 }
278 282
279 283 if ( $type === 'array' ) {
280 - $value = json_encode( $value );
281 - $value = str_replace( '\\', '', $value );
284 + // Convert to PHP array format instead of JSON
285 + $value = var_export( $value, true );
282 286 }
283 287
284 288 return [ $name, $value ];
285 289 }
286 290
287 - function run_non_fn_snippet( $id, $code = null, $test = false ) {
291 + function run_non_fn_snippet( $id, $code = null, $test = false, $prefix = '' ) {
288 292 // Retrieve the snippet code from the provided code or via the snippet ID.
289 293 if ( $code ) {
290 294 $snippet = [ 'code' => $code ];
291 295 } else {
@@ -292,13 +296,17 @@
292 296 $snippet = $this->get_snippet( $id );
293 297 }
294 298
295 299 // Remove any PHP opening tag.
296 - $snippet['code'] = preg_replace( '/<\?php/', '', $snippet['code'], 1 );
300 + $snippet['code'] = $this->snippet->sanitize_code( $snippet['code'] );
297 301
298 302 if ( $test ) {
299 303 $snippet['code'] = preg_replace( '/echo\s+(.+?);/s', 'echo $1 . "\n";', $snippet['code'] );
300 304 }
305 +
306 + if( $prefix ) {
307 + $snippet['code'] = $prefix . "\n" . $snippet['code'];
308 + }
301 309
302 310 $error = null;
303 311 $output = null;
304 312
@@ -432,13 +440,14 @@
432 440 if ( $index < count( $params['args'] ) - 1 ) {
433 441 $params['code'] .= ', ';
434 442 }
435 443 }
444 +
436 445 $params['code'] .= ");\necho print_r(\$mwcode_result, true);";
437 446
438 447 $error = null;
439 448 $output = null;
440 -
449 +
441 450 try {
442 451 ob_start();
443 452 eval( $params['code'] );
444 453 $output = ob_get_clean();
@@ -580,14 +589,17 @@
580 589
581 590 $blocked = false;
582 591 $page = isset( $_GET["page"] ) ? sanitize_text_field( $_GET["page"] ) : null;
583 592
584 - // Block on settings page for safety
593 +
585 594 if ( $page === 'mwcode_settings' ) {
586 - $blocked = true;
595 + // If we blocks global snippets like nonce_life filter, we would block the settings page so let's remove the block for this page
596 +
597 + $blocked = false;
598 + //$blocked = true;
587 599 }
588 600 // Block REST requests that aren't whitelisted
589 - elseif ( MeowCommon_Helpers::is_rest() && !Meow_MWCODE_Core::is_white_listed_rest() ) {
601 + elseif ( MeowKit_MWCODE_Helpers::is_rest() && !Meow_MWCODE_Core::is_white_listed_rest() ) {
590 602 $blocked = true;
591 603 }
592 604
593 605 if ( empty( $this->snippet ) ) {
@@ -618,9 +630,9 @@
618 630 return;
619 631 }
620 632
621 633 $snippets = array_map( function ( $snippet ) use ( $blocked ) {
622 - $snippet['code'] = preg_replace( '/<\?php/', '', $snippet['code'], 1 );
634 + $snippet['code'] = $this->snippet->sanitize_code( $snippet['code'] );
623 635 $snippet['blocked'] = $blocked;
624 636
625 637 // If the snippet must be executed only in the frontend, we bypass the block
626 638 if ( !is_admin() && $snippet['scope'] === 'frontend' ) {
@@ -636,25 +648,60 @@
636 648
637 649 #endregion
638 650
639 651 #region Shortcodes
652 + function separate_mwcode_atts( $atts ) {
640 653
654 + if( array_key_exists( 'id', $atts ) ) unset( $atts['id'] );
655 + if( array_key_exists( 'target', $atts ) ) unset( $atts['target'] );
656 + if( array_key_exists( 'code', $atts ) ) unset( $atts['code'] );
657 +
658 + return $atts;
659 + }
660 +
641 661 function content_shortcode( $atts ) {
642 662
663 + $user_atts = $this->separate_mwcode_atts( $atts );
664 +
643 665 $atts = shortcode_atts( array(
644 - 'id' => null,
645 - 'target' => null,
646 - 'code' => null,
647 - ), $atts );
666 + 'id' => null,
667 + 'target' => null, // js or php
668 + 'code' => null, // For Guttenberg block usage
669 + ), $atts, 'code-engine' );
648 670
649 671 $id = $atts['id'];
650 672 $target = $atts['target'];
651 673 $code = $atts['code'];
652 -
674 + $current_post = get_post();
675 +
676 + $no_js = defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML;
677 + $allow_php = $this->get_option( 'code_blocks', false );
678 + $allow_php_whitelist = $this->get_option( 'code_blocks_whitelist', [] );
679 +
653 680 // If the ID is null, it means it comes from a Guttenberg block
654 681 $is_block = empty( $id ) && !empty( $code );
655 - if( $is_block ){
656 682
683 + if( $is_block ) {
684 +
685 + if( $target !== 'js' && $target !== 'php' ) {
686 + return '<b>Code Engine:</b> Please provide a valid target (js or php).';
687 + }
688 +
689 + if ( $no_js && $target === 'js' ) {
690 + return '<b>Code Engine:</b> Code Block JS are disabled because unfiltered HTML is not allowed on your server.';
691 + }
692 +
693 + if ( $target === 'php' ) {
694 +
695 + if ( !$allow_php ) {
696 + return '<b>Code Engine:</b> Code Block PHP are disabled. If you are an administrator, you can enable it in the settings, this is not recommended. Please use a Content Snippet ( PHP ) instead.';
697 + }
698 +
699 + if ( !empty( $allow_php_whitelist ) && !in_array( $current_post->ID, $allow_php_whitelist ) ) {
700 + return '<b>Code Engine:</b> Code Block PHP are disabled for this post. If you are an administrator, you can enable it in the settings, this is not recommended. Please use a Content Snippet ( PHP ) instead.';
701 + }
702 + }
703 +
657 704 // Because the code from Blocks are sanitized, we need to replace the &quot; with "
658 705 $code = str_replace( '&quot;', '"', $code );
659 706
660 707 if ( $target === 'js' ) {
@@ -667,8 +714,9 @@
667 714
668 715 return $output;
669 716 }
670 717
718 + // If not a block, we get the snippet by ID
671 719 // If the ID is not null, it means it comes from a shortcode
672 720 if ( empty( $id ) && empty( $code ) ) {
673 721 return '<b>Code Engine:</b> Please provide a snippet ID.';
674 722 }
@@ -680,14 +728,18 @@
680 728 }
681 729
682 730 //Check if the snippet scope is either content_php or content_js
683 731 $is_content_php = $snippet['scope'] === 'content_php';
684 - $is_content_js = $snippet['scope'] === 'content_js';
732 + $is_content_js = $snippet['scope'] === 'content_js';
685 733
686 734 if ( !$is_content_php && !$is_content_js ) {
687 735 return '<b>Code Engine:</b> The snippet is not a content snippet.';
688 736 }
689 737
738 + if( $no_js && $is_content_js ) {
739 + return '<b>Code Engine:</b> Code Engine JS snippets are disabled because unfiltered HTML is not allowed on your server.';
740 + }
741 +
690 742 //Check if the snippet is active
691 743 if ( !$snippet['active'] ) {
692 744 return '<b>Code Engine:</b> The snippet is not active.';
693 745 }
@@ -698,9 +750,10 @@
698 750 $output = '<script>' . $snippet['code'] . '</script>';
699 751 }
700 752
701 753 if ( $is_content_php ) {
702 - $output = $this->run_non_fn_snippet( $id );
754 + $prefix = "\$mwcode_atts = unserialize( '" . serialize( $user_atts ) . "' );";
755 + $output = $this->run_non_fn_snippet( $id, null, false, $prefix );
703 756 }
704 757
705 758 return $output;
706 759 }