| 1 |
<?php |
| 2 |
/** |
| 3 |
* Divi 5 REST API Endpoint |
| 4 |
* |
| 5 |
* @package Smart_Post_Show_Pro |
| 6 |
* @subpackage Smart_Post_Show_Pro/admin/PageBuilders/Divi5 |
| 7 |
* @since 4.0.0 |
| 8 |
*/ |
| 9 |
|
| 10 |
namespace SmartPostShow\Admin\PageBuilders\Divi5; |
| 11 |
|
| 12 |
if ( ! defined( 'ABSPATH' ) ) { |
| 13 |
exit; // Cannot access directly. |
| 14 |
} |
| 15 |
|
| 16 |
use SmartPostShow\Blocks\Helper; |
| 17 |
|
| 18 |
/** |
| 19 |
* Register REST API endpoints for Divi 5 module. |
| 20 |
* |
| 21 |
* @since 4.0.0 |
| 22 |
* |
| 23 |
* @return void |
| 24 |
*/ |
| 25 |
function spsp_divi5_register_rest_routes() { |
| 26 |
// Get template HTML endpoint. |
| 27 |
register_rest_route( |
| 28 |
'spsp/divi5/v1', |
| 29 |
'/template-html', |
| 30 |
array( |
| 31 |
array( |
| 32 |
'methods' => 'GET', |
| 33 |
'callback' => __NAMESPACE__ . '\\spsp_divi5_get_template_html', |
| 34 |
'permission_callback' => function () { |
| 35 |
return current_user_can( 'edit_posts' ); |
| 36 |
}, |
| 37 |
'args' => array( |
| 38 |
'template_id' => array( |
| 39 |
'required' => true, |
| 40 |
'sanitize_callback' => 'absint', |
| 41 |
'description' => 'Template ID', |
| 42 |
), |
| 43 |
), |
| 44 |
), |
| 45 |
) |
| 46 |
); |
| 47 |
|
| 48 |
// Get saved templates list endpoint. |
| 49 |
register_rest_route( |
| 50 |
'spsp/divi5/v1', |
| 51 |
'/saved-templates', |
| 52 |
array( |
| 53 |
array( |
| 54 |
'methods' => 'GET', |
| 55 |
'callback' => __NAMESPACE__ . '\\spsp_divi5_get_saved_templates', |
| 56 |
'permission_callback' => function () { |
| 57 |
return current_user_can( 'edit_posts' ); |
| 58 |
}, |
| 59 |
), |
| 60 |
) |
| 61 |
); |
| 62 |
} |
| 63 |
|
| 64 |
/** |
| 65 |
* Get global CSS from plugin settings. |
| 66 |
* Reusable function that matches Assets_Manager::add_global_css() logic. |
| 67 |
* |
| 68 |
* @since 4.0.0 |
| 69 |
* |
| 70 |
* @return array Array with 'css' and 'fonts' keys. |
| 71 |
*/ |
| 72 |
function spsp_divi5_get_global_css() { |
| 73 |
$global_style = get_option( 'sp_smart_post_global_settings', array() ); |
| 74 |
$custom_css = $global_style['customCss'] ?? ''; |
| 75 |
$typography_css = ! empty( $global_style['typography']['typographyCss'] ) ? $global_style['typography']['typographyCss'] : ':root { --sp-smart-font-size-heading-1: 44px; --sp-smart-font-size-heading-2: 32px; --sp-smart-font-size-heading-3: 24px; --sp-smart-font-size-heading-4: 22px; --sp-smart-font-size-heading-5: 20px; --sp-smart-font-size-heading-6: 18px; --sp-smart-font-size-body-1: 18px; --sp-smart-font-size-body-2: 16px; --sp-smart-font-size-body-3: 14px; --sp-smart-font-size-body-4: 12px; --sp-smart-font-size-button-1: 18px; --sp-smart-font-size-button-2: 16px;}'; |
| 76 |
$root_css = ! empty( $global_style['rootcss'] ) ? $global_style['rootcss'] : ':root{ --sp-smart-breakpoint-tablet: 1023px; --sp-smart-breakpoint-mobile: 767px; --smart-post-light-text: #FAFAFA; --smart-post-background: #FFFFFF; --smart-post-primary-light: #EBEBEB; --smart-post-primary: #999999; --smart-post-primary-dark: #1D1D1D; --smart-post-secondary: #0054FB; --smart-post-dark-2-text: #3E3E3E; --smart-post-dark-text: #0A0A0A; --smart-post-black: #000000;} :root { --smart-post-shadow-subtle-1dp: 0px 1px 2px 0px rgba(0, 0, 0, 0.12); --smart-post-shadow-light-2dp: 0px 2px 4px 0px rgba(0, 0, 0, 0.14); --smart-post-shadow-medium-4dp: 0px 4px 6px 0px rgba(0, 0, 0, 0.16); --smart-post-shadow-strong-8dp: 0px 8px 18px 0px rgba(0, 0, 0, 0.18); --smart-post-shadow-deep-12dp: 0px 12px 17px 0px rgba(0, 0, 0, 0.20); --smart-post-shadow-sharp-4dp: 4px 4px 0px 0px rgba(0, 0, 0, 0.25);}'; |
| 77 |
$shadow_css = $global_style['shadow']['shadowRootCSS'] ?? ':root { --smart-post-shadow-subtle-1dp: 0px 1px 2px 0px rgba(0, 0, 0, 0.12); --smart-post-shadow-light-2dp: 0px 2px 4px 0px rgba(0, 0, 0, 0.14); --smart-post-shadow-medium-4dp: 0px 4px 6px 0px rgba(0, 0, 0, 0.16); --smart-post-shadow-strong-8dp: 0px 8px 18px 0px rgba(0, 0, 0, 0.18); --smart-post-shadow-deep-12dp: 0px 12px 17px 0px rgba(0, 0, 0, 0.20); --smart-post-shadow-sharp-4dp: 4px 4px 0px 0px rgba(0, 0, 0, 0.25);}'; |
| 78 |
$global_fonts = $global_style['typography']['fontList'] ?? ''; |
| 79 |
|
| 80 |
$css = wp_strip_all_tags( $typography_css . $root_css . $shadow_css . $custom_css ); |
| 81 |
|
| 82 |
return array( |
| 83 |
'css' => $css, |
| 84 |
'fonts' => is_array( $global_fonts ) ? $global_fonts : ( ! empty( $global_fonts ) ? array( $global_fonts ) : array() ), |
| 85 |
); |
| 86 |
} |
| 87 |
|
| 88 |
/** |
| 89 |
* Get template HTML for visual builder. |
| 90 |
* |
| 91 |
* @since 4.0.0 |
| 92 |
* |
| 93 |
* @param \WP_REST_Request $request REST request object. |
| 94 |
* @return \WP_REST_Response REST response with HTML. |
| 95 |
*/ |
| 96 |
function spsp_divi5_get_template_html( $request ) { |
| 97 |
$template_id = $request->get_param( 'template_id' ); |
| 98 |
|
| 99 |
// Validate template ID. |
| 100 |
if ( empty( $template_id ) || 0 === $template_id ) { |
| 101 |
return new \WP_REST_Response( |
| 102 |
array( |
| 103 |
'success' => false, |
| 104 |
'html' => '<div style="padding:20px;text-align:center;color:#999;">Invalid template ID</div>', |
| 105 |
), |
| 106 |
400 |
| 107 |
); |
| 108 |
} |
| 109 |
|
| 110 |
// Check if template exists and is published. |
| 111 |
$template_post = get_post( $template_id ); |
| 112 |
if ( ! $template_post || 'publish' !== $template_post->post_status ) { |
| 113 |
return new \WP_REST_Response( |
| 114 |
array( |
| 115 |
'success' => false, |
| 116 |
'html' => '<div style="padding:20px;text-align:center;color:#999;">Template not found or not published</div>', |
| 117 |
), |
| 118 |
404 |
| 119 |
); |
| 120 |
} |
| 121 |
|
| 122 |
// Build CSS output. |
| 123 |
$css_output = ''; |
| 124 |
|
| 125 |
// 1. Template static CSS file. |
| 126 |
$upload_dir = wp_upload_dir(); |
| 127 |
$css_file = trailingslashit( $upload_dir['basedir'] ) . 'smart-post-show/static/sp-post-' . $template_id . '.css'; |
| 128 |
if ( file_exists( $css_file ) ) { |
| 129 |
$css_file_content = file_get_contents( $css_file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents |
| 130 |
if ( ! empty( $css_file_content ) ) { |
| 131 |
$css_output .= '<style id="spsp-static-css-' . esc_attr( $template_id ) . '">' . $css_file_content . '</style>'; |
| 132 |
} |
| 133 |
} |
| 134 |
|
| 135 |
// 2. Template inline dynamic CSS from meta. |
| 136 |
$inline_css = get_post_meta( $template_id, '_sp_smart_css', true ); |
| 137 |
if ( ! empty( $inline_css ) ) { |
| 138 |
$css_output .= '<style id="spsp-dynamic-css-' . esc_attr( $template_id ) . '">' . $inline_css . '</style>'; |
| 139 |
} |
| 140 |
|
| 141 |
// 3. Template-specific Google Fonts. |
| 142 |
$font_lists = get_post_meta( $template_id, '_sp_smart_fonts', true ); |
| 143 |
if ( ! empty( $font_lists ) && is_array( $font_lists ) ) { |
| 144 |
$font_lists = array_unique( $font_lists ); |
| 145 |
foreach ( $font_lists as $font ) { |
| 146 |
if ( ! empty( $font ) ) { |
| 147 |
$css_output .= '<link rel="stylesheet" href="' . esc_url( 'https://fonts.googleapis.com/css?family=' . $font ) . '">'; // phpcs:ignore |
| 148 |
} |
| 149 |
} |
| 150 |
} |
| 151 |
|
| 152 |
// 4. Global CSS (includes --smart-show-secondary and other root variables). |
| 153 |
$global_css_data = spsp_divi5_get_global_css(); |
| 154 |
if ( ! empty( $global_css_data['css'] ) ) { |
| 155 |
$css_output .= '<style id="spsp-global-root-css">' . $global_css_data['css'] . '</style>'; |
| 156 |
} |
| 157 |
|
| 158 |
// 5. Global Google Fonts. |
| 159 |
if ( ! empty( $global_css_data['fonts'] ) ) { |
| 160 |
$font_array = array_unique( $global_css_data['fonts'] ); |
| 161 |
foreach ( $font_array as $g_font ) { |
| 162 |
if ( ! empty( $g_font ) ) { |
| 163 |
$css_output .= '<link rel="stylesheet" href="' . esc_url( 'https://fonts.googleapis.com/css?family=' . $g_font ) . '">'; // phpcs:ignore |
| 164 |
} |
| 165 |
} |
| 166 |
} |
| 167 |
|
| 168 |
// Render the shortcode - this is server-side rendering. |
| 169 |
$template_html = do_shortcode( '[smart_post id="' . absint( $template_id ) . '"]' ); |
| 170 |
// Prepend all CSS and fonts to HTML. |
| 171 |
$template_html = $css_output . $template_html; |
| 172 |
|
| 173 |
// Return HTML with CSS and fonts (all included inline). |
| 174 |
return new \WP_REST_Response( |
| 175 |
array( |
| 176 |
'success' => true, |
| 177 |
'html' => $template_html, |
| 178 |
), |
| 179 |
200 |
| 180 |
); |
| 181 |
} |
| 182 |
|
| 183 |
/** |
| 184 |
* Get saved templates list for settings dropdown. |
| 185 |
* |
| 186 |
* @since 4.0.0 |
| 187 |
* |
| 188 |
* @param \WP_REST_Request $request REST request object. |
| 189 |
* @return \WP_REST_Response REST response with templates list. |
| 190 |
*/ |
| 191 |
function spsp_divi5_get_saved_templates( $request ) { |
| 192 |
$templates = Helper::get_save_template_list(); |
| 193 |
|
| 194 |
$result = array(); |
| 195 |
$result['0'] = __( '- Select Template -', 'post-carousel' ); |
| 196 |
|
| 197 |
foreach ( $templates as $id => $title ) { |
| 198 |
$result[ $id ] = $title; |
| 199 |
} |
| 200 |
|
| 201 |
return new \WP_REST_Response( $result, 200 ); |
| 202 |
} |
| 203 |
|