PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / 0.4.3
Code Engine – PHP Snippets, AI Functions & Automation for WordPress v0.4.3
0.5.7 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 All 33 releases
← All changes | classes/core.php +66 -41 0.3.50.4.3 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,9 +89,11 @@
83 89 return [
84 90 //Safemode
85 91 "safe_mode_status" => "on", // on, off, whitelist
86 92 "safe_mode_whitelist" => [],
87 - "disallow_block_php" => true, // Do not allow PHP code to be execute through Blocks "code" parameter
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
88 96
89 97 //LOGS
90 98 "server_debug_mode" => false,
91 99
@@ -102,8 +110,11 @@
102 110 "api_token" => md5( time() . rand() ),
103 111
104 112 //MCP
105 113 "mcp_support" => false,
114 +
115 + //MAINTENANCE
116 + "clean_uninstall" => false,
106 117 ];
107 118 }
108 119
109 120 function get_all_options( ) {
@@ -117,19 +128,15 @@
117 128 return $options;
118 129 }
119 130
120 131 function update_options( $options ) {
121 - $current_options = get_option($this->option_name);
122 132
123 - if ($current_options === $options) {
124 - // $this->log('💾 The options are already the expected value.');
125 - } else {
126 - if ( !update_option( $this->option_name, $options, false ) ) {
127 - $this->log( '💾 There was an issue updating the options.' );
128 - }
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.' );
129 137 }
130 -
131 - $options = $this->sanitize_options( $options );
138 +
132 139 return $options;
133 140 }
134 141
135 142 function update_option( $option, $value ) {
@@ -160,9 +167,9 @@
160 167 $options_modified = true;
161 168 }
162 169
163 170 // Update AI Engine status
164 - $options_modified = $this->updateAIEngineStatus( $options ) || $options_modified;
171 + $options = $this->updateAIEngineStatus( $options );
165 172
166 173 // Disable AI related features if AI Engine is not available
167 174 if ( ! $options['ai_engine_status'] ) {
168 175 if ( $options['ai_suggestions'] !== false ) {
@@ -172,12 +179,8 @@
172 179 // Note: We don't disable MCP support here anymore
173 180 // It will be checked at runtime in the MCP class
174 181 }
175 182
176 - if ( $options_modified ) {
177 - update_option( $this->option_name, $options, false );
178 - }
179 -
180 183 return $options;
181 184 }
182 185
183 186 private function updateAIEngineStatus( &$options ) {
@@ -185,28 +188,25 @@
185 188
186 189 if ( is_null( $mwai ) || ! isset( $mwai ) ) {
187 190 $options['ai_engine_status'] = false;
188 191 $options['ai_engine_message'] = 'AI Engine is not available.';
189 - return true;
192 +
193 + return $options;
190 194 }
191 195
192 196 try {
193 197 $status = $mwai->checkStatus();
194 198
195 - if ( $options['ai_engine_status'] != true || $options['ai_engine_message'] != $status ) {
196 - $options['ai_engine_status'] = true;
197 - $options['ai_engine_message'] = $status;
198 - return true;
199 - }
199 + $options['ai_engine_status'] = true;
200 + $options['ai_engine_message'] = is_array( $status ) ? "Environments: " . implode( ', ', $status ) : $status;
201 +
200 202 } catch ( Exception $e ) {
201 - if ( $options['ai_engine_status'] != false || $options['ai_engine_message'] != $e->getMessage() ) {
203 +
202 204 $options['ai_engine_status'] = false;
203 205 $options['ai_engine_message'] = $e->getMessage();
204 - return true;
205 - }
206 206 }
207 207
208 - return false;
208 + return $options;
209 209 }
210 210
211 211 #endregion
212 212
@@ -277,16 +277,16 @@
277 277 $value = array_map( 'trim', $value );
278 278 }
279 279
280 280 if ( $type === 'array' ) {
281 - $value = json_encode( $value );
282 - $value = str_replace( '\\', '', $value );
281 + // Convert to PHP array format instead of JSON
282 + $value = var_export( $value, true );
283 283 }
284 284
285 285 return [ $name, $value ];
286 286 }
287 287
288 - function run_non_fn_snippet( $id, $code = null, $test = false ) {
288 + function run_non_fn_snippet( $id, $code = null, $test = false, $prefix = '' ) {
289 289 // Retrieve the snippet code from the provided code or via the snippet ID.
290 290 if ( $code ) {
291 291 $snippet = [ 'code' => $code ];
292 292 } else {
@@ -293,13 +293,17 @@
293 293 $snippet = $this->get_snippet( $id );
294 294 }
295 295
296 296 // Remove any PHP opening tag.
297 - $snippet['code'] = preg_replace( '/<\?php/', '', $snippet['code'], 1 );
297 + $snippet['code'] = $this->snippet->sanitize_code( $snippet['code'] );
298 298
299 299 if ( $test ) {
300 300 $snippet['code'] = preg_replace( '/echo\s+(.+?);/s', 'echo $1 . "\n";', $snippet['code'] );
301 301 }
302 +
303 + if( $prefix ) {
304 + $snippet['code'] = $prefix . "\n" . $snippet['code'];
305 + }
302 306
303 307 $error = null;
304 308 $output = null;
305 309
@@ -433,13 +437,14 @@
433 437 if ( $index < count( $params['args'] ) - 1 ) {
434 438 $params['code'] .= ', ';
435 439 }
436 440 }
441 +
437 442 $params['code'] .= ");\necho print_r(\$mwcode_result, true);";
438 443
439 444 $error = null;
440 445 $output = null;
441 -
446 +
442 447 try {
443 448 ob_start();
444 449 eval( $params['code'] );
445 450 $output = ob_get_clean();
@@ -589,9 +594,9 @@
589 594 $blocked = false;
590 595 //$blocked = true;
591 596 }
592 597 // Block REST requests that aren't whitelisted
593 - elseif ( MeowCommon_Helpers::is_rest() && !Meow_MWCODE_Core::is_white_listed_rest() ) {
598 + elseif ( MeowKit_MWCODE_Helpers::is_rest() && !Meow_MWCODE_Core::is_white_listed_rest() ) {
594 599 $blocked = true;
595 600 }
596 601
597 602 if ( empty( $this->snippet ) ) {
@@ -622,9 +627,9 @@
622 627 return;
623 628 }
624 629
625 630 $snippets = array_map( function ( $snippet ) use ( $blocked ) {
626 - $snippet['code'] = preg_replace( '/<\?php/', '', $snippet['code'], 1 );
631 + $snippet['code'] = $this->snippet->sanitize_code( $snippet['code'] );
627 632 $snippet['blocked'] = $blocked;
628 633
629 634 // If the snippet must be executed only in the frontend, we bypass the block
630 635 if ( !is_admin() && $snippet['scope'] === 'frontend' ) {
@@ -640,23 +645,35 @@
640 645
641 646 #endregion
642 647
643 648 #region Shortcodes
649 + function separate_mwcode_atts( $atts ) {
644 650
651 + if( array_key_exists( 'id', $atts ) ) unset( $atts['id'] );
652 + if( array_key_exists( 'target', $atts ) ) unset( $atts['target'] );
653 + if( array_key_exists( 'code', $atts ) ) unset( $atts['code'] );
654 +
655 + return $atts;
656 + }
657 +
645 658 function content_shortcode( $atts ) {
646 659
660 + $user_atts = $this->separate_mwcode_atts( $atts );
661 +
647 662 $atts = shortcode_atts( array(
648 - 'id' => null,
649 - 'target' => null,
650 - 'code' => null,
651 - ), $atts );
663 + 'id' => null,
664 + 'target' => null, // js or php
665 + 'code' => null, // For Guttenberg block usage
666 + ), $atts, 'code-engine' );
652 667
653 668 $id = $atts['id'];
654 669 $target = $atts['target'];
655 670 $code = $atts['code'];
671 + $current_post = get_post();
656 672
657 673 $no_js = defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML;
658 - $no_php = $this->get_option( 'disallow_block_php', true );
674 + $allow_php = $this->get_option( 'code_blocks', false );
675 + $allow_php_whitelist = $this->get_option( 'code_blocks_whitelist', [] );
659 676
660 677 // If the ID is null, it means it comes from a Guttenberg block
661 678 $is_block = empty( $id ) && !empty( $code );
662 679
@@ -669,10 +686,17 @@
669 686 if ( $no_js && $target === 'js' ) {
670 687 return '<b>Code Engine:</b> Code Block JS are disabled because unfiltered HTML is not allowed on your server.';
671 688 }
672 689
673 - if ( $no_php && $target === 'php' ) {
674 - 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.';
690 + if ( $target === 'php' ) {
691 +
692 + if ( !$allow_php ) {
693 + 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.';
694 + }
695 +
696 + if ( !empty( $allow_php_whitelist ) && !in_array( $current_post->ID, $allow_php_whitelist ) ) {
697 + 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.';
698 + }
675 699 }
676 700
677 701 // Because the code from Blocks are sanitized, we need to replace the &quot; with "
678 702 $code = str_replace( '&quot;', '"', $code );
@@ -723,9 +747,10 @@
723 747 $output = '<script>' . $snippet['code'] . '</script>';
724 748 }
725 749
726 750 if ( $is_content_php ) {
727 - $output = $this->run_non_fn_snippet( $id );
751 + $prefix = "\$mwcode_atts = unserialize( '" . serialize( $user_atts ) . "' );";
752 + $output = $this->run_non_fn_snippet( $id, null, false, $prefix );
728 753 }
729 754
730 755 return $output;
731 756 }