PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / 0.3.0
Code Engine – PHP Snippets, AI Functions & Automation for WordPress v0.3.0
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/api.php +154 -764 0.3.20.3.0 View file →
@@ -1,821 +1,211 @@
1 1 <?php
2 2
3 -class Meow_MWCODE_API {
4 - public $core;
5 - private $snippet_module;
6 - private $debug = false;
3 +class Meow_MWCODE_API
4 +{
5 + private $core = null;
6 + private $snippet = null;
7 7
8 - public function __construct( $core, $snippet_module ) {
9 - $this->core = $core;
10 - $this->snippet_module = $snippet_module;
11 - $this->debug = $this->core->get_option( 'server_debug_mode' );
12 - }
13 8
14 - #region Simple API
15 -
9 + public function __construct( $core, $snippet ) {
10 + $this->core = $core;
11 + $this->snippet = $snippet;
12 + }
13 +
16 14 /**
17 - * Get a snippet by its ID.
15 + * Get a function by its ID.
18 16 *
19 - * The options are used to filter the snippets:
17 + * The options are used to filter the functions:
20 18 * - 'php_ready_args' (bool): If false, the arguments will not be formatted for PHP. (no $ before the names).
21 19 *
22 - * @param int $id The snippet ID.
23 - * @param array $options Options for filtering.
20 + * @param $id
21 + * @param array $options
24 22 *
25 - * @return array|null The snippet data or null if not found.
26 - * @throws Exception If the snippet cannot be retrieved.
23 + * @return mixed
27 24 */
28 - public function getSnippet( $id, $options = [] ) {
29 - try {
30 - if ( empty( $id ) ) {
31 - throw new Exception( 'The snippet ID is required.' );
32 - }
33 -
34 - if ( $this->debug ) {
35 - $this->core->log( sprintf( 'API [GetSnippet]: ID=%d, Options=%s', $id, json_encode( $options ) ) );
36 - }
37 -
38 - // Try to get as function snippet first (for backward compatibility)
39 - $snippet = $this->snippet_module->get_function( $id, $options );
40 -
41 - // If not found as function, get from general snippets
42 - if ( empty( $snippet ) ) {
43 - $snippet = $this->snippet_module->select_one( $id, $options );
44 - if ( empty( $snippet ) ) {
45 - throw new Exception( sprintf( 'Snippet with ID %d not found.', $id ) );
46 - }
47 - }
48 -
49 - return $snippet;
50 - }
51 - catch ( Exception $e ) {
52 - if ( $this->debug ) {
53 - $this->core->log( '⚠️ API Error [GetSnippet]: ' . $e->getMessage() );
54 - }
55 - throw $e;
56 - }
25 + public function get_function( $id, $options = [] ) {
26 + $snippet = $this->snippet->get_function( $id, $options );
27 + return $snippet;
57 28 }
58 29
30 +
59 31 /**
60 - * Get a snippet by its name.
32 + * Get a function by its name.
61 33 *
62 - * The options are used to filter the snippets:
34 + * The options are used to filter the functions:
63 35 * - 'php_ready_args' (bool): If false, the arguments will not be formatted for PHP. (no $ before the names).
64 36 *
65 - * @param string $name The name of the snippet to be retrieved.
66 - * @param array $options Options for filtering.
37 + * @param $name The name of the function to be retrieved.
38 + * @param array $options
67 39 *
68 - * @return array|null The snippet data or null if not found.
69 - * @throws Exception If the snippet cannot be retrieved.
40 + * @return mixed
70 41 */
71 - public function getSnippetByName( $name, $options = [] ) {
72 - try {
73 - if ( empty( $name ) ) {
74 - throw new Exception( 'The snippet name is required.' );
75 - }
76 -
77 - if ( $this->debug ) {
78 - $this->core->log( sprintf( 'API [GetSnippetByName]: Name=%s, Options=%s', $name, json_encode( $options ) ) );
79 - }
80 -
81 - $snippet = $this->snippet_module->get_function_by_name( $name, $options );
82 - if ( empty( $snippet ) ) {
83 - throw new Exception( sprintf( 'Snippet with name "%s" not found.', $name ) );
84 - }
85 -
86 - return $snippet;
87 - }
88 - catch ( Exception $e ) {
89 - if ( $this->debug ) {
90 - $this->core->log( '⚠️ API Error [GetSnippetByName]: ' . $e->getMessage() );
91 - }
92 - throw $e;
93 - }
42 + public function get_function_by_name( $name, $options = [] ) {
43 + $snippet = $this->snippet->get_function_by_name( $name, $options );
44 + return $snippet;
94 45 }
95 46
96 47 /**
97 - * Get all snippets.
48 + * Get all functions.
98 49 *
99 - * @param bool $safe Whether to filter out snippets with invalid names.
100 - * @param string|null $scope Optional scope filter: 'function', 'backend', 'frontend', 'scheduled', 'persistent'.
101 - * @return array The list of snippets.
102 - */
103 - public function getSnippets( $safe = true, $scope = null ) {
104 - try {
105 - // Don't log here to avoid infinite loops during initialization
106 -
107 - // If scope is specified, use getSnippetsByScope
108 - if ( $scope ) {
109 - $snippets = $this->getSnippetsByScope( $scope );
110 - } else {
111 - // Get all snippets from the database
112 - $allSnippets = $this->snippet_module->select( 0, 9999, [], [] );
113 - $snippets = $allSnippets['data'] ?? [];
114 - }
115 -
116 - if ( $safe ) {
117 - $snippets = array_filter( $snippets, function( $snippet ) {
118 - $name = $snippet['name'];
119 - if ( !preg_match( '/^[a-zA-Z0-9_-]{1,64}$/', $name ) ) {
120 - if ( $this->debug ) {
121 - $this->core->log( sprintf( 'API [GetSnippets]: Filtered out snippet with invalid name: %s', $name ) );
122 - }
123 - return false;
124 - }
125 - return true;
126 - } );
127 - }
128 -
129 - return array_values( $snippets ); // Reset array keys
130 - }
131 - catch ( Exception $e ) {
132 - if ( $this->debug ) {
133 - $this->core->log( '⚠️ API Error [GetSnippets]: ' . $e->getMessage() );
134 - }
135 - throw $e;
136 - }
137 - }
138 -
139 - /**
140 - * Backward compatibility wrapper for getSnippets().
141 - * @deprecated Use getSnippets() instead.
50 + * @return mixed
142 51 *
143 - * @param bool $safe Whether to filter out snippets with invalid names.
144 - * @return array The list of function snippets only.
145 52 */
146 53 public function get_functions( $safe = true ) {
147 - error_log( 'Code Engine API: get_functions() is deprecated. Please use getSnippets() instead.' );
148 - // Return only function snippets for backward compatibility
149 - return $this->getSnippets( $safe, 'function' );
150 - }
54 + $snippets = $this->snippet->get_functions();
151 55
152 - /**
153 - * Execute a snippet by its ID.
154 - * The arguments should be an associative array with the argument names as keys.
155 - * Example: [ "$city" => "'Tokyo'", "$date" => "1999" ]
156 - *
157 - * @param int $id The snippet ID.
158 - * @param array $args The arguments to pass to the snippet.
159 - *
160 - * @return mixed The result of the snippet execution.
161 - * @throws Exception If the snippet cannot be executed.
162 - */
163 - public function executeSnippet( $id, $args = [] ) {
164 - try {
165 - if ( empty( $id ) ) {
166 - throw new Exception( 'The snippet ID is required.' );
167 - }
56 + if ( $safe ) {
57 +
58 + $snippets = array_filter( $snippets, function( $snippet ) {
59 + $name = $snippet['name'];
60 + if ( !preg_match( '/^[a-zA-Z0-9_-]{1,64}$/', $name ) ) {
61 + return false;
62 + }
63 +
64 + return true;
65 + } );
168 66
169 - if ( $this->debug ) {
170 - $this->core->log( sprintf( 'API [ExecuteSnippet]: ID=%d, Args=%s', $id, json_encode( $args ) ) );
171 - }
172 -
173 - // Verify the snippet exists
174 - $snippet = $this->snippet_module->get_function( $id );
175 - if ( empty( $snippet ) ) {
176 - throw new Exception( sprintf( 'Snippet with ID %d not found.', $id ) );
177 - }
178 -
179 - $output = $this->core->run_snippet( $id, $args );
180 -
181 - if ( $this->debug ) {
182 - $shortOutput = is_string( $output ) ? substr( $output, 0, 100 ) : json_encode( $output );
183 - $this->core->log( sprintf( 'API [ExecuteSnippet]: Success, Output=%s%s',
184 - $shortOutput,
185 - strlen( $shortOutput ) > 100 ? '...' : ''
186 - ) );
187 - }
188 -
189 - return $output;
190 67 }
191 - catch ( Exception $e ) {
192 - if ( $this->debug ) {
193 - $this->core->log( '⚠️ API Error [ExecuteSnippet]: ' . $e->getMessage() );
194 - }
195 - throw $e;
196 - }
68 +
69 + return $snippets;
197 70 }
198 71
72 +
199 73 /**
200 - * Execute a snippet by its name.
74 + * Execute a function by its ID.
75 + * The arguments should be an associative array with the argument names as keys.
76 + * Example: [ "$city" => " 'Tokyo' ", "$date" => "1999" ]
201 77 *
202 - * @param string $name The snippet name.
203 - * @param array $args The arguments to pass to the snippet.
78 + * @param $id
79 + * @param $args
204 80 *
205 - * @return mixed The result of the snippet execution.
206 - * @throws Exception If the snippet cannot be executed.
81 + * @return mixed
207 82 */
208 - public function executeSnippetByName( $name, $args = [] ) {
209 - try {
210 - if ( empty( $name ) ) {
211 - throw new Exception( 'The snippet name is required.' );
212 - }
213 -
214 - if ( $this->debug ) {
215 - $this->core->log( sprintf( 'API [ExecuteSnippetByName]: Name=%s, Args=%s', $name, json_encode( $args ) ) );
216 - }
217 -
218 - // Get the snippet by name to find its ID
219 - $snippet = $this->snippet_module->get_function_by_name( $name );
220 - if ( empty( $snippet ) || empty( $snippet['snippetId'] ) ) {
221 - throw new Exception( sprintf( 'Snippet with name "%s" not found.', $name ) );
222 - }
223 -
224 - return $this->executeSnippet( $snippet['snippetId'], $args );
225 - }
226 - catch ( Exception $e ) {
227 - if ( $this->debug ) {
228 - $this->core->log( '⚠️ API Error [ExecuteSnippetByName]: ' . $e->getMessage() );
229 - }
230 - throw $e;
231 - }
83 + public function execute_function( $id, $args ) {
84 + $output = $this->core->run_snippet( $id, $args );
85 + return $output;
232 86 }
233 - #endregion
234 -
235 - #region Standard API
236 -
87 +
88 +
237 89 /**
238 - * Create a new snippet.
90 + * Create a new callable snippet ( Function ).
239 91 *
240 - * @param string $name Name of the snippet.
241 - * @param string $code Code of the snippet.
242 - * @param string $scope Scope of the snippet: 'function', 'backend', 'frontend', 'scheduled', 'persistent'.
243 - * @param array $options Additional options:
244 - * - target: 'php' or 'js' (for function snippets)
245 - * - description: Description of the snippet
246 - * - args: Arguments for function snippets
247 - * - argsData: Argument data for function snippets (use 'description' for each argument's description)
248 - * - behavior: 'dynamic' or 'static' (for function snippets)
249 - * - tags: Array of tags
250 - * - priority: Execution priority
251 - * - active: Active status (true/false)
252 - * - endpoint: REST endpoint
253 - * - method: HTTP method (GET/POST)
254 - * - intervalHours: Hours for scheduled snippets
255 - * - intervalMinutes: Minutes for scheduled snippets
92 + * @param string $name Name of the function. This should be the name of the function declaration, like 'get_weather'.
93 + * @param string $target Target of the snippet. This should be either 'php' or 'js'. This will be used to determine the type of the function.
94 + * @param string $code Code of the snippet. This should be either a PHP or a JS function. No code outside of the function itself should be included.
95 + * @param string $description Description of the snippet. This will be displayed in Code Engine and used for Function Calling.
96 + * @param array $args Arguments of the function. This array should have the full name of each argument, like ['$city', '$date']. The '$' is required if the function is PHP.
97 + * @param array $args_data Data of the arguments. This array should have the name of each argument as key and an array with the type, description and default value. Example: [ '$city' => ['type' => 'string', 'desc' => 'City name', 'default' => 'Tokyo' ] ]. This will be used for Function Calling.
98 + * @param string $behavior Behavior of the function. This should be either 'dynamic' or 'static'. This will be used for Function Calling.
256 99 *
257 - * @return array The created snippet data.
258 - * @throws Exception If the snippet cannot be created.
259 100 */
260 - public function createSnippet( $name, $code, $scope = 'function', $options = [] ) {
101 + public function create_function( $name, $target, $code, $description, $args, $args_data, $behavior ) {
261 102
262 - try {
263 - if ( empty( $name ) ) {
264 - throw new Exception( 'The snippet name is required.' );
265 - }
266 -
267 - if ( empty( $code ) ) {
268 - throw new Exception( 'The snippet code is required.' );
269 - }
270 -
271 - $validScopes = ['function', 'backend', 'frontend', 'scheduled', 'persistent'];
272 - if ( !in_array( $scope, $validScopes ) ) {
273 - throw new Exception( sprintf( 'Invalid scope. Must be one of: %s', implode( ', ', $validScopes ) ) );
274 - }
275 -
276 - // Extract options with defaults
277 - $target = $options['target'] ?? 'php';
278 - $description = $options['description'] ?? '';
279 - $args = $options['args'] ?? [];
280 - $argsData = $options['argsData'] ?? [];
281 - $behavior = $options['behavior'] ?? 'dynamic';
282 - $tags = $options['tags'] ?? ['api'];
283 - $priority = $options['priority'] ?? 10;
284 - $active = $options['active'] ?? true;
285 - $endpoint = $options['endpoint'] ?? '';
286 - $method = $options['method'] ?? 'POST';
287 - $intervalHours = $options['intervalHours'] ?? 0;
288 - $intervalMinutes = $options['intervalMinutes'] ?? 0;
289 -
290 - // Validate function-specific options
291 - if ( $scope === 'function' ) {
292 - if ( !in_array( $target, ['php', 'js'] ) ) {
293 - throw new Exception( 'The target must be either "php" or "js" for function snippets.' );
294 - }
295 - if ( !in_array( $behavior, ['dynamic', 'static'] ) ) {
296 - throw new Exception( 'The behavior must be either "dynamic" or "static" for function snippets.' );
297 - }
298 - }
299 -
300 - if ( $this->debug ) {
301 - $shortCode = substr( $code, 0, 100 );
302 - $this->core->log( sprintf( 'API [CreateSnippet]: Name=%s, Scope=%s, Options=%s',
303 - $name, $scope, json_encode( $options ) ) );
304 - }
305 -
306 - $params = [
307 - // Core values
308 - 'id' => null,
309 - 'name' => $name,
310 - 'code' => $code,
311 - 'scope' => $scope,
312 - 'active' => $active ? 1 : 0,
313 - 'priority' => $priority,
314 - 'tags' => $tags,
315 - 'description' => $description,
316 - 'endpoint' => $endpoint,
317 - 'method' => $method,
318 - ];
319 -
320 - // Add function-specific params
321 - if ( $scope === 'function' ) {
322 - $params['functionName'] = $name;
323 - $params['functionTarget'] = $target;
324 - $params['functionArgs'] = $args;
325 - $params['functionArgsDict'] = $argsData;
326 - $params['functionBehavior'] = $behavior;
327 - }
328 -
329 - // Add scheduled-specific params
330 - if ( $scope === 'scheduled' ) {
331 - $params['intervalHours'] = $intervalHours;
332 - $params['intervalMinutes'] = $intervalMinutes;
333 - }
334 -
335 - $result = $this->core->add_snippet( $params );
336 -
337 - if ( $this->debug ) {
338 - $this->core->log( sprintf( 'API [CreateSnippet]: Success, ID=%d', $result['id'] ?? 0 ) );
339 - }
340 -
341 - return $result;
342 - }
343 - catch ( Exception $e ) {
344 - if ( $this->debug ) {
345 - $this->core->log( '⚠️ API Error [CreateSnippet]: ' . $e->getMessage() );
346 - }
347 - throw $e;
348 - }
103 + $temp_name = 'mwcode_' . time();
104 +
105 + $params = [
106 + // Predefined values
107 + 'id' => null,
108 + 'active' => 1,
109 + 'priority' => 10,
110 + 'tags' => ['api'],
111 + 'endpoint' => '',
112 + 'scope' => 'function',
113 +
114 + // Custom values
115 + 'name' => $name ?? $temp_name,
116 + 'code' => $code ?? "function $temp_name() { return 'Hello World'; }",
117 + 'description' => $description ?? '',
118 +
119 + 'functionName' => $name ?? $temp_name,
120 + 'functionTarget' => $target ?? 'php',
121 + 'functionArgs' => $args ?? [],
122 + 'functionArgsDict' => $args_data ?? [],
123 + 'functionBehavior' => $behavior ?? 'dynamic',
124 + ];
125 +
126 + $res = $this->core->add_snippet( $params );
127 +
128 + return $res;
349 129 }
130 +
350 131
351 132 /**
352 - * Update a snippet by its ID.
353 - * All parameters except ID are optional. If not specified, the current values will be used.
133 + * Update a function by its name. If the function does not exist, it will return false. The parameters are the same as create_function, but except the name the rest are optional. If not specified, the current values will be used.
354 134 *
355 - * @param int $id ID of the snippet to update.
356 - * @param array $params Parameters to update. Can include:
357 - * - name: Snippet name
358 - * - code: Snippet code
359 - * - scope: Snippet scope
360 - * - description: Description
361 - * - active: Active status
362 - * - priority: Execution priority
363 - * - tags: Array of tags
364 - * - endpoint: REST endpoint
365 - * - method: HTTP method
366 - * - target: 'php' or 'js' (for function snippets)
367 - * - args: Arguments (for function snippets)
368 - * - argsData: Argument data (for function snippets)
369 - * - behavior: 'dynamic' or 'static' (for function snippets)
370 - * - intervalHours: Hours (for scheduled snippets)
371 - * - intervalMinutes: Minutes (for scheduled snippets)
372 - *
373 - * @return array The updated snippet data.
374 - * @throws Exception If the snippet cannot be updated.
135 + * @param string $name Name of the function. This should be the name of the function declaration, like 'get_weather'.
136 + * @param string $target Target of the snippet. This should be either 'php' or 'js'. This will be used to determine the type of the function.
137 + * @param string $code Code of the snippet. This should be either a PHP or a JS function. No code outside of the function itself should be included.
138 + * @param string $description Description of the snippet. This will be displayed in Code Engine and used for Function Calling.
139 + * @param array $args Arguments of the function. This array should have the full name of each argument, like ['$city', '$date']. The '$' is required if the function is PHP.
140 + * @param array $args_data Data of the arguments. This array should have the name of each argument as key and an array with the type, description and default value. Example: [ '$city' => ['type' => 'string', 'desc' => 'City name', 'default' => 'Tokyo' ] ]. This will be used for Function Calling.
141 + * @param string $behavior Behavior of the function. This should be either 'dynamic' or 'static'. This will be used for Function Calling.
375 142 */
376 - public function updateSnippet( $id, $params = [] ) {
377 - try {
378 - if ( empty( $id ) ) {
379 - throw new Exception( 'The snippet ID is required.' );
380 - }
381 -
382 - if ( $this->debug ) {
383 - $this->core->log( sprintf( 'API [UpdateSnippet]: ID=%d, Params=%s', $id, json_encode( $params ) ) );
384 - }
385 -
386 - // Get existing snippet
387 - $snippet = $this->snippet_module->select_one( $id );
388 - if ( empty( $snippet ) ) {
389 - throw new Exception( sprintf( 'Snippet with ID %d not found.', $id ) );
390 - }
391 -
392 - // Validate scope if provided
393 - if ( isset( $params['scope'] ) ) {
394 - $validScopes = ['function', 'backend', 'frontend', 'scheduled', 'persistent'];
395 - if ( !in_array( $params['scope'], $validScopes ) ) {
396 - throw new Exception( sprintf( 'Invalid scope. Must be one of: %s', implode( ', ', $validScopes ) ) );
397 - }
398 - }
399 -
400 - // Validate function-specific parameters if provided
401 - $scope = $params['scope'] ?? $snippet['scope'];
402 - if ( $scope === 'function' ) {
403 - if ( isset( $params['target'] ) && !in_array( $params['target'], ['php', 'js'] ) ) {
404 - throw new Exception( 'The target must be either "php" or "js" for function snippets.' );
405 - }
406 - if ( isset( $params['behavior'] ) && !in_array( $params['behavior'], ['dynamic', 'static'] ) ) {
407 - throw new Exception( 'The behavior must be either "dynamic" or "static" for function snippets.' );
408 - }
409 - }
410 -
411 - // Build update params - merge with existing values
412 - $updateParams = [
413 - 'id' => $id,
414 - 'name' => $params['name'] ?? $snippet['name'],
415 - 'code' => $params['code'] ?? $snippet['code'],
416 - 'scope' => $scope,
417 - 'active' => isset( $params['active'] ) ? ( $params['active'] ? 1 : 0 ) : $snippet['active'],
418 - 'priority' => $params['priority'] ?? $snippet['priority'],
419 - 'tags' => $params['tags'] ?? $snippet['tags'],
420 - 'description' => $params['description'] ?? $snippet['description'] ?? '',
421 - 'endpoint' => $params['endpoint'] ?? $snippet['endpoint'] ?? '',
422 - 'method' => $params['method'] ?? $snippet['method'] ?? 'POST',
423 - ];
424 -
425 - // Add function-specific params if it's a function snippet
426 - if ( $scope === 'function' ) {
427 - $updateParams['functionName'] = $params['name'] ?? $snippet['name'];
428 - $updateParams['functionTarget'] = $params['target'] ?? $snippet['functionTarget'] ?? 'php';
429 - $updateParams['functionArgs'] = $params['args'] ?? $snippet['functionArgs'] ?? [];
430 - $updateParams['functionArgsDict'] = $params['argsData'] ?? $snippet['functionArgsDict'] ?? [];
431 - $updateParams['functionBehavior'] = $params['behavior'] ?? $snippet['functionBehavior'] ?? 'dynamic';
432 - }
433 -
434 - // Add scheduled-specific params if it's a scheduled snippet
435 - if ( $scope === 'scheduled' ) {
436 - $updateParams['intervalHours'] = $params['intervalHours'] ?? $snippet['intervalHours'] ?? 0;
437 - $updateParams['intervalMinutes'] = $params['intervalMinutes'] ?? $snippet['intervalMinutes'] ?? 0;
438 - }
439 -
440 - $result = $this->core->add_snippet( $updateParams );
441 -
442 - if ( $this->debug ) {
443 - $this->core->log( sprintf( 'API [UpdateSnippet]: Success, ID=%d', $result['id'] ?? $id ) );
444 - }
445 -
446 - return $result;
447 - }
448 - catch ( Exception $e ) {
449 - if ( $this->debug ) {
450 - $this->core->log( '⚠️ API Error [UpdateSnippet]: ' . $e->getMessage() );
451 - }
452 - throw $e;
453 - }
143 + public function update_function( $name, $target, $code, $description, $args, $args_data, $behavior ) {
144 + $snippet = $this->snippet->get_function_by_name( $name );
145 + if ( !$snippet ) { return false; }
146 +
147 + $params = [
148 + // Predefined values
149 + 'id' => $snippet['snippetId'],
150 + 'active' => 1,
151 + 'priority' => 10,
152 + 'tags' => ['api'],
153 + 'endpoint' => '',
154 + 'scope' => 'function',
155 +
156 + // Custom values
157 + 'name' => $name ?? $snippet['name'],
158 + 'code' => $code ?? $snippet['code'],
159 + 'description' => $description ?? '',
160 +
161 + 'functionName' => $name ?? $snippet['functionName'],
162 + 'functionTarget' => $target ?? $snippet['functionTarget'],
163 + 'functionArgs' => $args ?? $snippet['functionArgs'],
164 + 'functionArgsDict' => $args_data ?? $snippet['functionArgsDict'],
165 + 'functionBehavior' => $behavior ?? $snippet['functionBehavior'],
166 + ];
167 +
168 +
169 + $res = $this->core->add_snippet( $params );
170 +
171 + return $res;
454 172 }
455 173
456 174 /**
457 - * Delete a snippet by its ID.
175 + * Delete a function by its ID.
458 176 *
459 - * @param int $id Snippet ID.
460 - * @return bool True if the snippet was deleted successfully.
461 - * @throws Exception If the snippet cannot be deleted.
177 + * @param int $id Function ID
178 + * @return mixed
462 179 */
463 - public function deleteSnippet( $id ) {
464 - try {
465 - if ( empty( $id ) ) {
466 - throw new Exception( 'The snippet ID is required.' );
467 - }
468 -
469 - if ( $this->debug ) {
470 - $this->core->log( sprintf( 'API [DeleteSnippet]: ID=%d', $id ) );
471 - }
472 -
473 - // Verify the snippet exists
474 - $snippet = $this->snippet_module->select_one( $id );
475 - if ( empty( $snippet ) ) {
476 - throw new Exception( sprintf( 'Snippet with ID %d not found.', $id ) );
477 - }
478 -
479 - $params = [ 'id' => $id ];
480 -
481 - // Delete function snippet data if it's a function
482 - if ( $snippet['scope'] === 'function' ) {
483 - $this->snippet_module->delete_function_snippet( $params );
484 - }
485 -
486 - // Delete scheduled snippet data if it's scheduled
487 - if ( $snippet['scope'] === 'scheduled' ) {
488 - $this->snippet_module->delete_interval_snippet( $params );
489 - }
490 -
491 - $result = $this->snippet_module->delete( $params );
492 -
493 - if ( $this->debug ) {
494 - $this->core->log( sprintf( 'API [DeleteSnippet]: Success, ID=%d', $id ) );
495 - }
496 -
497 - return !empty( $result );
498 - }
499 - catch ( Exception $e ) {
500 - if ( $this->debug ) {
501 - $this->core->log( '⚠️ API Error [DeleteSnippet]: ' . $e->getMessage() );
502 - }
503 - throw $e;
504 - }
180 + public function delete_function( $id ) {
181 + $params = [
182 + 'id' => $id,
183 + ];
184 +
185 + $this->snippet->delete_function_snippet( $params );
186 + $result = $this->snippet->delete( $params );
187 +
188 + return $result;
505 189 }
506 190
507 191 /**
508 - * Delete a snippet by its name.
192 + * Delete a function by its name.
509 193 *
510 - * @param string $name Snippet name.
511 - * @return bool True if the snippet was deleted successfully.
512 - * @throws Exception If the snippet cannot be deleted.
194 + * @param string $name Function name
195 + * @return mixed
513 196 */
514 - public function deleteSnippetByName( $name ) {
515 - try {
516 - if ( empty( $name ) ) {
517 - throw new Exception( 'The snippet name is required.' );
518 - }
519 -
520 - if ( $this->debug ) {
521 - $this->core->log( sprintf( 'API [DeleteSnippetByName]: Name=%s', $name ) );
522 - }
523 -
524 - // Try to find as function first
525 - $snippet = $this->snippet_module->get_function_by_name( $name );
526 - if ( !empty( $snippet ) && !empty( $snippet['snippetId'] ) ) {
527 - return $this->deleteSnippet( $snippet['snippetId'] );
528 - }
529 -
530 - // If not found as function, search in all snippets
531 - $allSnippets = $this->snippet_module->select( 0, 9999, [], [] );
532 - foreach ( $allSnippets['data'] as $s ) {
533 - if ( $s['name'] === $name ) {
534 - return $this->deleteSnippet( $s['id'] );
535 - }
536 - }
537 -
538 - throw new Exception( sprintf( 'Snippet with name "%s" not found.', $name ) );
539 - }
540 - catch ( Exception $e ) {
541 - if ( $this->debug ) {
542 - $this->core->log( '⚠️ API Error [DeleteSnippetByName]: ' . $e->getMessage() );
543 - }
544 - throw $e;
545 - }
197 + public function delete_function_by_name( $name ) {
198 + $snippet = $this->snippet->get_function_by_name( $name );
199 + if ( !$snippet ) { return false; }
200 +
201 + $params = [
202 + 'id' => $snippet['snippetId'],
203 + ];
204 +
205 + $this->snippet->delete_function_snippet( $params );
206 + $result = $this->snippet->delete( $params );
207 +
208 + return $result;
546 209 }
547 - #endregion
548 -
549 - #region Standard API (No REST API)
550 -
551 - /**
552 - * Check if a snippet exists by ID.
553 - *
554 - * @param int $id The snippet ID.
555 - * @return bool True if the snippet exists.
556 - */
557 - public function snippetExists( $id ) {
558 - try {
559 - if ( empty( $id ) ) {
560 - return false;
561 - }
562 -
563 - $snippet = $this->snippet_module->select_one( $id );
564 - return !empty( $snippet );
565 - }
566 - catch ( Exception $e ) {
567 - if ( $this->debug ) {
568 - $this->core->log( '⚠️ API Error [SnippetExists]: ' . $e->getMessage() );
569 - }
570 - return false;
571 - }
572 - }
573 -
574 - /**
575 - * Check if a snippet exists by name.
576 - *
577 - * @param string $name The snippet name.
578 - * @return bool True if the snippet exists.
579 - */
580 - public function snippetExistsByName( $name ) {
581 - try {
582 - if ( empty( $name ) ) {
583 - return false;
584 - }
585 -
586 - // Check in functions first
587 - $snippet = $this->snippet_module->get_function_by_name( $name );
588 - if ( !empty( $snippet ) ) {
589 - return true;
590 - }
591 -
592 - // Check in all snippets
593 - $allSnippets = $this->snippet_module->select( 0, 9999, [], [] );
594 - foreach ( $allSnippets['data'] as $s ) {
595 - if ( $s['name'] === $name ) {
596 - return true;
597 - }
598 - }
599 -
600 - return false;
601 - }
602 - catch ( Exception $e ) {
603 - if ( $this->debug ) {
604 - $this->core->log( '⚠️ API Error [SnippetExistsByName]: ' . $e->getMessage() );
605 - }
606 - return false;
607 - }
608 - }
609 -
610 - /**
611 - * Validates snippet code syntax.
612 - *
613 - * @param string $code The snippet code to validate.
614 - * @param string $target The target language ('php' or 'js').
615 - * @return array ['valid' => bool, 'error' => string|null]
616 - */
617 - public function validateSnippetCode( $code, $target = 'php' ) {
618 - try {
619 - if ( empty( $code ) ) {
620 - return [ 'valid' => false, 'error' => 'Code is empty.' ];
621 - }
622 -
623 - if ( !in_array( $target, ['php', 'js'] ) ) {
624 - return [ 'valid' => false, 'error' => 'Invalid target language.' ];
625 - }
626 -
627 - if ( $target === 'php' ) {
628 - // Use the core's validate_php_code method if available
629 - if ( method_exists( $this->core, 'validate_php_code' ) ) {
630 - $validation = $this->core->validate_php_code( $code );
631 - return [
632 - 'valid' => $validation['valid'] ?? false,
633 - 'error' => $validation['error'] ?? null
634 - ];
635 - }
636 - }
637 -
638 - // Basic validation if no specific validator available
639 - return [ 'valid' => true, 'error' => null ];
640 - }
641 - catch ( Exception $e ) {
642 - return [ 'valid' => false, 'error' => $e->getMessage() ];
643 - }
644 - }
645 - #endregion
646 -
647 - #region Snippet Management
648 -
649 - /**
650 - * Activate a snippet by its ID.
651 - *
652 - * @param int $id The snippet ID.
653 - * @return bool True if activated successfully.
654 - * @throws Exception If the snippet cannot be activated.
655 - */
656 - public function activateSnippet( $id ) {
657 - try {
658 - if ( empty( $id ) ) {
659 - throw new Exception( 'The snippet ID is required.' );
660 - }
661 -
662 - if ( $this->debug ) {
663 - $this->core->log( sprintf( 'API [ActivateSnippet]: ID=%d', $id ) );
664 - }
665 -
666 - // Get the snippet
667 - $snippet = $this->snippet_module->select_one( $id );
668 - if ( empty( $snippet ) ) {
669 - throw new Exception( sprintf( 'Snippet with ID %d not found.', $id ) );
670 - }
671 -
672 - // Update only the active status
673 - $result = $this->updateSnippet( $id, [ 'active' => true ] );
674 - return !empty( $result );
675 - }
676 - catch ( Exception $e ) {
677 - if ( $this->debug ) {
678 - $this->core->log( '⚠️ API Error [ActivateSnippet]: ' . $e->getMessage() );
679 - }
680 - throw $e;
681 - }
682 - }
683 -
684 - /**
685 - * Deactivate a snippet by its ID.
686 - *
687 - * @param int $id The snippet ID.
688 - * @return bool True if deactivated successfully.
689 - * @throws Exception If the snippet cannot be deactivated.
690 - */
691 - public function deactivateSnippet( $id ) {
692 - try {
693 - if ( empty( $id ) ) {
694 - throw new Exception( 'The snippet ID is required.' );
695 - }
696 -
697 - if ( $this->debug ) {
698 - $this->core->log( sprintf( 'API [DeactivateSnippet]: ID=%d', $id ) );
699 - }
700 -
701 - // Get the snippet
702 - $snippet = $this->snippet_module->select_one( $id );
703 - if ( empty( $snippet ) ) {
704 - throw new Exception( sprintf( 'Snippet with ID %d not found.', $id ) );
705 - }
706 -
707 - // Update only the active status
708 - $result = $this->updateSnippet( $id, [ 'active' => false ] );
709 - return !empty( $result );
710 - }
711 - catch ( Exception $e ) {
712 - if ( $this->debug ) {
713 - $this->core->log( '⚠️ API Error [DeactivateSnippet]: ' . $e->getMessage() );
714 - }
715 - throw $e;
716 - }
717 - }
718 -
719 - /**
720 - * Get snippets by scope.
721 - *
722 - * @param string $scope The scope to filter by: 'backend', 'frontend', 'function', 'scheduled', 'persistent'.
723 - * @param array $filters Additional filters: 'active' (bool), 'tags' (array).
724 - * @return array The list of snippets matching the criteria.
725 - * @throws Exception If the scope is invalid.
726 - */
727 - public function getSnippetsByScope( $scope, $filters = [] ) {
728 - try {
729 - $validScopes = ['function', 'backend', 'frontend', 'scheduled', 'persistent'];
730 - if ( !in_array( $scope, $validScopes ) ) {
731 - throw new Exception( sprintf( 'Invalid scope. Must be one of: %s', implode( ', ', $validScopes ) ) );
732 - }
733 -
734 - if ( $this->debug ) {
735 - $this->core->log( sprintf( 'API [GetSnippetsByScope]: Scope=%s, Filters=%s', $scope, json_encode( $filters ) ) );
736 - }
737 -
738 - // For function scope, we can use the existing get_functions method
739 - if ( $scope === 'function' && empty( $filters ) ) {
740 - return $this->snippet_module->get_functions();
741 - }
742 -
743 - // For other scopes or with filters, we need to query all snippets
744 - $allSnippets = $this->snippet_module->select( 0, 9999, [], [] );
745 - $filtered = [];
746 -
747 - foreach ( $allSnippets['data'] as $snippet ) {
748 - // Filter by scope
749 - if ( $snippet['scope'] !== $scope ) {
750 - continue;
751 - }
752 -
753 - // Apply additional filters
754 - if ( isset( $filters['active'] ) && $snippet['active'] != $filters['active'] ) {
755 - continue;
756 - }
757 -
758 - if ( isset( $filters['tags'] ) && is_array( $filters['tags'] ) ) {
759 - $snippetTags = is_array( $snippet['tags'] ) ? $snippet['tags'] : [];
760 - $hasAllTags = true;
761 - foreach ( $filters['tags'] as $tag ) {
762 - if ( !in_array( $tag, $snippetTags ) ) {
763 - $hasAllTags = false;
764 - break;
765 - }
766 - }
767 - if ( !$hasAllTags ) {
768 - continue;
769 - }
770 - }
771 -
772 - $filtered[] = $snippet;
773 - }
774 -
775 - return $filtered;
776 - }
777 - catch ( Exception $e ) {
778 - if ( $this->debug ) {
779 - $this->core->log( '⚠️ API Error [GetSnippetsByScope]: ' . $e->getMessage() );
780 - }
781 - throw $e;
782 - }
783 - }
784 -
785 - /**
786 - * Get all active snippets.
787 - *
788 - * @param string|null $scope Optional scope filter.
789 - * @return array The list of active snippets.
790 - */
791 - public function getActiveSnippets( $scope = null ) {
792 - try {
793 - if ( $this->debug ) {
794 - $this->core->log( sprintf( 'API [GetActiveSnippets]: Scope=%s', $scope ?? 'all' ) );
795 - }
796 -
797 - if ( $scope ) {
798 - return $this->getSnippetsByScope( $scope, [ 'active' => true ] );
799 - }
800 -
801 - // Get all active snippets
802 - $allSnippets = $this->snippet_module->select( 0, 9999, [], [] );
803 - $active = [];
804 -
805 - foreach ( $allSnippets['data'] as $snippet ) {
806 - if ( $snippet['active'] ) {
807 - $active[] = $snippet;
808 - }
809 - }
810 -
811 - return $active;
812 - }
813 - catch ( Exception $e ) {
814 - if ( $this->debug ) {
815 - $this->core->log( '⚠️ API Error [GetActiveSnippets]: ' . $e->getMessage() );
816 - }
817 - throw $e;
818 - }
819 - }
820 - #endregion
210 +
821 211 }