PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / 0.0.1
Code Engine – PHP Snippets, AI Functions & Automation for WordPress v0.0.1
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
code-engine / classes / core.php

core.php in Code Engine – PHP Snippets, AI Functions & Automation for WordPress 0.0.1, at classes/core.php

266 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) exit;
4
5 require_once( CDEGN_PATH . '/constants/init.php' );
6 class Meow_CDEGN_Core
7 {
8 public $admin = null;
9 public $is_cli = false;
10 public $site_url = null;
11 private $option_name = 'cdegn_options';
12
13 /** @var Meow_CDEGN_Snippets_Code_Snippets */
14 protected $snippets_code_snippets = null;
15
16 /** @var Meow_CDEGN_Snippets_Wpcode */
17 protected $snippets_wpcode = null;
18
19 public function __construct() {
20 $this->site_url = get_site_url();
21 $this->is_cli = defined( 'WP_CLI' ) && WP_CLI;
22 add_action( 'plugins_loaded', array( $this, 'init' ) );
23
24 $this->snippets_code_snippets = new Meow_CDEGN_Snippets_Code_Snippets();
25 $this->snippets_wpcode = new Meow_CDEGN_Snippets_Wpcode();
26 }
27
28 public function init() {
29 // Part of the core, settings and stuff
30 $this->admin = new Meow_CDEGN_Admin( $this );
31 new Meow_CDEGN_Rest( $this );
32 }
33
34 #region Code Snippets
35
36 /**
37 * Add the new option to the cdegn_functions option.
38 *
39 * @param array $new_option
40 * @return void
41 */
42 public function add_cdegn_functions( array $new_option ): void {
43 $cdegn_functions = get_option( 'cdegn_functions', [] );
44
45 // Replace the option if it already exists, otherwise add it
46 $index = $this->cdegn_functions_search( $new_option, $cdegn_functions );
47 if ( $index === false ) {
48 $cdegn_functions[] = $new_option;
49 } else {
50 $cdegn_functions[$index] = $new_option;
51 }
52
53 update_option( 'cdegn_functions', $cdegn_functions );
54 }
55
56 /**
57 * Remove the option in the cdegn_functions option.
58 *
59 * @param int $snippet_id
60 * @param string $snippet_src
61 * @return void
62 */
63 public function remove_cdegn_functions( int $snippet_id, string $snippet_src ): void {
64 $cdegn_functions = get_option( 'cdegn_functions', [] );
65
66 // Remove the option if it exists, otherwise do nothing
67 $index = $this->cdegn_functions_search( [ 'snippet_id' => $snippet_id, 'snippet_src' => $snippet_src ], $cdegn_functions );
68 if ( $index === false ) {
69 return;
70 }
71
72 unset( $cdegn_functions[$index] );
73 $cdegn_functions = array_values( $cdegn_functions );
74 update_option( 'cdegn_functions', $cdegn_functions );
75 }
76
77 /**
78 * Searches the cdegn_functions array for a given cdegn_function.
79 * and returns the first corresponding key if successful.
80 *
81 * @param array $needle_cdegn_function
82 * @param array $haystack_cdegn_functions
83 * @return int|false
84 */
85 protected function cdegn_functions_search( array $needle_cdegn_function, array $haystack_cdegn_functions ) {
86 $index = false;
87 foreach ( $haystack_cdegn_functions as $key => $cdegn_function ) {
88 if (
89 $cdegn_function['snippet_id'] === $needle_cdegn_function['snippet_id']
90 && $cdegn_function['snippet_src'] === $needle_cdegn_function['snippet_src']
91 ) {
92 $index = $key;
93 break;
94 }
95 }
96 return $index;
97 }
98
99 /**
100 * Analyze a code snippet.
101 *
102 * @param int $snippet_id
103 * @param string $snippet_src
104 * @return array
105 */
106 public function analyze_code( int $snippet_id, string $snippet_src ): array {
107 $this->check_snippet_src_availability( $snippet_src );
108
109 $snippet = $this->get_snippet( $snippet_id, $snippet_src );
110 return $this->parse_snippet_code( $snippet->code() );
111 }
112
113 /**
114 * Get a specific snippet.
115 *
116 * @param int $snippet_id
117 * @param string $snippet_src
118 * @return Meow_CDEGN_Models_Snippet
119 */
120 public function get_snippet( int $snippet_id, string $snippet_src ): Meow_CDEGN_Models_Snippet {
121 switch ( $snippet_src ) {
122 case Meow_CDEGN_Snippets_Code_Snippets::$src:
123 return $this->snippets_code_snippets->getById( $snippet_id );
124 case Meow_CDEGN_Snippets_Wpcode::$src:
125 return $this->snippets_wpcode->getById( $snippet_id );
126 }
127 throw new Exception( __( 'Unsupported source selected.', 'code-engine' ) );
128 }
129
130 /**
131 * Parse a snippet code.
132 *
133 * @param string $code
134 * @return array
135 */
136 protected function parse_snippet_code( string $code ): array {
137 $pattern = '/function\s+(\w+)\s*\((.*?)\)/';
138 if ( preg_match_all( $pattern, $code, $matches ) !== 1 ) {
139 throw new Exception( __( 'Input must contain exactly one function definition.', 'code-engine') );
140 }
141
142 $function_name = $matches[1][0];
143 $arg_string = $matches[2][0];
144
145 $args = [];
146 if ( $arg_string ) {
147 $arg_parts = explode( ',', $arg_string );
148 foreach ( $arg_parts as $arg_part ) {
149 $arg_part = trim( $arg_part );
150 if ( strpos( $arg_part, '=' ) !== false ) {
151 list( $argName, $argDefault ) = explode( '=', $arg_part, 2 );
152 $args[ trim( $argName )] = [
153 'default' => trim( $argDefault )
154 ];
155 } else {
156 $args[ trim( $arg_part )] = [];
157 }
158 }
159 }
160
161 return [
162 'function_name' => $function_name,
163 'args' => $args
164 ];
165 }
166
167 /**
168 * Get the code quality of a code snippet via the AI Engine.
169 * Throws an exception if the AI Engine is not installed.
170 *
171 * @param int $snippet_id
172 * @param string $snippet_src
173 * @return string
174 * @throws Exception
175 */
176 public function get_code_quality_via_ai_engine( int $snippet_id, string $snippet_src ): string {
177 $this->check_snippet_src_availability( $snippet_src );
178
179 global $mwai;
180 if ( !isset( $mwai ) ) {
181 throw new Exception( __( 'AI Engine is not installed. Please download it <a href="https://wordpress.org/plugins/ai-engine/" target="_blank">here</a>.', 'code-engine' ) );
182 }
183
184 $snippet = $this->get_snippet( $snippet_id, $snippet_src );
185 $result = $mwai->simpleTextQuery( "Please check this code, in terms of quality, and security. List the potential issues. Each issue should be on one line, use a line return between each issue. Keep the issues and explanations short. Maximum of 10 issues. Here is the code:\n\n" . $snippet->code() );
186 return nl2br( $result );
187 }
188
189 /**
190 * Check the snippet source availability.
191 * Throws an exception if the snippet source is not supported.
192 *
193 * @param string $snippet_src
194 * @return void
195 * @throws Exception
196 */
197 protected function check_snippet_src_availability( string $snippet_src ): void {
198 $support_srcs = [
199 Meow_CDEGN_Snippets_Code_Snippets::$src,
200 Meow_CDEGN_Snippets_Wpcode::$src,
201 ];
202 if ( !in_array( $snippet_src, $support_srcs, true ) ) {
203 throw new Exception( __( 'Only Code Snippets and WPCode are supported for now.', 'code-engine' ) );
204 }
205 }
206
207 #endregion
208
209 #region Capabilities
210
211 public function can_access_settings() {
212 return apply_filters( 'cdegn_allow_setup', current_user_can( 'manage_options' ) );
213 }
214
215 public function can_access_features() {
216 return apply_filters( 'cdegn_allow_usage', current_user_can( 'administrator' ) );
217 }
218
219 #endregion
220
221 #region Options
222
223 public function get_option( $option, $default = null ) {
224 $options = $this->get_all_options();
225 return $options[$option] ?? $default;
226 }
227
228 public function get_all_options( $force = false ) {
229 // We could cache options this way, but if we do, the apply_filters seems to be called too early.
230 // That causes issues with filters used to modify the options dynamically (in AI Engine, for example).
231 // if ( !$force && !is_null( $this->options ) ) {
232 // return $this->options;
233 // }
234 $options = get_option( $this->option_name, [] );
235 foreach ( CDEGN_OPTIONS as $key => $value ) {
236 if ( !isset( $options[$key] ) ) {
237 $options[$key] = $value;
238 }
239 }
240 return $options;
241 }
242
243 public function update_options( $options ) {
244 if ( !update_option( $this->option_name, $options, false ) ) {
245 return false;
246 }
247 $options = $this->get_all_options( true );
248 return $options;
249 }
250
251 public function update_option( $option, $value ) {
252 $options = $this->get_all_options( true );
253 $options[$option] = $value;
254 return $this->update_options( $options );
255 }
256
257 public function reset_options() {
258 delete_option( $this->option_name );
259 return $this->get_all_options();
260 }
261
262 #endregion
263 }
264
265 ?>
266