Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 363 |
|
0.00% |
0 / 16 |
CRAP | |
0.00% |
0 / 1 |
WP_Admin | |
0.00% |
0 / 363 |
|
0.00% |
0 / 16 |
3906 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
load_php_textdomain | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
register_page | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
page_title | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
is_loading | |
0.00% |
0 / 92 |
|
0.00% |
0 / 1 |
2 | |||
render | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
register_assets | |
0.00% |
0 / 59 |
|
0.00% |
0 / 1 |
20 | |||
enqueue_block_assets | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
exit_to_dashboard | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
20 | |||
initialize | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
mark_sitegen_generated_themes | |
0.00% |
0 / 29 |
|
0.00% |
0 / 1 |
12 | |||
set_onboarding_restart_option | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
can_restart_onboarding | |
0.00% |
0 / 34 |
|
0.00% |
0 / 1 |
12 | |||
hide_onboarding_restart_card | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
2 | |||
enqueue_site_editor_assets | |
0.00% |
0 / 23 |
|
0.00% |
0 / 1 |
30 | |||
enqueue_preview_fonts | |
0.00% |
0 / 58 |
|
0.00% |
0 / 1 |
650 |
1 | <?php |
2 | namespace NewfoldLabs\WP\Module\Onboarding; |
3 | |
4 | use NewfoldLabs\WP\Module\Onboarding\Data\Data; |
5 | use NewfoldLabs\WP\Module\Onboarding\Data\Options; |
6 | use NewfoldLabs\WP\Module\Onboarding\Services\PluginService; |
7 | use NewfoldLabs\WP\Module\Onboarding\Services\ThemeService; |
8 | use NewfoldLabs\WP\Module\Onboarding\Data\Services\FlowService; |
9 | use NewfoldLabs\WP\Module\Onboarding\Data\Services\SiteGenService; |
10 | use NewfoldLabs\WP\Module\Onboarding\Data\Themes; |
11 | use NewfoldLabs\WP\Module\Onboarding\Services\I18nService; |
12 | use NewfoldLabs\WP\Module\Onboarding\Services\ReduxStateService; |
13 | use NewfoldLabs\WP\Module\Onboarding\Services\StatusService; |
14 | |
15 | /** |
16 | * Register Admin Page, Assets & Admin functionality with WordPress. |
17 | */ |
18 | final class WP_Admin { |
19 | |
20 | /** |
21 | * Identifier for page and assets. |
22 | * |
23 | * @var string |
24 | */ |
25 | public static $slug = 'nfd-onboarding'; |
26 | |
27 | /** |
28 | * Array of allowed referrers |
29 | * |
30 | * @var array |
31 | */ |
32 | protected static $allowed_referrers = array( |
33 | 'nfd-onboarding', |
34 | 'nfd-plugin', |
35 | ); |
36 | |
37 | /** |
38 | * Tap WordPress Hooks |
39 | * |
40 | * @return void |
41 | */ |
42 | public function __construct() { |
43 | \add_action( 'init', array( __CLASS__, 'load_php_textdomain' ) ); |
44 | \add_action( 'admin_menu', array( __CLASS__, 'register_page' ) ); |
45 | \add_action( 'load-dashboard_page_' . self::$slug, array( __CLASS__, 'page_title' ), 9, 1 ); |
46 | \add_action( 'load-dashboard_page_' . self::$slug, array( __CLASS__, 'initialize' ) ); |
47 | /** |
48 | * We're disabling the restart onboarding feature for now. |
49 | */ |
50 | \add_action( 'load-toplevel_page_bluehost', array( __CLASS__, 'hide_onboarding_restart_card' ) ); |
51 | // \add_action( 'load-themes.php', array( __CLASS__, 'can_restart_onboarding' ) ); |
52 | \add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_site_editor_assets' ) ); |
53 | if ( 'sitegen' === Data::current_flow() ) { |
54 | \add_action( 'load-themes.php', array( __CLASS__, 'mark_sitegen_generated_themes' ) ); |
55 | SiteGenService::pre_set_filter_wonder_blocks_transients(); |
56 | SiteGenService::instantiate_sitegen_hooks(); |
57 | } |
58 | } |
59 | |
60 | /** |
61 | * Loads the textdomain for the module. This applies only to PHP strings. |
62 | * |
63 | * @return boolean |
64 | */ |
65 | public static function load_php_textdomain() { |
66 | return I18nService::load_php_translations( |
67 | 'wp-module-onboarding', |
68 | NFD_ONBOARDING_PLUGIN_DIRNAME . '/vendor/newfold-labs/wp-module-onboarding/languages' |
69 | ); |
70 | } |
71 | |
72 | /** |
73 | * Register WordPress Admin Page. |
74 | * |
75 | * By passing null to add_submenu_page, the page isn't displayed in the left Admin Menu, |
76 | * but is available from /wp-admin/index.php?page=nfd-onboarding. |
77 | * |
78 | * @return void |
79 | */ |
80 | public static function register_page() { |
81 | \add_submenu_page( |
82 | '', |
83 | \__( 'Onboarding', 'wp-module-onboarding' ), |
84 | \__( 'Onboarding', 'wp-module-onboarding' ), |
85 | Permissions::ADMIN, |
86 | self::$slug, |
87 | array( __CLASS__, 'render' ), |
88 | 100 |
89 | ); |
90 | } |
91 | |
92 | /** |
93 | * Set the page title for the Onboarding page. |
94 | * |
95 | * @return void |
96 | * */ |
97 | public static function page_title() { |
98 | if ( isset( $_GET['page'] ) && \sanitize_text_field( wp_unslash( $_GET['page'] ) ) === self::$slug ) { |
99 | global $title; |
100 | $title = \__( 'Onboarding', 'wp-module-onboarding' ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited |
101 | } |
102 | } |
103 | |
104 | /** |
105 | * Render a loading screen. |
106 | * |
107 | * @return string |
108 | */ |
109 | public static function is_loading() { |
110 | ob_start(); |
111 | ?> |
112 | <style> |
113 | body.wp-admin { |
114 | overflow: hidden !important; |
115 | } |
116 | .nfd-onboarding-loading-app__skeleton { |
117 | position: relative; |
118 | overflow: hidden; |
119 | background-color: #DDE7F0; |
120 | } |
121 | .nfd-onboarding-loading-app__skeleton::after { |
122 | position: absolute; |
123 | top: 0; |
124 | right: 0; |
125 | bottom: 0; |
126 | left: 0; |
127 | transform: translateX(-100%); |
128 | background-image: linear-gradient( |
129 | 90deg, |
130 | rgba(255, 255, 255, 0) 0, |
131 | rgba(255, 255, 255, 0.2) 20%, |
132 | rgba(255, 255, 255, 0.5) 60%, |
133 | rgba(255, 255, 255, 0) |
134 | ); |
135 | animation: nfd-skeleton-animation 2.5s infinite; |
136 | content: ""; |
137 | } |
138 | @keyframes nfd-skeleton-animation { |
139 | 100% { |
140 | transform: translateX(100%); |
141 | } |
142 | } |
143 | #nfd-onboarding { |
144 | z-index: 100000; |
145 | } |
146 | .nfd-onboarding-loading-app { |
147 | background-color: #F1F5F9; |
148 | width: 100%; |
149 | opacity: 1; |
150 | transition: opacity 0.3s ease-in-out; |
151 | } |
152 | .nfd-onboarding-loading-app.fade-out { |
153 | opacity: 0; |
154 | } |
155 | .nfd-onboarding-loading-app__header { |
156 | background-color: #FFF; |
157 | border-bottom: 1px solid #ECEEFE; |
158 | display: flex; |
159 | justify-content: space-between; |
160 | align-items: center; |
161 | padding: 0 1.5rem; |
162 | min-height: 4rem; |
163 | } |
164 | .nfd-onboarding-loading-app__header__logo { |
165 | width: 135px; |
166 | height: 24px; |
167 | border-radius: 6px; |
168 | } |
169 | .nfd-onboarding-loading-app__header__exit { |
170 | width: 24px; |
171 | height: 24px; |
172 | border-radius: 6px; |
173 | } |
174 | .nfd-onboarding-loading-app__body { |
175 | position: absolute; |
176 | top: 0; |
177 | left: 0; |
178 | right: 0; |
179 | bottom: 0; |
180 | display: flex; |
181 | justify-content: center; |
182 | align-items: center; |
183 | } |
184 | .nfd-onboarding-loading-app__body__spinner { |
185 | width: 100px; |
186 | height: 100px; |
187 | margin-top: -65px; |
188 | border-radius: 12px; |
189 | opacity: 0.8; |
190 | } |
191 | </style> |
192 | <div class="nfd-onboarding-loading-app"> |
193 | <header class="nfd-onboarding-loading-app__header"> |
194 | <div class="nfd-onboarding-loading-app__header__logo nfd-onboarding-loading-app__skeleton"></div> |
195 | <div class="nfd-onboarding-loading-app__header__exit nfd-onboarding-loading-app__skeleton"></div> |
196 | </header> |
197 | <div class="nfd-onboarding-loading-app__body"> |
198 | <div class="nfd-onboarding-loading-app__body__spinner nfd-onboarding-loading-app__skeleton"></div> |
199 | </div> |
200 | </div> |
201 | <?php |
202 | return ob_get_clean(); |
203 | } |
204 | |
205 | /** |
206 | * Render DOM element for React SPA mount. |
207 | * |
208 | * @return void |
209 | */ |
210 | public static function render() { |
211 | echo PHP_EOL; |
212 | echo '<!-- NFD:ONBOARDING -->'; |
213 | echo PHP_EOL; |
214 | echo '<div id="nfd-onboarding" class="nfd-onboarding-container">' . self::is_loading() . '</div>'; |
215 | echo PHP_EOL; |
216 | echo '<!-- /NFD:ONBOARDING -->'; |
217 | echo PHP_EOL; |
218 | } |
219 | |
220 | /** |
221 | * Register built assets with WP_Dependency system. |
222 | * |
223 | * @return void |
224 | */ |
225 | public static function register_assets() { |
226 | global $current_screen; |
227 | |
228 | $current_screen->is_block_editor( true ); |
229 | |
230 | $asset_file = NFD_ONBOARDING_BUILD_DIR . '/onboarding.asset.php'; |
231 | |
232 | if ( is_readable( $asset_file ) ) { |
233 | $asset = include_once $asset_file; |
234 | |
235 | \wp_register_script( |
236 | self::$slug, |
237 | NFD_ONBOARDING_BUILD_URL . '/onboarding.js', |
238 | array_merge( $asset['dependencies'], array() ), |
239 | $asset['version'], |
240 | true |
241 | ); |
242 | |
243 | I18nService::load_js_translations( |
244 | 'wp-module-onboarding', |
245 | self::$slug, |
246 | NFD_ONBOARDING_DIR . '/languages' |
247 | ); |
248 | |
249 | $nfdOnboardingData = array( |
250 | 'runtime' => Data::runtime(), |
251 | 'input' => ReduxStateService::get( 'input' ), |
252 | 'sitegen' => ReduxStateService::get( 'sitegen' ), |
253 | ); |
254 | \wp_add_inline_script( |
255 | self::$slug, |
256 | 'var nfdOnboarding =' . wp_json_encode( $nfdOnboardingData ) . ';', |
257 | 'before' |
258 | ); |
259 | |
260 | \wp_register_style( |
261 | self::$slug, |
262 | NFD_ONBOARDING_BUILD_URL . '/onboarding.css', |
263 | array( 'wp-components', 'wp-editor', 'wp-edit-blocks' ), |
264 | $asset['version'] |
265 | ); |
266 | |
267 | wp_add_inline_script( |
268 | 'wp-blocks', |
269 | 'wp.blocks.unstable__bootstrapServerSideBlockDefinitions(' . wp_json_encode( get_block_editor_server_block_settings() ) . ');' |
270 | ); |
271 | |
272 | // Preload server-registered block bindings sources. |
273 | $registered_sources = get_all_registered_block_bindings_sources(); |
274 | if ( ! empty( $registered_sources ) ) { |
275 | $filtered_sources = array(); |
276 | foreach ( $registered_sources as $source ) { |
277 | $filtered_sources[] = array( |
278 | 'name' => $source->name, |
279 | 'label' => $source->label, |
280 | 'usesContext' => $source->uses_context, |
281 | ); |
282 | } |
283 | $script = sprintf( 'for ( const source of %s ) { wp.blocks.registerBlockBindingsSource( source ); }', wp_json_encode( $filtered_sources ) ); |
284 | wp_add_inline_script( |
285 | 'wp-blocks', |
286 | $script |
287 | ); |
288 | } |
289 | |
290 | wp_add_inline_script( |
291 | 'wp-blocks', |
292 | sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( get_block_categories( $block_editor_context ) ) ), |
293 | 'after' |
294 | ); |
295 | |
296 | \wp_enqueue_script( self::$slug ); |
297 | \wp_enqueue_style( self::$slug ); |
298 | |
299 | \add_action( 'enqueue_block_assets', array( __CLASS__, 'enqueue_block_assets' ) ); |
300 | } |
301 | } |
302 | |
303 | /** |
304 | * Enqueues the block assets for the live previews. |
305 | * |
306 | * @return void |
307 | */ |
308 | public static function enqueue_block_assets() { |
309 | // This hook exists in the patterns module. |
310 | \do_action( 'enqueue_nfd_wonder_blocks_utilities' ); |
311 | } |
312 | |
313 | /** |
314 | * Redirects to the brand plugin page or the WordPress admin dashboard. |
315 | * |
316 | * @return void |
317 | */ |
318 | public static function exit_to_dashboard(): bool { |
319 | $runtime_data = Data::runtime(); |
320 | $brand_plugin_url = ''; |
321 | $dashboard_redirect_params = 'referrer=' . self::$slug; |
322 | |
323 | // Get the brand plugin page URL from the runtime data. |
324 | if ( |
325 | isset( $runtime_data['currentBrand'], $runtime_data['currentBrand']['pluginDashboardPage'] ) && |
326 | is_string( $runtime_data['currentBrand']['pluginDashboardPage'] ) |
327 | ) { |
328 | // Set the brand plugin page URL. |
329 | $brand_plugin_url = $runtime_data['currentBrand']['pluginDashboardPage']; |
330 | } |
331 | |
332 | // If the brand plugin page URL is not found in the runtime, redirect to the WordPress admin. |
333 | if ( empty( $brand_plugin_url ) ) { |
334 | wp_redirect( admin_url() . '?' . $dashboard_redirect_params ); |
335 | exit; |
336 | } |
337 | |
338 | // If the brand plugin page URL is found in the runtime, redirect to the brand plugin page. |
339 | wp_redirect( $brand_plugin_url . '&' . $dashboard_redirect_params ); |
340 | exit; |
341 | } |
342 | |
343 | /** |
344 | * Initialize Plugins and Themes if necessary. |
345 | * |
346 | * @return void |
347 | */ |
348 | public static function initialize() { |
349 | if ( ! empty( $_GET['nfd_plugins'] ) && 'true' === sanitize_text_field( $_GET['nfd_plugins'] ) ) { |
350 | PluginService::initialize(); |
351 | } |
352 | |
353 | // Install and activate the default theme. |
354 | $default_theme_installation_result = ThemeService::initialize(); |
355 | if ( ! $default_theme_installation_result ) { |
356 | self::exit_to_dashboard(); |
357 | } |
358 | |
359 | self::register_assets(); |
360 | |
361 | self::set_onboarding_restart_option(); |
362 | } |
363 | |
364 | /** |
365 | * Enqueue scripts that mark Sitegen flow generated themes. |
366 | * |
367 | * @return void |
368 | */ |
369 | public static function mark_sitegen_generated_themes() { |
370 | $flow_data = get_option( Options::get_option_name( 'flow' ), false ); |
371 | |
372 | if ( ! $flow_data || ! isset( $flow_data['sitegen']['homepages'] ) ) { |
373 | return; |
374 | } |
375 | |
376 | \wp_register_script( |
377 | 'sitegen-theme-marker', |
378 | NFD_ONBOARDING_BUILD_URL . '/sitegen-theme-marker.js', |
379 | array(), |
380 | '1.0.0', |
381 | true |
382 | ); |
383 | |
384 | \wp_add_inline_script( |
385 | 'sitegen-theme-marker', |
386 | 'var nfdOnboarding =' . wp_json_encode( |
387 | array( |
388 | 'homepages' => $flow_data['sitegen']['homepages'], |
389 | 'active' => Themes::get_active_theme(), |
390 | ) |
391 | ) . ';', |
392 | 'before' |
393 | ); |
394 | |
395 | \wp_register_style( |
396 | 'sitegen-theme-marker', |
397 | NFD_ONBOARDING_BUILD_URL . '/sitegen-theme-marker.css.css', |
398 | array(), |
399 | '1.0.0', |
400 | 'all' |
401 | ); |
402 | |
403 | \wp_enqueue_script( 'sitegen-theme-marker' ); |
404 | \wp_enqueue_style( 'sitegen-theme-marker' ); |
405 | } |
406 | |
407 | /** |
408 | * Sets the option in DB for the Initial Load of Onboarding |
409 | * |
410 | * @return void |
411 | */ |
412 | public static function set_onboarding_restart_option(): void { |
413 | // Check if the customer is eligible for onboarding restart |
414 | if ( StatusService::is_onboarding_restart_eligible() ) { |
415 | // Get the option name for 'can_restart' |
416 | $option_name = Options::get_option_name( 'can_restart' ); |
417 | |
418 | // Check if the option doesn't exist before adding it |
419 | if ( ! get_option( $option_name ) ) { |
420 | // Add the option if it doesn't exist |
421 | add_option( $option_name, true ); |
422 | } |
423 | } else { |
424 | // Get the option name for 'can_restart' |
425 | $option_name = Options::get_option_name( 'can_restart' ); |
426 | |
427 | // Add the option if it doesn't exist |
428 | update_option( $option_name, false ); |
429 | } |
430 | } |
431 | |
432 | /** |
433 | * Enqueue scripts that adds a new button to Restart Onboarding in themes.php |
434 | * |
435 | * @return void |
436 | */ |
437 | public static function can_restart_onboarding(): void { |
438 | $can_restart = get_option( Options::get_option_name( 'can_restart' ), false ); |
439 | |
440 | // If the customer in ineligible for restart don't enqueue scripts |
441 | if ( ! $can_restart || ! StatusService::is_onboarding_restart_eligible() ) { |
442 | return; |
443 | } |
444 | |
445 | \wp_register_script( |
446 | 'onboarding-restart-button', |
447 | NFD_ONBOARDING_BUILD_URL . '/onboarding-restart-button.js', |
448 | array(), |
449 | '1.0.0', |
450 | true |
451 | ); |
452 | |
453 | \wp_add_inline_script( |
454 | 'onboarding-restart-button', |
455 | 'var nfdOnboardingRestartMeta =' . wp_json_encode( |
456 | array( |
457 | 'buttonText' => \__( 'Build with AI', 'wp-module-onboarding' ), |
458 | 'buttonHref' => \admin_url( 'index.php?page=' . self::$slug ), |
459 | ) |
460 | ) . ';', |
461 | 'before' |
462 | ); |
463 | |
464 | \wp_register_style( |
465 | 'onboarding-restart-button', |
466 | NFD_ONBOARDING_BUILD_URL . '/onboarding-restart-button.css.css', |
467 | array(), |
468 | '1.0.0', |
469 | 'all' |
470 | ); |
471 | |
472 | /** |
473 | * Temporary: hide the build with ai button |
474 | */ |
475 | wp_add_inline_style( |
476 | 'onboarding-restart-button', |
477 | '.themes .theme.build-with-ai { |
478 | display: none !important; |
479 | }' |
480 | ); |
481 | |
482 | \wp_enqueue_script( 'onboarding-restart-button' ); |
483 | \wp_enqueue_style( 'onboarding-restart-button' ); |
484 | } |
485 | |
486 | /** |
487 | * Temporary: Enqueue scripts that hides the build with ai button |
488 | * |
489 | * @return void |
490 | */ |
491 | public static function hide_onboarding_restart_card(): void { |
492 | \wp_register_style( |
493 | 'hide-onboarding-restart-card', |
494 | false, |
495 | ); |
496 | |
497 | \wp_add_inline_style( |
498 | 'hide-onboarding-restart-card', |
499 | 'div[data-testid="restartOnboarding"] { |
500 | display: none !important; |
501 | }' |
502 | ); |
503 | |
504 | \wp_enqueue_style( 'hide-onboarding-restart-card' ); |
505 | } |
506 | |
507 | /* |
508 | Enqueue site editor specific assets when coming from onboarding. |
509 | * |
510 | * @return void |
511 | */ |
512 | public static function enqueue_site_editor_assets() { |
513 | global $pagenow; |
514 | |
515 | // Only proceed if we're on site-editor.php and have the right referrer |
516 | if ( 'site-editor.php' === $pagenow && |
517 | isset( $_GET['referrer'] ) && |
518 | in_array( $_GET['referrer'], self::$allowed_referrers, true ) |
519 | ) { |
520 | |
521 | $asset_file = NFD_ONBOARDING_BUILD_DIR . '/onboarding-design-studio.asset.php'; |
522 | |
523 | if ( is_readable( $asset_file ) ) { |
524 | $asset = include_once $asset_file; |
525 | |
526 | \wp_register_script( |
527 | 'nfd-design-studio', |
528 | NFD_ONBOARDING_BUILD_URL . '/onboarding-design-studio.js', |
529 | $asset['dependencies'] ?? array( 'wp-editor', 'wp-blocks', 'wp-components' ), |
530 | $asset['version'] ?? '1.0.0', |
531 | true |
532 | ); |
533 | |
534 | \wp_register_style( |
535 | 'nfd-design-studio', |
536 | NFD_ONBOARDING_BUILD_URL . '/onboarding-design-studio.css.css', |
537 | array( 'wp-components' ), |
538 | $asset['version'] ?? '1.0.0' |
539 | ); |
540 | |
541 | \wp_enqueue_script( 'nfd-design-studio' ); |
542 | \wp_enqueue_style( 'nfd-design-studio' ); |
543 | |
544 | // Enqueue fonts for preview |
545 | self::enqueue_preview_fonts(); |
546 | } |
547 | } |
548 | } |
549 | |
550 | /** |
551 | * Enqueue all available fonts for preview in design studio |
552 | * |
553 | * @return void |
554 | */ |
555 | private static function enqueue_preview_fonts() { |
556 | |
557 | $hiive_api_base = defined( 'NFD_DATA_WB_DEV_MODE' ) && NFD_DATA_WB_DEV_MODE |
558 | ? 'http://patterns-platform.test/api/v1' |
559 | : 'https://paterns.hiive.cloud/api/v1'; |
560 | |
561 | $font_pairs = get_option( 'nfd_module_onboarding_editor_fontpair' ); |
562 | $unique_fonts = array(); |
563 | |
564 | if ( $font_pairs && is_array( $font_pairs ) ) { |
565 | foreach ( $font_pairs as $font_pair ) { |
566 | if ( isset( $font_pair['font_heading_name'] ) ) { |
567 | $unique_fonts[] = $font_pair['font_heading_name']; |
568 | } |
569 | if ( isset( $font_pair['font_content_name'] ) ) { |
570 | $unique_fonts[] = $font_pair['font_content_name']; |
571 | } |
572 | } |
573 | } |
574 | |
575 | $unique_fonts = array_unique( $unique_fonts ); |
576 | |
577 | foreach ( $unique_fonts as $font_id ) { |
578 | if ( empty( $font_id ) ) { |
579 | continue; |
580 | } |
581 | |
582 | // Check if font data is already cached |
583 | $cache_key = 'nfd_font_data_' . sanitize_key( $font_id ); |
584 | $font_data = get_transient( $cache_key ); |
585 | |
586 | if ( false === $font_data ) { |
587 | // Fetch font data from Hiive API |
588 | $response = wp_remote_get( |
589 | $hiive_api_base . '/fonts/' . urlencode( sanitize_title( $font_id ) ), |
590 | array( |
591 | 'timeout' => 10, |
592 | 'headers' => array( |
593 | 'Accept' => 'application/json', |
594 | ), |
595 | ) |
596 | ); |
597 | |
598 | if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) === 200 ) { |
599 | $body = wp_remote_retrieve_body( $response ); |
600 | $font_data = json_decode( $body, true ); |
601 | |
602 | set_transient( $cache_key, $font_data, HOUR_IN_SECONDS ); |
603 | } |
604 | } |
605 | |
606 | // Enqueue the font if we have valid data |
607 | if ( $font_data && |
608 | isset( $font_data['wp_json']['fontFace'][0]['src'][0] ) && |
609 | isset( $font_data['wp_json']['name'] ) |
610 | ) { |
611 | $font_url = $font_data['wp_json']['fontFace'][0]['src'][0]; |
612 | $font_name = $font_data['wp_json']['name']; |
613 | $font_handle = 'nfd-font-' . sanitize_title( $font_id ); |
614 | |
615 | // Create CSS for the font-face declaration |
616 | $font_css = ''; |
617 | if ( isset( $font_data['wp_json']['fontFace'] ) && is_array( $font_data['wp_json']['fontFace'] ) ) { |
618 | foreach ( $font_data['wp_json']['fontFace'] as $font_face ) { |
619 | $font_css .= '@font-face {'; |
620 | $font_css .= 'font-family: "' . esc_attr( $font_face['fontFamily'] ) . '";'; |
621 | |
622 | if ( isset( $font_face['fontWeight'] ) ) { |
623 | $font_css .= 'font-weight: ' . esc_attr( $font_face['fontWeight'] ) . ';'; |
624 | } |
625 | |
626 | if ( isset( $font_face['fontStyle'] ) ) { |
627 | $font_css .= 'font-style: ' . esc_attr( $font_face['fontStyle'] ) . ';'; |
628 | } |
629 | |
630 | if ( isset( $font_face['fontStretch'] ) ) { |
631 | $font_css .= 'font-stretch: ' . esc_attr( $font_face['fontStretch'] ) . ';'; |
632 | } |
633 | |
634 | if ( isset( $font_face['src'] ) && is_array( $font_face['src'] ) ) { |
635 | $src_declarations = array(); |
636 | foreach ( $font_face['src'] as $src ) { |
637 | $src_declarations[] = 'url("' . esc_url( $src ) . '") format("woff2")'; |
638 | } |
639 | $font_css .= 'src: ' . implode( ', ', $src_declarations ) . ';'; |
640 | } |
641 | |
642 | $font_css .= 'font-display: swap;'; |
643 | $font_css .= '}'; |
644 | } |
645 | } |
646 | |
647 | // Register and enqueue the font style |
648 | \wp_register_style( $font_handle, false ); |
649 | \wp_enqueue_style( $font_handle ); |
650 | \wp_add_inline_style( $font_handle, $font_css ); |
651 | } |
652 | } |
653 | } |
654 | } // END /NewfoldLabs/WP/Module/Onboarding/Admin() |