PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / 0.4.5
Code Engine – PHP Snippets, AI Functions & Automation for WordPress v0.4.5
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 +63 -53 0.3.50.4.5 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 ) {
@@ -182,31 +185,13 @@
182 185
183 186 private function updateAIEngineStatus( &$options ) {
184 187 global $mwai;
185 188
186 - if ( is_null( $mwai ) || ! isset( $mwai ) ) {
187 - $options['ai_engine_status'] = false;
188 - $options['ai_engine_message'] = 'AI Engine is not available.';
189 - return true;
190 - }
189 + $options['mwai_has_ai'] = !empty( $mwai ) && method_exists( $mwai, 'hasAI' ) && $mwai->hasAI();
190 + // Legacy
191 + $options['ai_engine_status'] = $options['mwai_has_ai'];
191 192
192 - try {
193 - $status = $mwai->checkStatus();
194 -
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 - }
200 - } catch ( Exception $e ) {
201 - if ( $options['ai_engine_status'] != false || $options['ai_engine_message'] != $e->getMessage() ) {
202 - $options['ai_engine_status'] = false;
203 - $options['ai_engine_message'] = $e->getMessage();
204 - return true;
205 - }
206 - }
207 -
208 - return false;
193 + return $options;
209 194 }
210 195
211 196 #endregion
212 197
@@ -277,16 +262,16 @@
277 262 $value = array_map( 'trim', $value );
278 263 }
279 264
280 265 if ( $type === 'array' ) {
281 - $value = json_encode( $value );
282 - $value = str_replace( '\\', '', $value );
266 + // Convert to PHP array format instead of JSON
267 + $value = var_export( $value, true );
283 268 }
284 269
285 270 return [ $name, $value ];
286 271 }
287 272
288 - function run_non_fn_snippet( $id, $code = null, $test = false ) {
273 + function run_non_fn_snippet( $id, $code = null, $test = false, $prefix = '' ) {
289 274 // Retrieve the snippet code from the provided code or via the snippet ID.
290 275 if ( $code ) {
291 276 $snippet = [ 'code' => $code ];
292 277 } else {
@@ -293,13 +278,17 @@
293 278 $snippet = $this->get_snippet( $id );
294 279 }
295 280
296 281 // Remove any PHP opening tag.
297 - $snippet['code'] = preg_replace( '/<\?php/', '', $snippet['code'], 1 );
282 + $snippet['code'] = $this->snippet->sanitize_code( $snippet['code'] );
298 283
299 284 if ( $test ) {
300 285 $snippet['code'] = preg_replace( '/echo\s+(.+?);/s', 'echo $1 . "\n";', $snippet['code'] );
301 286 }
287 +
288 + if( $prefix ) {
289 + $snippet['code'] = $prefix . "\n" . $snippet['code'];
290 + }
302 291
303 292 $error = null;
304 293 $output = null;
305 294
@@ -433,13 +422,14 @@
433 422 if ( $index < count( $params['args'] ) - 1 ) {
434 423 $params['code'] .= ', ';
435 424 }
436 425 }
426 +
437 427 $params['code'] .= ");\necho print_r(\$mwcode_result, true);";
438 428
439 429 $error = null;
440 430 $output = null;
441 -
431 +
442 432 try {
443 433 ob_start();
444 434 eval( $params['code'] );
445 435 $output = ob_get_clean();
@@ -589,9 +579,9 @@
589 579 $blocked = false;
590 580 //$blocked = true;
591 581 }
592 582 // Block REST requests that aren't whitelisted
593 - elseif ( MeowCommon_Helpers::is_rest() && !Meow_MWCODE_Core::is_white_listed_rest() ) {
583 + elseif ( MeowKit_MWCODE_Helpers::is_rest() && !Meow_MWCODE_Core::is_white_listed_rest() ) {
594 584 $blocked = true;
595 585 }
596 586
597 587 if ( empty( $this->snippet ) ) {
@@ -622,9 +612,9 @@
622 612 return;
623 613 }
624 614
625 615 $snippets = array_map( function ( $snippet ) use ( $blocked ) {
626 - $snippet['code'] = preg_replace( '/<\?php/', '', $snippet['code'], 1 );
616 + $snippet['code'] = $this->snippet->sanitize_code( $snippet['code'] );
627 617 $snippet['blocked'] = $blocked;
628 618
629 619 // If the snippet must be executed only in the frontend, we bypass the block
630 620 if ( !is_admin() && $snippet['scope'] === 'frontend' ) {
@@ -640,23 +630,35 @@
640 630
641 631 #endregion
642 632
643 633 #region Shortcodes
634 + function separate_mwcode_atts( $atts ) {
644 635
636 + if( array_key_exists( 'id', $atts ) ) unset( $atts['id'] );
637 + if( array_key_exists( 'target', $atts ) ) unset( $atts['target'] );
638 + if( array_key_exists( 'code', $atts ) ) unset( $atts['code'] );
639 +
640 + return $atts;
641 + }
642 +
645 643 function content_shortcode( $atts ) {
646 644
645 + $user_atts = $this->separate_mwcode_atts( $atts );
646 +
647 647 $atts = shortcode_atts( array(
648 - 'id' => null,
649 - 'target' => null,
650 - 'code' => null,
651 - ), $atts );
648 + 'id' => null,
649 + 'target' => null, // js or php
650 + 'code' => null, // For Guttenberg block usage
651 + ), $atts, 'code-engine' );
652 652
653 653 $id = $atts['id'];
654 654 $target = $atts['target'];
655 655 $code = $atts['code'];
656 + $current_post = get_post();
656 657
657 658 $no_js = defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML;
658 - $no_php = $this->get_option( 'disallow_block_php', true );
659 + $allow_php = $this->get_option( 'code_blocks', false );
660 + $allow_php_whitelist = $this->get_option( 'code_blocks_whitelist', [] );
659 661
660 662 // If the ID is null, it means it comes from a Guttenberg block
661 663 $is_block = empty( $id ) && !empty( $code );
662 664
@@ -669,10 +671,17 @@
669 671 if ( $no_js && $target === 'js' ) {
670 672 return '<b>Code Engine:</b> Code Block JS are disabled because unfiltered HTML is not allowed on your server.';
671 673 }
672 674
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.';
675 + if ( $target === 'php' ) {
676 +
677 + if ( !$allow_php ) {
678 + 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.';
679 + }
680 +
681 + if ( !empty( $allow_php_whitelist ) && !in_array( $current_post->ID, $allow_php_whitelist ) ) {
682 + 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.';
683 + }
675 684 }
676 685
677 686 // Because the code from Blocks are sanitized, we need to replace the &quot; with "
678 687 $code = str_replace( '&quot;', '"', $code );
@@ -723,9 +732,10 @@
723 732 $output = '<script>' . $snippet['code'] . '</script>';
724 733 }
725 734
726 735 if ( $is_content_php ) {
727 - $output = $this->run_non_fn_snippet( $id );
736 + $prefix = "\$mwcode_atts = unserialize( '" . serialize( $user_atts ) . "' );";
737 + $output = $this->run_non_fn_snippet( $id, null, false, $prefix );
728 738 }
729 739
730 740 return $output;
731 741 }