← All changes
|
includes/abilities/templates/wdesignkit-replace-template.php
+38
-5
2.6.1
→
2.7.0
View file →
| @@ -58,8 +58,9 @@ | ||
| 58 | 58 | ], |
| 59 | 59 | 'execute_callback' => 'wdesignkit_mcp_replace_template', |
| 60 | 60 | 'permission_callback' => 'wdesignkit_mcp_permission_callback', |
| 61 | 61 | 'meta' => [ |
| 62 | + 'public' => true, | |
| 62 | 63 | 'show_in_rest' => true, |
| 63 | 64 | 'mcp' => ['public' => true], |
| 64 | 65 | 'annotations' => [ |
| 65 | 66 | 'instructions' => implode("\n", [ |
| @@ -103,9 +104,42 @@ | ||
| 103 | 104 | 'message' => 'Replacement requires explicit confirmation. Re-send with confirm: true after previewing with dry_run: true.', |
| 104 | 105 | ]; |
| 105 | 106 | } |
| 106 | 107 | |
| 108 | + // Wrap the replacement body in the envelope the cloud, the importer and the editor JS expect — | |
| 109 | + // { file_type, title, page_id, content, el_type, settings } with the layout in `content`, the | |
| 110 | + // same shape the Save Template UI builds. | |
| 111 | + // | |
| 112 | + // Writing the raw layout instead broke both builders: | |
| 113 | + // Elementor — the layout decodes to a LIST, and adding the string key 'custom_meta' to a | |
| 114 | + // list makes wp_json_encode() emit an object, turning the indices into "0","1",… | |
| 115 | + // Gutenberg — block markup is a STRING, so json_decode() returned null, the is_array() | |
| 116 | + // branch never ran, and the markup was stored bare with no envelope. The editor | |
| 117 | + // then runs JSON.parse() on it and throws. | |
| 118 | + // | |
| 119 | + // This ability has no `builder` input, so infer it: Elementor data decodes to an array, | |
| 120 | + // Gutenberg content is serialized block markup. | |
| 121 | + $decoded_content = json_decode($data, true); | |
| 122 | + $is_elementor = is_array($decoded_content); | |
| 123 | + | |
| 124 | + $settings = []; | |
| 107 | 125 | if ($post_id !== '') { |
| 126 | + $page_settings = get_post_meta((int) $post_id, '_elementor_page_settings', true); | |
| 127 | + if (is_array($page_settings) && !empty($page_settings)) { | |
| 128 | + $settings = $page_settings; | |
| 129 | + } | |
| 130 | + } | |
| 131 | + | |
| 132 | + $envelope = [ | |
| 133 | + 'file_type' => $is_elementor ? 'elementor' : 'wp_block', | |
| 134 | + 'title' => '', | |
| 135 | + 'page_id' => $post_id !== '' ? (int) $post_id : 0, | |
| 136 | + 'content' => $is_elementor ? $decoded_content : $data, | |
| 137 | + 'el_type' => '', | |
| 138 | + 'settings' => $settings, | |
| 139 | + ]; | |
| 140 | + | |
| 141 | + if ($post_id !== '') { | |
| 108 | 142 | $custom_fields = []; |
| 109 | 143 | foreach ((array) get_post_custom($post_id) as $key => $value) { |
| 110 | 144 | if (is_string($key) && str_contains($key, 'nxt-')) { |
| 111 | 145 | $custom_fields[$key] = $value; |
| @@ -111,15 +145,14 @@ | ||
| 111 | 145 | $custom_fields[$key] = $value; |
| 112 | 146 | } |
| 113 | 147 | } |
| 114 | 148 | if (!empty($custom_fields)) { |
| 115 | - $decoded = json_decode($data, true); | |
| 116 | - if (is_array($decoded)) { | |
| 117 | - $decoded['custom_meta'] = $custom_fields; | |
| 118 | - $data = wp_json_encode($decoded); | |
| 119 | - } | |
| 149 | + // On the envelope (an object), so it cannot reshape `content`. | |
| 150 | + $envelope['custom_meta'] = $custom_fields; | |
| 120 | 151 | } |
| 121 | 152 | } |
| 153 | + | |
| 154 | + $data = wp_json_encode($envelope); | |
| 122 | 155 | |
| 123 | 156 | $args = [ |
| 124 | 157 | 'data' => $data, |
| 125 | 158 | 'post_id' => $post_id, |