← All changes
|
includes/abilities/widgets/wdesignkit-widget-preview.php
+22
-6
2.5.5
→
2.7.1
View file →
| @@ -9,12 +9,12 @@ | ||
| 9 | 9 | exit(); |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | 12 | wp_register_ability('wdesignkit/widget-preview', [ |
| 13 | - 'label' => __('WDesignKit Widget Preview', 'sprout-mcp'), | |
| 13 | + 'label' => __('WDesignKit Widget Preview', 'wdesignkit'), | |
| 14 | 14 | 'description' => __( |
| 15 | 15 | 'Creates (or reuses) a temporary WordPress page to preview a widget and returns its editor URL. For Elementor widgets the page opens in the Elementor canvas editor. For Gutenberg/gutenberg_core widgets the page opens in the block editor. No page is created for builder types other than those two.', |
| 16 | - 'sprout-mcp', | |
| 16 | + 'wdesignkit', | |
| 17 | 17 | ), |
| 18 | 18 | 'category' => 'wdesignkit', |
| 19 | 19 | 'input_schema' => [ |
| 20 | 20 | 'type' => 'object', |
| @@ -45,10 +45,11 @@ | ||
| 45 | 45 | 'page_id' => ['type' => 'integer'], |
| 46 | 46 | ], |
| 47 | 47 | ], |
| 48 | 48 | 'execute_callback' => 'wdesignkit_mcp_widget_preview', |
| 49 | - 'permission_callback' => 'sprout_mcp_permission_callback', | |
| 49 | + 'permission_callback' => 'wdesignkit_mcp_permission_callback', | |
| 50 | 50 | 'meta' => [ |
| 51 | + 'public' => true, | |
| 51 | 52 | 'show_in_rest' => true, |
| 52 | 53 | 'mcp' => ['public' => true], |
| 53 | 54 | 'annotations' => [ |
| 54 | 55 | 'instructions' => implode("\n", [ |
| @@ -81,10 +82,13 @@ | ||
| 81 | 82 | if ($folder === '') { |
| 82 | 83 | return ['success' => false, 'message' => 'folder is required.']; |
| 83 | 84 | } |
| 84 | 85 | |
| 85 | - // Normalise gutenberg_core → gutenberg for filesystem lookup | |
| 86 | - $fs_builder = ($builder === 'gutenberg_core') ? 'gutenberg' : $builder; | |
| 86 | + // gutenberg_core widgets live under their own gutenberg_core/ directory — create-widget, | |
| 87 | + // list-widgets, and the gutenberg_core loader all use the raw builder name. Resolve the | |
| 88 | + // folder under the actual builder dir; collapsing gutenberg_core → gutenberg made the | |
| 89 | + // lookup fail with "Widget folder not found" for every Core Gutenberg widget. (bug: 86d3rc7nf) | |
| 90 | + $fs_builder = $builder; | |
| 87 | 91 | |
| 88 | 92 | $widget_dir = WDKIT_BUILDER_PATH . '/' . $fs_builder . '/' . $folder; |
| 89 | 93 | |
| 90 | 94 | if (!is_dir($widget_dir)) { |
| @@ -90,8 +94,15 @@ | ||
| 90 | 94 | if (!is_dir($widget_dir)) { |
| 91 | 95 | return ['success' => false, 'message' => "Widget folder not found: {$fs_builder}/{$folder}"]; |
| 92 | 96 | } |
| 93 | 97 | |
| 98 | + // Realpath validation — ensure we're still inside WDKIT_BUILDER_PATH. | |
| 99 | + $real_widget = realpath($widget_dir); | |
| 100 | + $real_base = realpath(WDKIT_BUILDER_PATH); | |
| 101 | + if (!$real_widget || !$real_base || strpos($real_widget, $real_base . DIRECTORY_SEPARATOR) !== 0) { | |
| 102 | + return ['success' => false, 'message' => 'Invalid widget path.']; | |
| 103 | + } | |
| 104 | + | |
| 94 | 105 | // Read widget metadata from JSON |
| 95 | 106 | $widget_name = $folder; |
| 96 | 107 | $widget_id = ''; |
| 97 | 108 | $files = array_diff(@scandir($widget_dir) ?: [], ['.', '..']); |
| @@ -187,9 +198,14 @@ | ||
| 187 | 198 | return ['success' => false, 'message' => 'Failed to create preview page.']; |
| 188 | 199 | } |
| 189 | 200 | |
| 190 | 201 | if (function_exists('serialize_blocks')) { |
| 191 | - $blocks = [['blockName' => 'wdkit/' . $page_data, 'attrs' => [], 'innerHTML' => '', 'innerContent' => []]]; | |
| 202 | + // Generated Gutenberg widgets register their block as wdkit/wb-<widget_id> | |
| 203 | + // (see gutenberg_file.js / gutenberg_core_file.js). Ensure the wb- prefix so | |
| 204 | + // the inserted block matches the registered name and renders instead of | |
| 205 | + // showing WordPress's "invalid content" recovery error. | |
| 206 | + $block_suffix = (strpos($page_data, 'wb-') === 0) ? $page_data : 'wb-' . $page_data; | |
| 207 | + $blocks = [['blockName' => 'wdkit/' . $block_suffix, 'attrs' => [], 'innerHTML' => '', 'innerContent' => []]]; | |
| 192 | 208 | $updated_content = serialize_blocks($blocks); |
| 193 | 209 | wp_update_post(['ID' => $page_id, 'post_content' => $updated_content]); |
| 194 | 210 | } |
| 195 | 211 | |