header',
'body > footer',
'[role="banner"]',
'[role="contentinfo"]',
'#masthead',
'#colophon',
'.site-header',
'.site-footer',
'.ha-site-header',
'.ha-site-footer',
'.skip-link',
]
);
printf(
'' . "\n",
\Academy\Helper::esc_css( $hide ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped with esc_css().
);
}
/**
* Whether this request is a preview of an unsaved design.
*
* @return bool
*/
public static function is_preview() {
static $preview = null;
if ( null !== $preview ) {
return $preview;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$nonce = isset( $_GET[ self::QUERY ] ) ? sanitize_text_field( wp_unslash( $_GET[ self::QUERY ] ) ) : '';
if ( '' === $nonce || ! function_exists( 'wp_get_current_user' ) ) {
return false;
}
$preview = (bool) wp_verify_nonce( $nonce, self::NONCE ) && current_user_can( 'manage_options' );
return $preview;
}
/**
* Show the design being edited instead of the saved one.
*
* @param mixed $value Saved design.
* @return mixed
*/
public function use_draft( $value ) {
if ( ! self::is_preview() ) {
return $value;
}
$draft = get_transient( self::DRAFT . get_current_user_id() );
return is_array( $draft ) ? $draft : $value;
}
/**
* Other plugins pin banners, chat bubbles and pop-ups to the window. They
* are not part of the design being edited, so the preview puts them away —
* only floating boxes sitting directly on the page body, never anything
* inside the course area.
*
* @return void
*/
public function print_script() {
if ( ! self::is_preview() ) {
return;
}
// Links keep the preview in every view, with or without the theme's
// header and footer; putting other plugins' pop-ups away is only for
// the bare view.
self::keep_preview_script();
self::freeze_links_script();
if ( self::is_bare() ) {
self::overlay_script();
}
}
/**
* Carry the preview arguments onto the site's own links. The unsaved design
* is only shown on requests that hold the preview nonce, so following a link
* inside the preview (a dashboard menu item, say) would otherwise drop it and
* show the saved design instead of the one being edited.
*
* @return void
*/
private static function keep_preview_script() {
?>
Palette::sanitize( $palette ),
'sync' => (bool) $sync,
'display' => is_array( $display ) ? $display : null,
],
30 * MINUTE_IN_SECONDS
);
}
}
/**
* Keep the learn page options someone is editing, for the preview.
*
* @param array|null $learn Clean learn page options, or null to leave the draft.
* @return void
*/
public static function save_learn_draft( $learn ) {
if ( is_array( $learn ) ) {
set_transient( self::DRAFT . 'learn_' . get_current_user_id(), $learn, 30 * MINUTE_IN_SECONDS );
}
}
/**
* Keep the dashboard options someone is editing, for the preview.
*
* @param array|null $dashboard Clean dashboard options, or null to leave the draft.
* @return void
*/
public static function save_dashboard_draft( $dashboard ) {
if ( is_array( $dashboard ) ) {
set_transient( self::DRAFT . 'dashboard_' . get_current_user_id(), $dashboard, 30 * MINUTE_IN_SECONDS );
}
}
/**
* Show the dashboard options being edited in the preview.
*
* @return void
*/
public function use_dashboard_draft() {
if ( ! self::is_preview() ) {
return;
}
$draft = get_transient( self::DRAFT . 'dashboard_' . get_current_user_id() );
if ( is_array( $draft ) ) {
Palette::refresh_globals( \Academy\FrontendDashboard\Settings::to_settings( \Academy\FrontendDashboard\Settings::sanitize( $draft ) ) );
}
}
/**
* Show the learn page options being edited in the preview.
*
* @return void
*/
public function use_learn_draft() {
if ( ! self::is_preview() ) {
return;
}
$draft = get_transient( self::DRAFT . 'learn_' . get_current_user_id() );
if ( is_array( $draft ) ) {
Palette::refresh_globals( \Academy\LearnPage\Settings::to_settings( \Academy\LearnPage\Settings::sanitize( $draft ) ) );
}
}
/**
* Show the colours being edited in the preview: Academy's palette, and the
* theme's colours when they are set to follow it.
*
* @return void
*/
public function use_draft_palette() {
if ( ! self::is_preview() ) {
return;
}
$draft = get_transient( self::DRAFT . 'palette_' . get_current_user_id() );
if ( ! is_array( $draft ) || empty( $draft['palette'] ) ) {
return;
}
Palette::refresh_globals( $draft['palette'] );
if ( ! empty( $draft['display'] ) ) {
Palette::refresh_globals(
[
'course_archive_sidebar_position' => $draft['display']['sidebar'],
'is_enabled_course_single_enroll_count' => $draft['display']['enrollCount'],
'course_card_style' => $draft['display']['cardStyle'],
]
);
}
if ( ! empty( $draft['sync'] ) ) {
ThemeColors::preview_theme( Palette::brand( $draft['palette'] ) );
}
}
/**
* The pages the preview can show.
*
* @return array catalog and course URLs, ready to load in the preview.
*/
public static function urls() {
$course = get_posts(
[
'post_type' => 'academy_courses',
'post_status' => 'publish',
'posts_per_page' => 1,
'fields' => 'ids',
]
);
$nonce = wp_create_nonce( self::NONCE );
$catalog = (string) get_post_type_archive_link( 'academy_courses' );
$single = $course ? (string) get_permalink( $course[0] ) : '';
$learn = self::learn_urls( $course ? (int) $course[0] : 0 );
$dashboard = (int) \Academy\Helper::get_settings( 'frontend_dashboard_page' );
$dashboard = $dashboard ? (string) get_permalink( $dashboard ) : '';
return [
'learnBlocks' => $learn['blocks'] ? add_query_arg( self::QUERY, $nonce, $learn['blocks'] ) : '',
'learnReact' => $learn['react'] ? add_query_arg( self::QUERY, $nonce, $learn['react'] ) : '',
'dashboard' => $dashboard ? add_query_arg( self::QUERY, $nonce, $dashboard ) : '',
'catalog' => $catalog ? add_query_arg( self::QUERY, $nonce, $catalog ) : '',
'course' => $single ? add_query_arg( self::QUERY, $nonce, $single ) : '',
'chromeArg' => self::CHROME,
'hasCourse' => ! empty( $course ),
];
}
/**
* The first topic of a course, on each learn page.
*
* @param int $course_id Course ID.
* @return array blocks and react URLs.
*/
private static function learn_urls( $course_id ) {
$urls = [
'blocks' => '',
'react' => '',
];
if ( ! $course_id ) {
return $urls;
}
foreach ( (array) \Academy\Helper::get_course_curriculum( $course_id, false ) as $section ) {
foreach ( (array) ( $section['topics'] ?? [] ) as $topic ) {
$topic = 'sub-curriculum' === ( $topic['type'] ?? '' ) ? current( (array) ( $topic['topics'] ?? [] ) ) : $topic;
if ( is_array( $topic ) && ! empty( $topic['id'] ) ) {
$urls['blocks'] = \Academy\LearnPage\Data::link( $topic, $course_id );
$urls['react'] = add_query_arg( [ 'source' => 'curriculums' ], get_permalink( $course_id ) ) . '#/' . $topic['type'] . '/' . $topic['id'];
return $urls;
}
}
}
return $urls;
}
}