PluginProbe
TableKit – WordPress Table Builder for Data Tables, WooCommerce Product Tables & Post Tables / 2.2.7
TableKit – WordPress Table Builder for Data Tables, WooCommerce Product Tables & Post Tables v2.2.7
2.2.14 2.2.13 2.2.12 2.2.11 2.2.10 2.2.9 2.2.8 2.2.7 2.2.6 2.2.5 2.2.4 2.2.3 trunk 1.0.0 1.0.1 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2
table-builder-block / includes / Core / RestApi.php

RestApi.php in TableKit – WordPress Table Builder for Data Tables, WooCommerce Product Tables & Post Tables 2.2.7, at includes/Core/RestApi.php

336 lines 12.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace TableBuilder\Core;
3
4 defined('ABSPATH') || exit;
5
6 /**
7 * REST API fallback when tablekit-essential is not active.
8 * Mimics tablekit-essential behavior for compatibility.
9 *
10 * @since 1.0.0
11 */
12 class RestApi {
13 use \TableBuilder\Traits\Singleton;
14
15 public function __construct() {
16 add_action('rest_api_init', array($this, 'register_routes'));
17 add_action('activated_plugin', array($this, 'clear_plugin_cache'));
18 add_action('deactivated_plugin', array($this, 'clear_plugin_cache'));
19 }
20
21 // Clear plugin cache when plugins change.
22 public function clear_plugin_cache() {
23 delete_transient('tablekit_plugin_data');
24 }
25
26 // Register REST routes only if tablekit-essential is not active.
27 public function register_routes() {
28 if ($this->is_tablekit_essential_active()) {
29 return;
30 }
31
32 register_rest_route('tablekit/v1', '/table-manager-api/check-plugins', array(
33 'methods' => 'POST',
34 'callback' => array($this, 'check_plugins_status'),
35 'permission_callback' => '__return_true',
36 ));
37
38 register_rest_route('tablekit/v1', '/table-manager-api/activate-plugins', array(
39 'methods' => 'POST',
40 'callback' => array($this, 'activate_plugins'),
41 'permission_callback' => function() { return current_user_can('activate_plugins'); },
42 ));
43
44 register_rest_route('tablekit/v1', '/table-manager-api/install-plugins', array(
45 'methods' => 'POST',
46 'callback' => array($this, 'install_plugins'),
47 'permission_callback' => function() { return current_user_can('install_plugins'); },
48 ));
49
50 register_rest_route('tablekit/v1', '/table-manager-api/check-pro-license', array(
51 'methods' => 'POST',
52 'callback' => array($this, 'check_pro_license'),
53 'permission_callback' => function() { return current_user_can('activate_plugins'); },
54 ));
55 }
56
57 private function is_tablekit_essential_active() {
58 if (!function_exists('is_plugin_active')) {
59 require_once ABSPATH . 'wp-admin/includes/plugin.php';
60 }
61 return is_plugin_active('tablekit-essential/tablekit-essential.php');
62 }
63
64 public function check_plugins_status($request) {
65 $plugins = $request->get_json_params()['plugins'] ?? array();
66 if (empty($plugins)) {
67 return new \WP_REST_Response(array('status' => 'error', 'message' => 'No plugins specified.'), 400);
68 }
69
70 // Clear plugin cache to ensure fresh data (critical for detecting deactivated plugins on servers)
71 wp_cache_delete('plugins', 'plugins');
72
73
74 if (!function_exists('get_plugins') || !function_exists('is_plugin_active')) {
75 require_once ABSPATH . 'wp-admin/includes/plugin.php';
76 }
77
78 $all_plugins = get_plugins();
79 $status = array();
80
81 foreach ($plugins as $slug) {
82 $slug = sanitize_text_field($slug);
83 if (empty($slug)) continue;
84
85 $plugin_file = null;
86 foreach ($all_plugins as $plugin_path => $plugin_data) {
87 if (strpos($plugin_path, $slug . '/') === 0 || $plugin_path === $slug . '.php') {
88 $plugin_file = $plugin_path;
89 break;
90 }
91 }
92
93 $is_installed = $plugin_file !== null;
94 $is_active = $is_installed && is_plugin_active($plugin_file);
95
96 $status[$slug] = array(
97 'installed' => $is_installed,
98 'active' => $is_active,
99 'state' => $is_installed ? ($is_active ? 'installed_active' : 'installed_inactive') : 'not_installed',
100 'plugin_file' => $plugin_file,
101 );
102 }
103
104 return new \WP_REST_Response(array('status' => 'success', 'plugins' => $status), 200);
105 }
106
107 // Activate plugins.
108 public function activate_plugins($request) {
109 $plugins = $request->get_json_params()['plugins'] ?? array();
110 if (empty($plugins)) {
111 return new \WP_REST_Response(array('status' => 'error', 'message' => 'No plugins specified.'), 400);
112 }
113
114 if (!function_exists('activate_plugin')) {
115 require_once ABSPATH . 'wp-admin/includes/plugin.php';
116 }
117
118 wp_cache_delete('plugins', 'plugins');
119
120 // Set transient to prevent redirect during programmatic activation
121 set_transient('tablekit_skip_activation_redirect', true, 60);
122
123 $all_plugins = get_plugins();
124 $activated = array();
125 $failed = array();
126
127 foreach ($plugins as $slug) {
128 $slug = sanitize_text_field($slug);
129 if (empty($slug)) continue;
130
131 $plugin_file = null;
132 foreach ($all_plugins as $plugin_path => $plugin_data) {
133 if (strpos($plugin_path, $slug . '/') === 0 || $plugin_path === $slug . '.php') {
134 $plugin_file = $plugin_path;
135 break;
136 }
137 }
138
139 if (!$plugin_file) {
140 $failed[] = array('slug' => $slug, 'error' => 'Plugin not found');
141 continue;
142 }
143
144 if (is_plugin_active($plugin_file)) {
145 $activated[] = $slug;
146 continue;
147 }
148
149 $result = activate_plugin($plugin_file, '', false, true); // Silent activation
150 if (is_wp_error($result)) {
151 $failed[] = array('slug' => $slug, 'error' => $result->get_error_message());
152 } else {
153 $activated[] = $slug;
154 }
155 }
156
157 // Clean up transient
158 delete_transient('tablekit_skip_activation_redirect');
159
160 // Clear plugin cache after activation
161 $this->clear_plugin_cache();
162
163 return new \WP_REST_Response(array(
164 'status' => empty($failed) ? 'success' : 'partial',
165 'activated' => $activated,
166 'failed' => $failed,
167 ), 200);
168 }
169
170 // Install plugins.
171 public function install_plugins($request) {
172 $plugins = $request->get_json_params()['plugins'] ?? array();
173 if (empty($plugins)) {
174 return new \WP_REST_Response(array('status' => 'error', 'message' => 'No plugins specified.'), 400);
175 }
176
177 if (!function_exists('plugins_api')) {
178 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
179 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
180 require_once ABSPATH . 'wp-admin/includes/file.php';
181 }
182
183 $failed = array();
184
185 foreach ($plugins as $slug) {
186 $slug = sanitize_text_field($slug);
187 if (empty($slug)) continue;
188
189 // Check if pro plugin
190 if (strpos($slug, '-pro') !== false) {
191 $failed[] = array('slug' => $slug, 'error' => 'Pro plugins must be purchased manually');
192 continue;
193 }
194
195 // Check if already installed
196 $all_plugins = get_plugins();
197 $plugin_file = null;
198 foreach ($all_plugins as $plugin_path => $plugin_data) {
199 if (strpos($plugin_path, $slug . '/') === 0) {
200 $plugin_file = $plugin_path;
201 break;
202 }
203 }
204
205 if ($plugin_file) {
206 // Already installed, just activate
207 if (!is_plugin_active($plugin_file)) {
208 set_transient('tablekit_skip_activation_redirect', true, 60); // Set transient to prevent redirect
209 activate_plugin($plugin_file, '', false, true); // Silent activation
210 delete_transient('tablekit_skip_activation_redirect');
211 }
212 continue;
213 }
214
215 // Install plugin
216 $api = plugins_api('plugin_information', array('slug' => $slug, 'fields' => array('sections' => false)));
217
218 if (is_wp_error($api)) {
219 $failed[] = array('slug' => $slug, 'error' => $api->get_error_message());
220 continue;
221 }
222
223 $upgrader = new \Plugin_Upgrader(new \WP_Ajax_Upgrader_Skin());
224 $result = $upgrader->install($api->download_link);
225
226 if (is_wp_error($result)) {
227 $failed[] = array('slug' => $slug, 'error' => $result->get_error_message());
228 } elseif ($result === false) {
229 $failed[] = array('slug' => $slug, 'error' => 'Installation failed');
230 }
231 }
232
233 // Clear plugin cache after installation
234 $this->clear_plugin_cache();
235
236 return new \WP_REST_Response(array(
237 'status' => empty($failed) ? 'success' : 'partial',
238 'failed' => $failed,
239 ), 200);
240 }
241
242 /**
243 * Check pro plugin license.
244 */
245 public function check_pro_license($request) {
246 $plugins = $request->get_json_params()['plugins'] ?? array();
247 if (empty($plugins)) {
248 return new \WP_REST_Response(array('status' => 'error', 'message' => 'No plugins specified.'), 400);
249 }
250
251 // Check if this is gutenkit-blocks-addon-pro
252 $is_gutenkit_pro = false;
253 foreach ($plugins as $slug) {
254 if (strpos($slug, 'gutenkit-blocks-addon-pro') !== false) {
255 $is_gutenkit_pro = true;
256 break;
257 }
258 }
259
260 if (!$is_gutenkit_pro) {
261 return new \WP_REST_Response(array(
262 'status' => 'error',
263 'license_valid' => false,
264 'message' => 'License check is only available for GutenKit Pro.',
265 ), 400);
266 }
267
268 // Check GutenKit license status
269 // GutenKit uses these options to store license info
270 $oppai = get_option('__gutenkit_oppai__', '');
271 $key = get_option('__gutenkit_license_key__', '');
272
273 $license_valid = !empty($oppai) && !empty($key);
274
275 if (!$license_valid) {
276 return new \WP_REST_Response(array(
277 'status' => 'error',
278 'license_valid' => false,
279 'message' => 'Pro plugin license is not active. Please activate your license at GutenKit → Settings → License to use pro features.',
280 ), 200);
281 }
282
283 return new \WP_REST_Response(array(
284 'status' => 'success',
285 'license_valid' => true,
286 'message' => 'License is valid.',
287 ), 200);
288 }
289
290 /**
291 * Get localized data - mimics tablekit-essential format.
292 * Now with caching to improve performance.
293 */
294 public static function get_localized_data() {
295 // Check cache first (expires after 12 hours)
296 $cached_data = get_transient('tablekit_plugin_data');
297 if (false !== $cached_data && is_array($cached_data)) {
298 // Update dynamic nonces
299 $cached_data['restNonce'] = wp_create_nonce('wp_rest');
300 $cached_data['ajaxNonce'] = wp_create_nonce('tablekit_activate_nonce');
301 return $cached_data;
302 }
303
304 if (!function_exists('get_plugins') || !function_exists('is_plugin_active')) {
305 require_once ABSPATH . 'wp-admin/includes/plugin.php';
306 }
307
308 $all_plugins = get_plugins();
309 $active_plugins = array();
310 $installed_plugins = array();
311
312 foreach ($all_plugins as $plugin_path => $plugin_data) {
313 $slug = explode('/', $plugin_path)[0];
314 $installed_plugins[] = $slug;
315
316 if (is_plugin_active($plugin_path)) {
317 $active_plugins[] = $slug;
318 }
319 }
320
321 $data = array(
322 'apiUrl' => rest_url('tablekit/v1/'),
323 'restNonce' => wp_create_nonce('wp_rest'),
324 'ajaxNonce' => wp_create_nonce('tablekit_activate_nonce'),
325 'activePlugins' => array_unique($active_plugins),
326 'installedPlugins' => array_unique($installed_plugins),
327 'requiredPlugins' => array('gutenkit-blocks-addon', 'gutenkit-blocks-addon-pro'),
328 );
329
330 // Cache for 12 hours
331 set_transient('tablekit_plugin_data', $data, 12 * HOUR_IN_SECONDS);
332
333 return $data;
334 }
335 }
336