'POST', 'callback' => 'addifect_save_template_data', 'permission_callback' => 'addifect_can_edit_designs', 'args' => array( 'design_id' => array( 'required' => true, 'type' => 'integer', 'sanitize_callback' => 'absint', ), 'template_id' => array( 'required' => true, 'type' => 'string', 'sanitize_callback' => 'addifect_sanitize_template_id', ), 'template_data' => array( 'required' => true, 'type' => 'object', 'sanitize_callback' => 'addifect_recursive_sanitize_array', ), 'is_part' => array( 'required' => false, 'type' => 'boolean', 'default' => false, ), ), ) ); } ); /** * Save Addifect template data. * Updates the Design-specific index in Meta and mirrors it to a high-speed session transient. * * @param WP_REST_Request $request REST request object. * @return WP_REST_Response|WP_Error */ function addifect_save_template_data( WP_REST_Request $request ) { $design_id = $request->get_param( 'design_id' ); $template_id = $request->get_param( 'template_id' ); $block = $request->get_param( 'template_data' ); $is_part = $request->get_param( 'is_part' ); if ( empty( $design_id ) ) { return new WP_Error( 'no_design_id', 'No valid design ID provided.', array( 'status' => 400 ) ); } /** * 1. Update Master Index Meta */ $master_index = get_post_meta( $design_id, '_addifect_design_index', true ); if ( ! is_array( $master_index ) ) { $master_index = array( 'parts' => array(), 'all_keys' => array(), ); } else { // Ensure keys exist if legacy data is structured differently. if ( ! isset( $master_index['all_keys'] ) ) { $master_index['all_keys'] = array(); } if ( ! isset( $master_index['parts'] ) ) { $master_index['parts'] = array(); } } // Update keys if they are new. if ( ! in_array( $template_id, $master_index['all_keys'], true ) ) { $master_index['all_keys'][] = $template_id; } if ( $is_part && ! in_array( $template_id, $master_index['parts'], true ) ) { $master_index['parts'][] = $template_id; } /** * THE CRITICAL FIX: Update the timestamp every time! * This ensures the browser cache busts on every save. */ $master_index['updated'] = time(); update_post_meta( $design_id, '_addifect_design_index', $master_index ); // Sync the high-speed transient (now with the fresh timestamp). set_transient( 'addifect_active_session_index', $master_index, 12 * HOUR_IN_SECONDS ); /** * 2. Update Master Templates Meta. */ $all_templates = get_post_meta( $design_id, '_addifect_design_templates', true ); if ( ! is_array( $all_templates ) ) { $all_templates = array(); } $all_templates[ $template_id ] = $block; update_post_meta( $design_id, '_addifect_design_templates', wp_slash( $all_templates ) ); /** * 3. Sync Content Transient */ set_transient( 'addifect_site_template_' . $template_id, $block, 12 * HOUR_IN_SECONDS ); // Update Connection Source of Truth. update_option( 'addifect_active_connection', array( 'kit_id' => null, 'design_id' => $design_id, 'last_sync' => time(), ) ); return new WP_REST_Response( array( 'success' => true, 'updated' => $master_index['updated'], ), 200 ); } add_action( 'rest_api_init', function () { register_rest_route( 'addifect-client/v1', '/unpublish-template', array( 'methods' => 'POST', 'callback' => 'addifect_unpublish_template_data', 'permission_callback' => 'addifect_can_edit_designs', 'args' => array( 'design_id' => array( 'required' => true, 'type' => 'integer', 'sanitize_callback' => 'absint', ), 'template_id' => array( 'required' => true, 'type' => 'string', 'sanitize_callback' => 'addifect_sanitize_template_id', ), 'is_part' => array( 'required' => false, 'type' => 'boolean', 'default' => false, ), ), ) ); } ); /** * Unpublish/Delete Addifect template data. * Removes the template from the master index, deletes the payload, and busts cache. * * @param WP_REST_Request $request REST request object. */ function addifect_unpublish_template_data( WP_REST_Request $request ) { $design_id = $request->get_param( 'design_id' ); $template_id = $request->get_param( 'template_id' ); $is_part = $request->get_param( 'is_part' ); if ( empty( $design_id ) ) { return new WP_Error( 'no_design_id', 'No valid design ID provided.', array( 'status' => 400 ) ); } /** * 1. Clean Master Index Meta */ $master_index = get_post_meta( $design_id, '_addifect_design_index', true ); if ( is_array( $master_index ) ) { if ( isset( $master_index['all_keys'] ) ) { $master_index['all_keys'] = array_values( array_diff( $master_index['all_keys'], array( $template_id ) ) ); } if ( isset( $master_index['parts'] ) ) { $master_index['parts'] = array_values( array_diff( $master_index['parts'], array( $template_id ) ) ); } $master_index['updated'] = time(); update_post_meta( $design_id, '_addifect_design_index', $master_index ); set_transient( 'addifect_active_session_index', $master_index, 12 * HOUR_IN_SECONDS ); } /** * 2. Clean Master Templates Meta */ $all_templates = get_post_meta( $design_id, '_addifect_design_templates', true ); if ( is_array( $all_templates ) && isset( $all_templates[ $template_id ] ) ) { unset( $all_templates[ $template_id ] ); update_post_meta( $design_id, '_addifect_design_templates', wp_slash( $all_templates ) ); } /** * 3. Clear the Content Transient */ delete_transient( 'addifect_site_template_' . $template_id ); return new WP_REST_Response( array( 'success' => true, 'message' => 'Template unpublished and cache cleared.', ), 200 ); }