| @@ -5,8 +5,9 @@ | ||
| 5 | 5 | use Templately\Core\Importer\Utils\Utils; |
| 6 | 6 | use Templately\Core\Platform; |
| 7 | 7 | use Templately\Core\Module; |
| 8 | 8 | use Templately\Utils\Helper; |
| 9 | +use Templately\Utils\Options; | |
| 9 | 10 | |
| 10 | 11 | use WP_Error; |
| 11 | 12 | use function get_permalink; |
| 12 | 13 | use function get_edit_post_link; |
| @@ -12,8 +13,9 @@ | ||
| 12 | 13 | use function get_edit_post_link; |
| 13 | 14 | use function wp_insert_post; |
| 14 | 15 | use function wp_slash; |
| 15 | 16 | use function wp_unslash; |
| 17 | +use function wp_update_post; | |
| 16 | 18 | use function json_decode; |
| 17 | 19 | |
| 18 | 20 | class Gutenberg extends Platform { |
| 19 | 21 | /** |
| @@ -163,15 +165,100 @@ | ||
| 163 | 165 | * Inserts a template into the Gutenberg editor. |
| 164 | 166 | * |
| 165 | 167 | * @param mixed $data |
| 166 | 168 | * @param int $postId |
| 169 | + * @param array $settings | |
| 167 | 170 | * @return array |
| 168 | 171 | */ |
| 169 | - public function insert($data, $postId = 0) { | |
| 170 | - $data['content'] = Utils::import_and_replace_attachments($data['content'], $postId); | |
| 172 | + public function insert($data, $postId = 0, $settings = []) { | |
| 173 | + if ( ! empty( $settings ) && is_array( $settings ) && ! empty( $data['content'] ) && is_string( $data['content'] ) ) { | |
| 174 | + $data['content'] = \Templately\Core\Importer\Utils\GutenbergSettingsMerger::merge( $data['content'], $settings ); | |
| 175 | + } | |
| 176 | + | |
| 177 | + $data['content'] = Utils::import_and_replace_attachments( | |
| 178 | + $data['content'], | |
| 179 | + $postId, | |
| 180 | + [ | |
| 181 | + 'attachment_timeout' => 8, | |
| 182 | + 'attachment_retries' => 0, | |
| 183 | + 'attachment_deadline' => microtime( true ) + 20, | |
| 184 | + ] | |
| 185 | + ); | |
| 171 | 186 | return $data; |
| 172 | 187 | } |
| 173 | 188 | |
| 189 | + /** | |
| 190 | + * Import template to Templately Library | |
| 191 | + * | |
| 192 | + * @param integer $id | |
| 193 | + * @param Import $importer | |
| 194 | + * @param array $settings | |
| 195 | + * | |
| 196 | + * @return array|WP_Error array on success, WP_Error on failure. | |
| 197 | + */ | |
| 198 | + public function import_in_library( $id, $importer = null, $settings = [], $template_type = '', $item_type = '' ) { | |
| 199 | + $template_data = $importer->get_content( $id, 'gutenberg', 'remote' ); | |
| 200 | + | |
| 201 | + if ( is_wp_error( $template_data ) ) { | |
| 202 | + return $template_data; | |
| 203 | + } | |
| 204 | + | |
| 205 | + if ( ! empty( $settings ) && ! empty( $template_data['content'] ) && is_string( $template_data['content'] ) ) { | |
| 206 | + $template_data['content'] = \Templately\Core\Importer\Utils\GutenbergSettingsMerger::merge( $template_data['content'], $settings ); | |
| 207 | + } | |
| 208 | + | |
| 209 | + // Handle attachment replacements before saving | |
| 210 | + $template_data['content'] = Utils::import_and_replace_attachments( $template_data['content'], 0 ); | |
| 211 | + | |
| 212 | + // Frontend-provided template_type (from item details API) takes precedence over | |
| 213 | + // whatever the fetched content JSON reports. | |
| 214 | + if ( ! empty( $template_type ) ) { | |
| 215 | + $template_data['template_type'] = $template_type; | |
| 216 | + } | |
| 217 | + | |
| 218 | + // Resolve the correct Builder Type using template_type before passing to the importer. | |
| 219 | + try { | |
| 220 | + $type = static::resolve_library_type( $template_data ); | |
| 221 | + } catch ( \InvalidArgumentException $e ) { | |
| 222 | + return Helper::error( 'unsupported_template_type', $e->getMessage(), 'import', 400 ); | |
| 223 | + } | |
| 224 | + | |
| 225 | + $factory = new \Templately\Builder\Factory\TemplateFactory( 'gutenberg' ); | |
| 226 | + | |
| 227 | + $template = $factory->create( $type, [ | |
| 228 | + 'post_title' => $template_data['title'], | |
| 229 | + 'post_status' => 'publish', | |
| 230 | + 'post_type' => 'templately_library', | |
| 231 | + ] ); | |
| 232 | + | |
| 233 | + if ( is_wp_error( $template ) ) { | |
| 234 | + return $template; | |
| 235 | + } | |
| 236 | + | |
| 237 | + $template->import( array_merge( $template_data, [ | |
| 238 | + 'import_settings' => [ | |
| 239 | + 'title' => $template_data['title'], | |
| 240 | + 'type' => $type, | |
| 241 | + ] | |
| 242 | + ] ) ); | |
| 243 | + | |
| 244 | + $post_id = $template->get_main_id(); | |
| 245 | + | |
| 246 | + // Companion content for archive/fluent types — same side effects (Shop page, | |
| 247 | + // page_for_posts, LearnDash courses slug, fluent single-page template) the FSI | |
| 248 | + // Templates runner performs when importing these template types. | |
| 249 | + Utils::create_companion_content( $type, $template_data['title'] ?? '', 'gutenberg' ); | |
| 250 | + | |
| 251 | + // Mark user as having imported a template | |
| 252 | + Options::get_instance()->set( 'has_imported_template', true ); | |
| 253 | + | |
| 254 | + return [ | |
| 255 | + 'post_id' => $post_id, | |
| 256 | + 'edit_link' => get_edit_post_link( $post_id, 'internal' ), | |
| 257 | + 'visit' => get_permalink( $post_id ), | |
| 258 | + ]; | |
| 259 | + } | |
| 260 | + | |
| 174 | 261 | /** |
| 175 | 262 | * AJAX handler to update the option `templately-gutenberg-hide-buttons` |
| 176 | 263 | */ |
| 177 | 264 | public function update_gutenberg_hide_buttons() { |
| @@ -177,8 +264,16 @@ | ||
| 177 | 264 | public function update_gutenberg_hide_buttons() { |
| 178 | 265 | // Check nonce for security |
| 179 | 266 | check_ajax_referer( 'templately_nonce', 'nonce' ); |
| 180 | 267 | |
| 268 | + // The nonce alone is not authorization: `templately_nonce` is handed to | |
| 269 | + // every user who loads a Templately-enqueued screen, so without this any | |
| 270 | + // logged-in user could write the option. It toggles buttons in the block | |
| 271 | + // editor, so the people who use that editor are exactly the right gate. | |
| 272 | + if ( ! current_user_can( 'edit_posts' ) ) { | |
| 273 | + wp_send_json_error( [ 'message' => __( 'Insufficient permissions', 'templately' ) ], 403 ); | |
| 274 | + } | |
| 275 | + | |
| 181 | 276 | // Get the new value from the AJAX request |
| 182 | 277 | $hide_buttons = isset($_GET['hide_buttons']) ? sanitize_text_field($_GET['hide_buttons']) : ''; |
| 183 | 278 | |
| 184 | 279 | // Update the option |
| @@ -190,5 +285,5 @@ | ||
| 190 | 285 | wp_send_json_success([ |
| 191 | 286 | 'hide_buttons' => $hide_buttons, |
| 192 | 287 | ]); |
| 193 | 288 | } |
| 194 | -} | |
| 289 | +} | |