PluginProbe
WDesignKit – AI Templates, Widget Builder & MCP Workflow / 2.7.0
WDesignKit – AI Templates, Widget Builder & MCP Workflow v2.7.0
2.7.1 2.7.0 2.6.6 2.6.5 2.6.4 2.6.3 2.6.2 2.6.1 2.6.0 2.5.5 2.5.4 2.5.3 2.5.2 2.5.1 2.5.0 2.4.0 2.3.3 2.3.2 2.3.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 All 130 releases
wdesignkit / includes / abilities / widgets / wdesignkit-check-widget-versions.php

wdesignkit-check-widget-versions.php in WDesignKit – AI Templates, Widget Builder & MCP Workflow 2.7.0, at includes/abilities/widgets/wdesignkit-check-widget-versions.php

142 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Ability: Check cloud version info for locally installed WDesignKit widgets.
4 */
5
6 declare(strict_types=1);
7
8 if (!defined('ABSPATH')) {
9 exit();
10 }
11
12 wp_register_ability('wdesignkit/check-widget-versions', [
13 'label' => __('Check WDesignKit Widget Versions', 'wdesignkit'),
14 'description' => __(
15 'Queries the WDesignKit cloud for version information on one or more widgets identified by their marketplace record IDs (r_id). Returns the latest available version per widget so callers can detect which locally installed widgets are out of date.',
16 'wdesignkit',
17 ),
18 'category' => 'wdesignkit',
19 'input_schema' => [
20 'type' => 'object',
21 'properties' => [
22 'r_ids' => [
23 'type' => 'string',
24 'description' => 'Comma-separated list of marketplace record IDs (r_id values). Get these from the widget JSON config under widget_data.widgetdata.r_id or from wdesignkit/list-widgets.',
25 ],
26 'check_all_local' => [
27 'type' => 'boolean',
28 'description' => 'When true, scans every local widget across all builders, collects their r_id values, and checks versions for all at once. Overrides r_ids. Skips widgets that have no r_id (i.e. never pushed to cloud).',
29 ],
30 ],
31 'additionalProperties' => false,
32 ],
33 'output_schema' => [
34 'type' => 'object',
35 'properties' => [
36 'success' => ['type' => 'boolean'],
37 'message' => ['type' => 'string'],
38 'versions' => ['type' => ['object', 'array']],
39 ],
40 ],
41 'execute_callback' => 'wdesignkit_mcp_check_widget_versions',
42 'permission_callback' => 'wdesignkit_mcp_permission_callback',
43 'meta' => [
44 'public' => true,
45 'show_in_rest' => true,
46 'mcp' => ['public' => true],
47 'annotations' => [
48 'instructions' => implode("\n", [
49 'Checks cloud version info for installed widgets.',
50 'Requires WDesignKit cloud login.',
51 'r_id is the marketplace record ID stored in the widget JSON config.',
52 'Use check_all_local: true to scan every installed widget automatically.',
53 'Widgets that were never pushed to the marketplace have no r_id and are skipped.',
54 ]),
55 'readonly' => true,
56 'destructive' => false,
57 'idempotent' => true,
58 ],
59 ],
60 ]);
61
62 function wdesignkit_mcp_check_widget_versions(array $input): array {
63 // Timeout guard: cloud version check uses a 30s HTTP timeout; guard PHP execution with a comfortable buffer.
64 set_time_limit(60);
65
66 if (!defined('WDKIT_SERVER_API_URL')) {
67 return ['success' => false, 'message' => 'WDesignKit plugin is not active.'];
68 }
69
70 $auth = wdesignkit_mcp_template_get_auth();
71 if (empty($auth['logged_in'])) {
72 return ['success' => false, 'message' => $auth['message'] ?? 'Not logged in.'];
73 }
74
75 $r_ids_raw = sanitize_text_field((string) ($input['r_ids'] ?? ''));
76 $check_all_local = !empty($input['check_all_local']);
77
78 if ($check_all_local && defined('WDKIT_BUILDER_PATH')) {
79 $collected = [];
80 foreach (['elementor', 'gutenberg', 'gutenberg_core', 'bricks'] as $builder_name) {
81 $builder_dir = WDKIT_BUILDER_PATH . '/' . $builder_name;
82 if (!is_dir($builder_dir)) {
83 continue;
84 }
85 foreach (array_diff(@scandir($builder_dir) ?: [], ['.', '..']) as $widget_folder) {
86 $widget_path = $builder_dir . '/' . $widget_folder;
87 if (!is_dir($widget_path)) {
88 continue;
89 }
90 foreach (array_diff(@scandir($widget_path) ?: [], ['.', '..']) as $f) {
91 if (pathinfo($f, PATHINFO_EXTENSION) !== 'json') {
92 continue;
93 }
94 $raw = @file_get_contents($widget_path . '/' . $f);
95 $jd = ($raw !== false) ? json_decode($raw, true) : null;
96 $rid = $jd['widget_data']['widgetdata']['r_id'] ?? '';
97 if ($rid !== '' && $rid !== '0' && $rid !== 0) {
98 $collected[] = (string) $rid;
99 }
100 break;
101 }
102 }
103 }
104 $r_ids_raw = implode(',', array_unique($collected));
105 }
106
107 if ($r_ids_raw === '') {
108 if ($check_all_local) {
109 // No locally installed widgets have been pushed to the marketplace yet — this is
110 // informational, not an error. Return success:true so callers are not misled.
111 return ['success' => true, 'message' => 'No marketplace-connected widgets found. All locally installed widgets have r_id=0 (never pushed to the cloud marketplace).', 'versions' => []];
112 }
113 return ['success' => false, 'message' => 'Provide r_ids or use check_all_local: true.'];
114 }
115
116 $response = wp_remote_post(
117 WDKIT_SERVER_API_URL . 'api/wp/widget/version/get',
118 [
119 'method' => 'POST',
120 'body' => ['id' => $r_ids_raw, 'token' => $auth['token']],
121 'timeout' => 30,
122 ]
123 );
124
125 if (is_wp_error($response)) {
126 return ['success' => false, 'message' => $response->get_error_message()];
127 }
128
129 $body = wp_remote_retrieve_body($response);
130 $data = json_decode($body, true);
131
132 if (!is_array($data)) {
133 return ['success' => false, 'message' => 'Unexpected response from WDesignKit cloud.'];
134 }
135
136 return [
137 'success' => (bool) ($data['success'] ?? false),
138 'message' => $data['message'] ?? $data['description'] ?? '',
139 'versions' => $data['versions'] ?? $data['data'] ?? [],
140 ];
141 }
142