PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / 0.0.2
Code Engine – PHP Snippets, AI Functions & Automation for WordPress v0.0.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/rest.php +99 -825 trunk0.0.2 View file →
@@ -1,893 +1,167 @@
1 1 <?php
2 2
3 -class Meow_MWCODE_Rest
3 +class Meow_CDEGN_Rest
4 4 {
5 - private $admin = null;
6 5 private $core = null;
7 - private $snippet = null;
8 6 private $namespace = 'code-engine/v1';
9 7
10 - private $bearer_token = null;
11 -
12 - public function __construct( $core, $admin, $snippet ) {
8 + public function __construct( $core ) {
13 9 if ( !current_user_can( 'administrator' ) ) {
14 10 return;
15 11 }
16 12 $this->core = $core;
17 - $this->admin = $admin;
18 - $this->snippet = $snippet;
19 13 add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
20 14 }
21 15
22 - function rest_api_init() {
16 + public function rest_api_init() {
23 17 try {
24 - #region REST Settings
25 - register_rest_route( $this->namespace, '/settings/update', array(
18 + // POST endpoints
19 + register_rest_route( $this->namespace, '/register', array(
26 20 'methods' => 'POST',
27 21 'permission_callback' => array( $this->core, 'can_access_settings' ),
28 - 'callback' => array( $this, 'rest_settings_update' )
22 + 'callback' => array( $this, 'rest_register' ),
29 23 ) );
30 - register_rest_route( $this->namespace, '/settings/list', array(
31 - 'methods' => 'GET',
32 - 'permission_callback' => array( $this->core, 'can_access_settings' ),
33 - 'callback' => array( $this, 'rest_settings_list' ),
34 - ) );
35 - register_rest_route( $this->namespace, '/settings/reset', array(
24 + register_rest_route( $this->namespace, '/unregister', array(
36 25 'methods' => 'POST',
37 26 'permission_callback' => array( $this->core, 'can_access_settings' ),
38 - 'callback' => array( $this, 'rest_settings_reset' ),
27 + 'callback' => array( $this, 'rest_unregister' ),
39 28 ) );
40 - register_rest_route( $this->namespace, '/settings/functions', array(
41 - 'methods' => 'GET',
42 - 'permission_callback' => array( $this->core, 'can_access_settings' ),
43 - 'callback' => array( $this, 'rest_export_functions' ),
44 - ) );
45 - register_rest_route( $this->namespace, '/settings/functions/replace', array(
29 + register_rest_route( $this->namespace, '/refresh', array(
46 30 'methods' => 'POST',
47 31 'permission_callback' => array( $this->core, 'can_access_settings' ),
48 - 'callback' => array( $this, 'rest_replace_functions' ),
32 + 'callback' => array( $this, 'rest_refresh' ),
49 33 ) );
50 - register_rest_route( $this->namespace, '/settings/functions/raw', array(
51 - 'methods' => 'GET',
52 - 'permission_callback' => array( $this->core, 'can_access_settings' ),
53 - 'callback' => array( $this, 'rest_functions_raw' ),
54 - ) );
55 - register_rest_route( $this->namespace, '/settings/functions/raw', array(
34 + register_rest_route( $this->namespace, '/check-quality', array(
56 35 'methods' => 'POST',
57 36 'permission_callback' => array( $this->core, 'can_access_settings' ),
58 - 'callback' => array( $this, 'rest_functions_raw_update' ),
37 + 'callback' => array( $this, 'rest_check_quality' ),
59 38 ) );
60 - #endregion
61 39
62 - #region MISC
63 - register_rest_route( $this->namespace, '/quick_start', array(
64 - 'methods' => 'POST',
65 - 'permission_callback' => array( $this->core, 'can_access_settings' ),
66 - 'callback' => array( $this, 'rest_quick_start' ),
67 - ) );
68 -
69 - register_rest_route( $this->namespace, '/server_clock', array(
40 + // GET endpoints
41 + register_rest_route( $this->namespace, '/functions', array(
70 42 'methods' => 'GET',
71 43 'permission_callback' => array( $this->core, 'can_access_settings' ),
72 - 'callback' => array( $this, 'rest_server_clock' ),
44 + 'callback' => array( $this, 'rest_functions' ),
73 45 ) );
74 -
75 - register_rest_route( $this->namespace, '/fetch_posts', array(
76 - 'methods' => 'POST',
77 - 'permission_callback' => array( $this->core, 'can_access_features' ),
78 - 'callback' => array( $this, 'rest_fetch_posts' ),
79 - 'args' => array(
80 - 'search' => array( 'required' => false ),
81 - 'offset' => array( 'required' => false, 'default' => 0 ),
82 - 'limit' => array( 'required' => false, 'default' => 10 ),
83 - )
84 - ) );
85 -
86 - #endregion
87 -
88 - #region REST AI Engine
89 - register_rest_route( $this->namespace, '/ai_read_comments', array(
90 - 'methods' => 'POST',
91 - 'permission_callback' => array( $this->core, 'can_access_settings' ),
92 - 'callback' => array( $this, 'rest_ai_read_comments' ),
93 - ) );
94 - register_rest_route( $this->namespace, '/ai_query', array(
95 - 'methods' => 'POST',
96 - 'permission_callback' => array( $this->core, 'can_access_settings' ),
97 - 'callback' => array( $this, 'rest_ai_query' ),
98 - ) );
99 - #endregion
100 -
101 - #region REST Run
102 - register_rest_route( $this->namespace, '/run/test', [
103 - 'methods' => 'POST',
104 - 'callback' => [ $this, 'rest_test' ],
105 - 'permission_callback' => [ $this->core, 'can_access_settings' ],
106 - ] );
107 -
108 - register_rest_route( $this->namespace, '/run/lint', [
109 - 'methods' => 'POST',
110 - 'callback' => [ $this, 'rest_lint' ],
111 - 'permission_callback' => [ $this->core, 'can_access_settings' ],
112 - ] );
113 - #endregion
114 -
115 - #region REST Snippets
116 -
117 - register_rest_route($this->namespace, '/snippets/list', [
118 - 'methods' => 'POST',
119 - 'callback' => [$this, 'rest_list'],
120 - 'permission_callback' => [$this->core, 'can_access_settings'],
121 - ]);
122 -
123 - register_rest_route( $this->namespace, '/snippets/stats', [
124 - 'methods' => 'GET',
125 - 'callback' => [$this, 'rest_stats'],
126 - 'permission_callback' => [$this->core, 'can_access_settings'],
127 - ]);
128 -
129 - register_rest_route($this->namespace, '/snippets/tags', [
130 - 'methods' => 'POST',
131 - 'callback' => [$this, 'rest_tags'],
132 - 'permission_callback' => [$this->core, 'can_access_settings'],
133 - ]);
134 -
135 - register_rest_route($this->namespace, '/snippets/import', [
136 - 'methods' => 'GET',
137 - 'callback' => [$this, 'rest_import'],
138 - 'permission_callback' => [$this->core, 'can_access_settings'],
139 - ]);
140 -
141 - register_rest_route($this->namespace, '/snippets/add', array(
142 - 'methods' => 'POST',
143 - 'callback' => array($this, 'rest_add'),
144 - 'permission_callback' => array($this->core, 'can_access_settings')
145 - ));
146 -
147 - register_rest_route($this->namespace, '/snippets/update', array(
148 - 'methods' => 'POST',
149 - 'callback' => array($this, 'rest_update'),
150 - 'permission_callback' => array($this->core, 'can_access_settings')
151 - ));
152 -
153 - register_rest_route($this->namespace, '/snippets/delete', array(
154 - 'methods' => 'POST',
155 - 'callback' => array($this, 'rest_delete'),
156 - 'permission_callback' => array($this->core, 'can_access_settings')
157 - ));
158 -
159 -
160 - register_rest_route($this->namespace, '/snippets/replace', array(
161 - 'methods' => 'POST',
162 - 'callback' => array($this, 'rest_replace'),
163 - 'permission_callback' => array($this->core, 'can_access_settings')
164 - ));
165 -
166 - register_rest_route($this->namespace, '/snippets/delete_duplicates', array(
167 - 'methods' => 'POST',
168 - 'callback' => array($this, 'rest_delete_duplicates'),
169 - 'permission_callback' => array($this->core, 'can_access_settings')
170 - ));
171 -
172 -
173 - // SNIPPETS ENDPOINTS
174 - $snippets = $this->snippet->select(
175 - null, // offset
176 - -1, // limit
177 - [
178 - [ 'accessor' => 'active', 'value' => 1 ],
179 - [ 'accessor' => 'endpoint', 'value' => 1 ],
180 - ], // filter
181 - null, // sort
182 - );
183 -
184 - $public_api_enabled = $this->core->get_option( 'api_endpoint', false );
185 - if ( (int) $snippets['total'] > 0 && $public_api_enabled ) {
186 -
187 - $this->bearer_token = $this->core->get_option( 'api_token', null );
188 - if ( !empty( $this->bearer_token ) ) {
189 - add_filter( 'mwcode_allow_public_api', [ $this, 'auth_via_bearer_token' ], 10, 3 );
190 - }
191 -
192 - $data = $snippets['data'];
193 -
194 - foreach ( $data as $snippet ) {
195 - register_rest_route( $this->namespace, '/snippets-endpoint/' . $snippet['endpoint'], array(
196 - 'methods' => $snippet['method'] ?: 'POST',
197 - 'permission_callback' => function( $request ) {
198 - return $this->can_access_public_api( 'snippets-endpoint', $request );
199 - },
200 - 'callback' => array( $this, 'rest_call_snippet' ),
201 - 'args' => array(
202 - 'id' => array( 'required' => true, 'default' => $snippet['id'] ),
203 - ),
204 - ) );
205 -
206 - //$this->core->log( "Registered REST API endpoint: /{$this->namespace}/snippets-endpoint/{$snippet['endpoint']} ({$snippet['method']})" );
207 - }
208 - }
209 -
210 - #endregion
211 -
212 - #region REST Logs
213 - register_rest_route( $this->namespace, '/get_logs', array(
214 - 'methods' => 'GET',
215 - 'permission_callback' => array( $this->core, 'can_access_features' ),
216 - 'callback' => array( $this, 'rest_get_logs' )
217 - ) );
218 - register_rest_route( $this->namespace, '/clear_logs', array(
219 - 'methods' => 'GET',
220 - 'permission_callback' => array( $this->core, 'can_access_features' ),
221 - 'callback' => array( $this, 'rest_clear_logs' )
222 - ) );
223 -
224 - #endregion
225 46 }
226 - catch (Exception $e) {
227 - var_dump($e);
47 + catch ( Exception $e ) {
48 + var_dump( $e );
228 49 }
229 50 }
230 51
231 - #region Auth
232 -
233 - public function auth_via_bearer_token( $allow, $feature, $extra ) {
234 - if ( !empty( $extra ) && !empty( $extra->get_header( 'Authorization' ) ) ) {
235 - $token = $extra->get_header( 'Authorization' );
236 - $token = str_replace( 'Bearer ', '', $token );
237 - if ( $token === $this->bearer_token ) {
238 - $admin = $this->get_admin_user();
239 - wp_set_current_user( $admin->ID, $admin->user_login );
240 - return true;
52 + public function rest_register( $request ) {
53 + try {
54 + $json = $request->get_json_params();
55 + $snippet_id = isset( $json['snippet_id'] ) ? (int)$json['snippet_id'] : null;
56 + $snippet_src = isset( $json['snippet_src'] ) ? (string)$json['snippet_src'] : null;
57 + if ( !$snippet_id || !$snippet_src ) {
58 + throw new Exception( __( 'Snippet ID and Snippet src are required.', 'code-engine') );
241 59 }
242 - }
243 - return $allow;
244 - }
245 60
246 - function can_access_public_api( $feature, $extra ) {
247 - $logged_in = is_user_logged_in();
248 - return apply_filters( 'mwcode_allow_public_api', $logged_in, $feature, $extra );
249 - }
61 + $snippet_information = $this->core->analyze_code( $snippet_id, $snippet_src );
62 + $new_option = [
63 + 'snippet_id' => $snippet_id,
64 + 'snippet_src' => $snippet_src,
65 + 'name' => $snippet_information['function_name'],
66 + 'desc' => '',
67 + 'args' => $snippet_information['args'],
68 + ];
69 + $this->core->add_cdegn_functions( $new_option );
250 70
251 - function get_admin_user() {
252 - $admin = get_users( [ 'role' => 'administrator' ] );
253 - if ( !empty( $admin ) ) {
254 - return $admin[0];
255 - }
256 - return null;
257 - }
71 + $cdegn_function = new Meow_CDEGN_Models_Cdegn_Function( $new_option );
258 72
259 - #endregion
260 -
261 - #region Logs
262 -
263 - function rest_get_logs() {
264 - $logs = $this->core->get_logs();
265 - return new WP_REST_Response( [ 'success' => true, 'data' => $logs ], 200 );
266 - }
267 -
268 - function rest_clear_logs() {
269 - $this->core->clear_logs();
270 - return new WP_REST_Response( [ 'success' => true ], 200 );
271 - }
272 -
273 -
274 - #endregion
275 -
276 - #region Settings
277 -
278 - function rest_settings_list() {
279 - return new WP_REST_Response( [
280 - 'success' => true,
281 - 'options' => $this->core->get_all_options()
282 - ], 200 );
283 - }
284 -
285 -
286 - function rest_settings_update( $request ) {
287 - try {
288 - $params = $request->get_json_params();
289 - $value = $params['options'];
290 - $options = $this->core->update_options( $value );
291 - $success = !!$options;
292 - $message = __( $success ? 'OK' : "Could not update options.", 'code-engine' );
293 - return new WP_REST_Response([ 'success' => $success, 'message' => $message, 'options' => $options ], 200 );
73 + return new WP_REST_Response( [
74 + 'message' => 'Registered successfully.',
75 + 'overview' => $cdegn_function->overview(),
76 + ], 200 );
294 77 }
295 78 catch ( Exception $e ) {
296 - return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
79 + return new WP_REST_Response( [ 'message' => $e->getMessage() ], 500 );
297 80 }
298 81 }
299 82
300 - function rest_settings_reset() {
301 - try {
302 - $options = $this->core->reset_options();
303 - $success = !!$options;
304 - $message = __( $success ? 'OK' : "Could not reset options.", 'code-engine' );
305 - return new WP_REST_Response([ 'success' => $success, 'message' => $message, 'options' => $options ], 200 );
306 - }
307 - catch ( Exception $e ) {
308 - return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
309 - }
310 - }
311 -
312 - function rest_export_functions() {
313 - $functions = $this->snippet->get_functions();
314 - return new WP_REST_Response([ 'success' => true, 'functions' => $functions ], 200);
315 - }
316 -
317 - function rest_replace_functions( $request ) {
318 - try {
319 - $params = $request->get_json_params();
320 - $functions = $params['functions'];
321 -
322 - $this->snippet->set_functions( $functions );
323 -
324 - return new WP_REST_Response([ 'success' => true, 'data' => $functions ], 200);
325 - } catch (Exception $e) {
326 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
327 - }
328 -
329 - }
330 -
331 - function rest_functions_raw() {
332 - $functions = $this->snippet->get_functions_raw();
333 - return new WP_REST_Response([ 'success' => true, 'functions' => $functions ], 200);
334 - }
335 -
336 - function rest_functions_raw_update( $request ) {
337 - try {
338 - $params = $request->get_json_params();
339 - $functions = $params['functions'];
340 -
341 - if ( empty( $functions ) ) {
342 - $functions = [];
343 - } else {
344 - // Decode the JSON string into a PHP array
345 - $functions = json_decode($functions, true);
346 -
347 - // Check if decoding was successful
348 - if (json_last_error() !== JSON_ERROR_NONE) {
349 - return new WP_REST_Response([ 'success' => false, 'message' => 'Invalid JSON format' ], 400);
350 - }
83 + public function rest_unregister( $request ) {
84 + try {
85 + $json = $request->get_json_params();
86 + $snippet_id = isset( $json['snippet_id'] ) ? (int)$json['snippet_id'] : null;
87 + $snippet_src = isset( $json['snippet_src'] ) ? (string)$json['snippet_src'] : null;
88 + if ( !$snippet_id || !$snippet_src ) {
89 + throw new Exception( __( 'Snippet ID and Snippet src are required.', 'code-engine') );
351 90 }
352 -
353 - $this->snippet->set_functions_raw( $functions );
354 -
355 - return new WP_REST_Response([ 'success' => true, 'data' => $functions ], 200);
356 - } catch (Exception $e) {
357 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
358 - }
359 - }
360 91
361 - #endregion
92 + $this->core->remove_cdegn_functions( $snippet_id, $snippet_src );
362 93
363 -
364 - #region MISC
365 -
366 - function rest_quick_start( $request ) {
367 - global $mwai;
368 -
369 - if ( is_null( $mwai ) || !isset( $mwai ) ) {
370 - return new WP_REST_Response([ 'success' => false, 'message' => 'AI Engine is not available.' ], 500 );
94 + return new WP_REST_Response( [
95 + 'message' => 'Unregistered successfully.',
96 + ], 200 );
371 97 }
372 -
373 - $params = $request->get_json_params();
374 - if( empty( $params['prompt'] ) ) {
375 - return new WP_REST_Response([ 'success' => false, 'message' => 'Prompt is required.' ], 500 );
98 + catch ( Exception $e ) {
99 + return new WP_REST_Response( [ 'message' => $e->getMessage() ], 500 );
376 100 }
377 -
378 - $user_prompt = "<user_prompt>" . $params['prompt'] . "</user_prompt>";
379 -
380 - // Main instructions: explain the categories and how to generate the snippet
381 - $prompt_instructions = "<instruction>"
382 - . "Create a code snippet based on the user's prompt for a WordPress environment. "
383 - . "The snippet can be in PHP or JS. If the prompt does not specify the language, assume PHP. "
384 - . "Below are the categories you can use for the code snippet:\n\n"
385 - . "1. 'function': This can be either a JS or PHP function. The snippet should only contain the function itself, "
386 - . " with no code outside its declaration. The function can take parameters; for each parameter, specify a "
387 - . " default value, type ('string', 'number', 'boolean', 'mixed', etc.), required boolean, and a description.\n"
388 - . "2. 'scheduled': This can only be PHP. It’s code that will be run by a cron job for scheduled tasks. "
389 - . " If the user wants a task to run over time or on a schedule, use this category. The scheduling itself "
390 - . " is handled automatically, so you only need to generate the main code. You can specify a target hour "
391 - . " and minute.\n"
392 - . "3. 'persistent', 'back', 'front': This is a PHP-only snippet for use across the website, typically for WordPress filters or "
393 - . " action hooks. You can specify if the snippet should be 'persistent', 'front', or 'back' to indicate "
394 - . " whether it loads on the front end, back end, or both. These are know as global snippets.\n"
395 - . "4. 'content': This can be either 'content_js' or 'content_php'. A shortcode will be generated for this "
396 - . " snippet so the user can place it inside a post.\n"
397 - . "</instruction>";
398 -
399 - // Goal: specify what data to generate
400 - $prompt_goal = "<goal>"
401 - . "Generate the snippet’s code and the metadata needed to describe it, including:\n"
402 - . "- A snippet name\n"
403 - . "- A description\n"
404 - . "- The type (one of 'backend', 'frontend', 'function', 'persistent', 'scheduled', 'content_php', 'content_js')\n"
405 - . "- Tags (comma-separated)\n"
406 - . "For certain types, include additional details:\n"
407 - . "- For a 'function' type, provide the scope ('js' or 'php') and its parameters, including default values, types, required and descriptions.\n"
408 - . "- For a 'scheduled' snippet, specify the target hour and minute.\n"
409 - . "</goal>";
410 -
411 - // Warning: any additional information the user should know
412 - $prompt_warning = "<warning>"
413 - . "Dont use any <?php tags, <script> tags or markdown ``` format, just provide the raw code. "
414 - . " When using a 'scheduled' all the cron scheduling is handled automatically, so you only need to generate the main code and dont need to worry about the scheduling logic. "
415 - . "If the type is 'function', the code should only contain the function itself, with no code outside its declaration, as well as no comments outside of the function. THIS IS THE CASE ONLY FOR FUNCTIONS. For any other type, the code is invoked using eval() and should be a complete snippet of code. If the snippet is a function type the default values should NOT be deplared in the parameters, this will be done automatically. If the snippet is not a function type but your wirte a function, make sure to call the function at the end of the code. "
416 - . " If the snippet is a content type, the code should be the content of the shortcode, not the shortcode itself. and NOT a function, it should be raw code with an echo statement. There are no attributes for content snippets. The shortcode is generated automatically like [code-engine id=''] and the id is the snippet id. "
417 - . "</warning>";
418 -
419 - // Format: how to structure the final output
420 - $prompt_format = "<format>"
421 - . "Return all information in JSON format with the following keys:\n"
422 - . "- 'code': the code for the snippet. It should not be on one line only, make sure it is well formated.\n"
423 - . "- 'name': the snippet name\n"
424 - . "- 'description': a description of the snippet\n"
425 - . "- 'type': the snippet type\n"
426 - . "- 'tags': the snippet tags\n"
427 - . "- 'scope': the scope (only applicable if type is 'function')\n"
428 - . "- 'parameters': an array of parameter objects (only for 'function'), each with 'name', 'default', 'type', and 'description'\n"
429 - . "- 'target_hour': the target hour (only for 'scheduled')\n"
430 - . "- 'target_minute': the target minute (only for 'scheduled')\n"
431 - . "- 'misc': any additional information. If you had to assume some stuff, like a filter name or a thing the user didn't think about, let it know by adding messages in this key.\n"
432 - . "</format>";
433 -
434 - // Combine all prompt parts
435 - $prompt = $prompt_instructions . $prompt_goal . $prompt_format . $prompt_warning . $user_prompt;
436 -
437 - $response = $mwai->simpleJsonQuery( $prompt );
438 -
439 - return new WP_REST_Response( [ 'success' => true, 'data' => $response ], 200 );
440 101 }
441 102
442 - function rest_server_clock() {
443 - $now = current_datetime();
444 - $now = $now->format( 'H:i:s ( Y/m/d )' );
103 + public function rest_refresh( $request ) {
104 + try {
105 + $json = $request->get_json_params();
106 + $snippet_id = isset( $json['snippet_id'] ) ? (int)$json['snippet_id'] : null;
107 + $snippet_src = isset( $json['snippet_src'] ) ? (string)$json['snippet_src'] : null;
108 + if ( !$snippet_id || !$snippet_src ) {
109 + throw new Exception( __( 'Snippet ID and Snippet src are required.', 'code-engine') );
110 + }
445 111
446 - return new WP_REST_Response( [ 'success' => true, 'time' => $now ], 200 );
447 - }
112 + $snippet_information = $this->core->analyze_code( $snippet_id, $snippet_src );
113 + $new_option = [
114 + 'snippet_id' => $snippet_id,
115 + 'snippet_src' => 'Code Snippets',
116 + 'name' => $snippet_information['function_name'],
117 + 'desc' => '',
118 + 'args' => $snippet_information['args'],
119 + ];
120 + $this->core->add_cdegn_functions( $new_option );
448 121
449 - function rest_fetch_posts( $request ) {
450 - try {
451 - $params = $request->get_json_params();
452 - $search = isset($params['search']) ? $params['search'] : '';
453 - $offset = isset($params['offset']) ? intval($params['offset']) : 0;
454 - $limit = isset($params['limit']) ? intval($params['limit']) : 10;
122 + $cdegn_function = new Meow_CDEGN_Models_Cdegn_Function( $new_option );
455 123
456 - global $wpdb;
457 - $searchPlaceholder = $search ? '%' . $search . '%' : '';
458 - $where_search_clause = $search ? $wpdb->prepare(
459 - "AND ( p.post_title LIKE %s OR p.post_content LIKE %s OR p.post_name LIKE %s ) ",
460 - $searchPlaceholder,
461 - $searchPlaceholder,
462 - $searchPlaceholder
463 - ) : '';
464 -
465 - $posts = $wpdb->get_results(
466 - $wpdb->prepare(
467 - "SELECT p.ID, p.post_title, p.post_date, p.post_status, u.display_name as author
468 - FROM $wpdb->posts p
469 - LEFT JOIN $wpdb->users u ON p.post_author = u.ID
470 - WHERE p.post_type = 'post'
471 - AND p.post_status IN ('publish', 'draft', 'private')
472 - $where_search_clause
473 - ORDER BY p.post_date DESC
474 - LIMIT %d, %d",
475 - $offset,
476 - $limit
477 - ),
478 - OBJECT
479 - );
480 -
481 - $posts_count = (int)$wpdb->get_var(
482 - "SELECT COUNT(*)
483 - FROM $wpdb->posts p
484 - WHERE p.post_type = 'post'
485 - AND p.post_status IN ('publish', 'draft', 'private')
486 - $where_search_clause"
487 - );
488 -
489 - $data = array_map(function($post) {
490 - return [
491 - 'id' => $post->ID,
492 - 'title' => $post->post_title,
493 - 'date' => $post->post_date,
494 - 'author' => $post->author,
495 - 'status' => $post->post_status
496 - ];
497 - }, $posts);
498 -
499 - return new WP_REST_Response([
500 - 'success' => true,
501 - 'data' => $data,
502 - 'total' => $posts_count
503 - ], 200);
504 - } catch (Exception $e) {
505 - return new WP_REST_Response(['success' => false, 'message' => $e->getMessage()], 500);
124 + return new WP_REST_Response( [
125 + 'message' => 'Refreshed successfully.',
126 + 'overview' => $cdegn_function->overview(),
127 + ], 200 );
506 128 }
507 - }
508 -
509 - #endregion
510 -
511 - #region AI Engine
512 -
513 - function rest_ai_query( $request ) {
514 -
515 - $query = $request->get_param('query');
516 - $code = $request->get_param('code');
517 -
518 - global $mwai;
519 -
520 - if ( is_null( $query ) || !isset( $query ) ) {
521 - return new WP_REST_Response([ 'success' => false, 'message' => 'No query provided.' ], 500 );
129 + catch ( Exception $e ) {
130 + return new WP_REST_Response( [ 'message' => $e->getMessage() ], 500 );
522 131 }
523 -
524 - if ( is_null( $mwai ) || !isset( $mwai ) ) {
525 - return new WP_REST_Response([ 'success' => false, 'message' => 'AI Engine is not available.' ], 500 );
526 - }
527 -
528 - $prompt = "In your response, do not include any explanation outside the code if this is a functon, everything should be inside. Any information should be added as comments only, not example function calls. Do not use <?php tags or markdown ``` format, just provide the raw code. Based on the code provided, modify it as needed: $query\n\n$code";
529 - $response = $mwai->simpleTextQuery( $prompt );
530 -
531 - return new WP_REST_Response([ 'success' => true, 'code' => $response ], 200);
532 132 }
533 133
534 - function rest_ai_read_comments( $request ) {
535 - $code = $request->get_param('code');
536 - global $mwai;
537 -
538 - if ( is_null( $code ) || !isset( $code ) ) {
539 - return new WP_REST_Response([ 'success' => false, 'message' => 'No code provided.' ], 500 );
540 - }
541 -
542 - if ( is_null( $mwai ) || !isset( $mwai ) ) {
543 - return new WP_REST_Response([ 'success' => false, 'message' => 'AI Engine is not available.' ], 500 );
544 - }
545 -
546 - $prompt = "Based on the comments in the code, modify the snippet so it accords with what the comments say. In your response, only include the modfied code with the comments removed and nothing else, no <?php tag, no markdown ``` format, just the raw code.\n\n$code";
547 - $prompt = apply_filters( 'mwcode_ai_suggestion_prompt', $prompt, $code );
548 -
549 - $response = $mwai->simpleTextQuery( $prompt );
550 -
551 - return new WP_REST_Response([ 'success' => true, 'code' => $response ], 200);
552 -
553 - }
554 -
555 - #endregion
556 -
557 - #region Snippets
558 -
559 - function rest_call_snippet( $request ) {
560 - try {
561 - $route = $request->get_route();
562 - $endpoint = basename( $route );
563 -
564 - $id = $request->get_param( 'id' );
565 -
566 - $snippet = $this->snippet->select_one( $id );
567 - if ( empty( $snippet ) || $snippet['endpoint'] !== $endpoint ) {
568 - return new WP_REST_Response( ['success' => false, 'message' => 'Snippet not found.' ], 404 );
569 - } elseif ( !$snippet['active'] ) {
570 - return new WP_REST_Response( ['success' => false, 'message' => 'Snippet is not active.' ], 403 );
134 + public function rest_check_quality( $request ) {
135 + try {
136 + $json = $request->get_json_params();
137 + $snippet_id = isset( $json['snippet_id'] ) ? (int)$json['snippet_id'] : null;
138 + $snippet_src = isset( $json['snippet_src'] ) ? (string)$json['snippet_src'] : null;
139 + if ( !$snippet_id || !$snippet_src ) {
140 + throw new Exception( __( 'Snippet ID and Snippet src are required.', 'code-engine') );
571 141 }
572 142
573 - // Get the arguments from the request
574 - $args = $request->get_param('args');
575 - if ( !empty( $args ) ) {
576 - $args = json_decode( $args, true );
577 - if ( json_last_error() !== JSON_ERROR_NONE ) {
578 - throw new Exception('Failed to decode JSON from args: ' . json_last_error_msg() );
579 - }
580 - }
143 + $detail = $this->core->get_code_quality_via_ai_engine( $snippet_id, $snippet_src );
581 144
582 - // Get the body from the request
583 - $body = $request->get_body();
584 - if ( !empty( $body ) ) {
585 - $bodyDecoded = json_decode( $body, true );
586 - if ( json_last_error() !== JSON_ERROR_NONE ) {
587 - throw new Exception( 'Failed to decode JSON from body: ' . json_last_error_msg() );
588 - }
589 - if ( !empty( $args ) && is_array( $args ) ) {
590 - $args = array_merge( $args, $bodyDecoded );
591 - } else {
592 - $args = $bodyDecoded;
593 - }
594 - }
595 -
596 - $output = $this->core->run_snippet( $id, $args );
597 -
598 - return new WP_REST_Response( $output, 200);
599 - } catch (ParseError $e) {
600 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
601 - } catch ( Exception $e ) {
602 - return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
145 + return new WP_REST_Response( [
146 + 'success' => true,
147 + 'detail' => $detail,
148 + ], 200 );
603 149 }
604 - }
605 -
606 - public function rest_list( $request )
607 - {
608 - try {
609 - $params = $request->get_json_params();
610 - $page = $params['page'] ? intval($params['page']) : 1;
611 - $limit = $params['limit'] ?? 10;
612 - $offset = ($page - 1) * $limit;
613 -
614 - $filters = $params['filters'] ?? [];
615 -
616 - $filters = array_filter( $filters, function( $filter ) {
617 - return $filter['value'] !== 'all';
618 - });
619 -
620 - foreach ($filters as $key => $filter) {
621 - if ( $filter['accessor'] === 'scope' && $filter['value'] === 'disabled' ) {
622 - $filters[] = ['accessor' => 'active', 'value' => 0];
623 - unset( $filters[$key] );
624 - }
625 - }
626 -
627 - $sort = ['accessor' => 'id', 'by' => 'asc'];
628 - $sortByFunctionName = $params['sort']['accessor'] == 'functionName';
629 -
630 - if ( !$sortByFunctionName && !empty( $params['sort'] ) ) {
631 - $sort = $params['sort'];
632 - }
633 -
634 -
635 - if ( !empty( $filters['scope'] ) ) {
636 - //$filters['scope'] = [ 'accessor' => 'scope', 'value' => 'frontend' ];
637 - }
638 -
639 - $list = $this->snippet->select( $offset, $limit, $filters, $sort );
640 -
641 - //when listing let's reset any error message on the dashboard
642 - $this->core->update_option( 'fatal_error', '' );
643 -
644 -
645 - //TODO: Delete in future versions, we are converting the scopes since they have changed
646 - $to_update = [];
647 - foreach ( $list['data'] as $key => $snippet ) {
648 - if ( $snippet['scope'] === 'admin' ) {
649 - $list['data'][$key]['scope'] = 'backend';
650 - $to_update[] = $key;
651 - }
652 -
653 - if ( $snippet['scope'] === 'front' ) {
654 - $list['data'][$key]['scope'] = 'frontend';
655 - $to_update[] = $key;
656 - }
657 -
658 - if ( $snippet['scope'] === 'front,admin' ) {
659 - $list['data'][$key]['scope'] = 'persistent';
660 - $to_update[] = $key;
661 - }
662 -
663 - if ( $snippet['scope'] === 'library' ) {
664 - $list['data'][$key]['scope'] = 'persistent';
665 - $to_update[] = $key;
666 - }
667 -
668 - if ( $snippet['scope'] === 'interval' ) {
669 - $list['data'][$key]['scope'] = 'scheduled';
670 - $to_update[] = $key;
671 - }
672 - }
673 -
674 - foreach ( $to_update as $key ) {
675 - $snippet = $list['data'][$key];
676 - $this->core->log( "Updating snippet for new scopes: " . $snippet['id'] );
677 - $this->snippet->update( $snippet );
678 - }
679 -
680 - if ( $sortByFunctionName ) {
681 - // Manually sort by functionName
682 - usort( $list['data'], function( $a, $b ) use ( $params ) {
683 - $result = strcmp( $a['functionName'], $b['functionName'] );
684 - // If sorting by 'desc', invert the comparison result
685 - if ( $params['sort']['by'] === 'desc' ) {
686 - return -$result;
687 - }
688 - // Otherwise, return the comparison result for 'asc'
689 - return $result;
690 - } );
691 - }
692 -
693 - //$this->core->log( "snippets" . print_r($list['data'], 1) );
694 -
695 - return new WP_REST_Response([ 'success' => true, 'total' => $list['total'], 'data' => $list['data'] ], 200);
696 - } catch (Exception $e) {
697 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
698 - }
699 - }
700 -
701 - public function rest_stats( )
702 - {
703 - try {
704 - $stats = $this->snippet->stats();
705 - return new WP_REST_Response([ 'success' => true, 'data' => $stats ], 200);
706 - } catch (Exception $e) {
707 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
708 - }
709 - }
710 -
711 - public function rest_tags()
712 - {
713 - try {
714 - $list = $this->snippet->select_tags();
715 - return new WP_REST_Response([ 'success' => true, 'data' => $list ], 200);
716 - } catch (Exception $e) {
717 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
718 - }
719 - }
720 -
721 - public function rest_import( )
722 - {
723 - try {
724 - $snippet = $this->snippet->import( );
725 - return new WP_REST_Response([ 'success' => true, 'total' => $snippet ], 200);
726 - } catch (Exception $e) {
727 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
150 + catch ( Exception $e ) {
151 + return new WP_REST_Response( [ 'message' => $e->getMessage() ], 500 );
728 152 }
729 153 }
730 154
731 - public function rest_add( $request )
732 - {
733 - try {
734 - $params = $request->get_json_params();
735 - $name = $params['name'];
736 - $code = $params['code'];
737 - if ( empty( $name ) || empty( $code ) ) {
738 - throw new Exception( __( 'Name and code are required.', 'code-engine' ) );
739 - }
740 -
741 - $res = $this->core->add_snippet( $params );
742 - $snippet = $res['snippet'];
743 - $result = $res['result'];
744 -
745 - return new WP_REST_Response([ 'success' => true, 'data' => $result, 'snippet' => $snippet ], 200);
746 - } catch (Exception $e) {
747 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
748 - }
749 - }
750 -
751 - public function rest_update( $request )
752 - {
753 - try {
754 - $params = $request->get_json_params();
755 - $id = $params['id'];
756 - if ( empty( $id ) ) {
757 - throw new Exception( __( 'ID is required.', 'code-engine' ) );
758 - }
759 -
760 - $params['update'] = true;
761 - $this->snippet->validate( $params );
762 - $this->snippet->create_or_update_function_snippet( $params );
763 - $this->snippet->create_or_update_interval_snippet( $params );
764 -
765 - $params = $this->snippet->formatParamsForDatabase( $params );
766 - $result = $this->snippet->update( $params );
767 - return new WP_REST_Response([ 'success' => true, 'data' => $result ], 200);
768 - } catch (Exception $e) {
769 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
770 - }
771 - }
772 -
773 -
774 - public function rest_delete( $request )
775 - {
776 - try {
777 - $params = $request->get_json_params();
778 - $id = $params['id'];
779 -
780 - if ( empty( $id ) ) {
781 - throw new Exception( __( 'ID is required.', 'code-engine' ) );
782 - }
783 -
784 - $this->snippet->delete_function_snippet( $params );
785 - $this->snippet->delete_interval_snippet( $params );
786 -
787 - $result = $this->snippet->delete( $params );
788 -
789 - return new WP_REST_Response([ 'success' => true, 'data' => $result ], 200);
790 - } catch (Exception $e) {
791 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
792 - }
793 - }
794 -
795 - public function rest_replace( $request ){
796 - try {
797 - $params = $request->get_json_params();
798 - $snippets = $params['snippets'];
799 -
800 - // Delete all current snippets
801 - $this->snippet->delete_all();
802 -
803 - // Insert new snippets
804 - $result = [];
805 - foreach ( $snippets as $snippet ) {
806 - $this->snippet->validate( $snippet );
807 - $snippet = $this->snippet->formatParamsForDatabase( $snippet );
808 - $result[] = $this->snippet->insert( $snippet );
809 - }
810 -
811 - return new WP_REST_Response([ 'success' => true, 'data' => $result ], 200);
812 - } catch (Exception $e) {
813 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
155 + public function rest_functions() {
156 + try {
157 + return new WP_REST_Response( [
158 + 'functions' => array_map( function( $cdegn_function ) {
159 + return new Meow_CDEGN_Models_Cdegn_Function( $cdegn_function );
160 + }, get_option( 'cdegn_functions', [] ) ),
161 + ], 200 );
814 162 }
815 - }
816 -
817 - public function rest_delete_duplicates() {
818 - try {
819 - $result = $this->snippet->delete_duplicates();
820 - return new WP_REST_Response([ 'success' => true, 'data' => [ 'deleted' => $result ] ], 200);
821 - } catch (Exception $e) {
822 - return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage() ], 500 );
163 + catch ( Exception $e ) {
164 + return new WP_REST_Response( [ 'message' => $e->getMessage() ], 500 );
823 165 }
824 166 }
825 -
826 -
827 - #endregion
828 -
829 - #region Run
830 -
831 - /**
832 - * Execute a function snippet and return the result.
833 - *
834 - * It executes the provided function code with the given arguments and returns the result or any error encountered.
835 - *
836 - * @param WP_REST_Request $request The REST API request object.
837 - * @return WP_REST_Response The REST API response containing the result or error.
838 - */
839 - public function rest_test( $request ) {
840 - if ( is_array( $request ) ) {
841 - $params = $request;
842 - } else {
843 - $params = $request->get_json_params();
844 - }
845 -
846 - try {
847 - $output = "(Code Engine) No output.";
848 - $error = null;
849 -
850 - $scope = $params['scope'];
851 - if ( $scope === 'function' ) {
852 - $output = $this->core->run_snippet( null, [], $params );
853 - } else {
854 - $output = $this->core->run_non_fn_snippet( null, $params['code'], true );
855 - }
856 -
857 - $error = $output['error'] ?? null;
858 - unset( $output['error'] );
859 -
860 - return new WP_REST_Response( [ 'success' => true, 'return' => $output, 'error' => $error ], 200 );
861 - } catch ( Exception $e ) {
862 - return new WP_REST_Response( [ 'success' => false, 'message' => $e->getMessage() ], 500 );
863 - }
864 - }
865 -
866 -
867 - /**
868 - * Lint the code.
869 - *
870 - * @param $request
871 - * @return WP_REST_Response
872 - */
873 - public function rest_lint( $request ) {
874 - try {
875 - $params = $request->get_json_params();
876 - $code = $params['code'];
877 -
878 - if ( empty( $code ) ) {
879 - throw new Exception( __( 'Code is required.', 'code-engine' ) );
880 - }
881 -
882 - $linting_new_code = empty( $params['id'] );
883 - $result = $this->core->parse_snippet( $code, $linting_new_code );
884 -
885 - return new WP_REST_Response( [ 'success' => true, 'lint' => $result ], 200 );
886 - } catch ( ParseError $e ) {
887 - return new WP_REST_Response( [ 'success' => false, 'message' => $e->getMessage() ], 500 );
888 - } catch ( Exception $e ) {
889 - return new WP_REST_Response( [ 'success' => false, 'message' => $e->getMessage() ], 500 );
890 - }
891 - }
892 - #endregion
893 167 }