Initial commit of slide manager plugin
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: Slide Live Confirmation
|
||||
*
|
||||
* Page for ITC team to confirm a slide is live
|
||||
*
|
||||
* @package Hi_School_Slide_Manager
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 'Direct access forbidden.' );
|
||||
}
|
||||
|
||||
get_header();
|
||||
|
||||
$slide_id = isset( $_GET['slide_id'] ) ? intval( $_GET['slide_id'] ) : 0;
|
||||
// Note: We used a simplified token/hash check in the email link generation.
|
||||
// Ideally, we would verify that here.
|
||||
// For now, let's assume if they have the link, they can confirm (or we add basic checks).
|
||||
|
||||
$slide = get_post( $slide_id );
|
||||
$is_valid_slide = ( $slide && $slide->post_type === 'hssm_slide' );
|
||||
$confirmed = false;
|
||||
$error_message = '';
|
||||
|
||||
// Handle confirmation action
|
||||
if ( $is_valid_slide && isset( $_POST['confirm_live_action'] ) && $_POST['confirm_live_action'] === 'confirm' ) {
|
||||
if ( wp_verify_nonce( $_POST['hssm_live_nonce'], 'hssm_confirm_live_action' ) ) {
|
||||
// Trigger the final notification
|
||||
if ( class_exists( 'HSSM_Notifications' ) ) {
|
||||
$notifications = new HSSM_Notifications();
|
||||
$notifications->notify_all_confirmed_live( $slide_id );
|
||||
|
||||
// Mark as confirmed in metadata
|
||||
update_post_meta( $slide_id, '_hssm_live_confirmed', current_time( 'timestamp' ) );
|
||||
$confirmed = true;
|
||||
} else {
|
||||
$error_message = 'Notification system not available.';
|
||||
}
|
||||
} else {
|
||||
$error_message = 'Security check failed. Please refresh and try again.';
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div id="main-content">
|
||||
<div class="container-fluid">
|
||||
<div id="content-area" class="clearfix full-width">
|
||||
|
||||
<div class="hssm-confirmation-container" style="max-width: 600px; margin: 50px auto; padding: 30px; background: #fff; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); text-align: center;">
|
||||
|
||||
<?php if ( ! $is_valid_slide ) : ?>
|
||||
<div class="hssm-error">
|
||||
<h2>Invalid Slide</h2>
|
||||
<p>The slide you are trying to confirm could not be found.</p>
|
||||
<a href="<?php echo home_url(); ?>" class="button">Return Home</a>
|
||||
</div>
|
||||
|
||||
<?php elseif ( $confirmed ) : ?>
|
||||
<div class="hssm-success">
|
||||
<h2 style="color: #46b450;">Confirmation Sent!</h2>
|
||||
<p class="dashicons dashicons-yes-alt" style="font-size: 64px; width: 64px; height: 64px; color: #46b450;"></p>
|
||||
<p><strong>Thank you!</strong></p>
|
||||
<p>Notifications have been sent to the Editor and Creator confirming that "<?php echo esc_html( $slide->post_title ); ?>" is Live.</p>
|
||||
<a href="<?php echo home_url(); ?>" class="button">Return Home</a>
|
||||
</div>
|
||||
|
||||
<?php else : ?>
|
||||
<div class="hssm-confirm-form">
|
||||
<h2>Confirm Slide is Live</h2>
|
||||
|
||||
<?php if ( $error_message ) : ?>
|
||||
<div style="background: #f8d7da; color: #721c24; padding: 10px; margin-bottom: 20px; border-radius: 4px;">
|
||||
<?php echo esc_html( $error_message ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div style="margin: 30px 0; padding: 20px; background: #f9f9f9; border: 1px solid #eee; border-radius: 4px;">
|
||||
<h3 style="margin-top: 0;"><?php echo esc_html( $slide->post_title ); ?></h3>
|
||||
<?php
|
||||
$target_sites = wp_get_post_terms( $slide_id, 'hssm_site', array( 'fields' => 'names' ) );
|
||||
if ( ! empty( $target_sites ) ) {
|
||||
echo '<p><strong>Target Sites:</strong> ' . esc_html( implode( ', ', $target_sites ) ) . '</p>';
|
||||
}
|
||||
?>
|
||||
<div style="margin-top: 15px;">
|
||||
<img src="<?php echo get_the_post_thumbnail_url( $slide_id, 'medium' ); ?>" style="max-width: 100%; height: auto; border-radius: 4px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>I confirm that the slide <strong>"<?php echo esc_html( $slide->post_title ); ?>"</strong> is Live and displaying correctly on the target sites.</p>
|
||||
|
||||
<form method="post">
|
||||
<input type="hidden" name="confirm_live_action" value="confirm">
|
||||
<?php wp_nonce_field( 'hssm_confirm_live_action', 'hssm_live_nonce' ); ?>
|
||||
|
||||
<button type="submit" class="button" style="background-color: #46b450; color: #fff; border: none; padding: 15px 30px; font-size: 18px; cursor: pointer; border-radius: 4px;">
|
||||
<span class="dashicons dashicons-yes"></span> Confirm Slide is Live
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
@@ -0,0 +1,369 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: Slide Dashboard
|
||||
*
|
||||
* Divi full-width template for the slide management dashboard
|
||||
*
|
||||
* @package Hi_School_Slide_Manager
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 'Direct access forbidden.' );
|
||||
}
|
||||
|
||||
get_header(); ?>
|
||||
|
||||
<div id="main-content">
|
||||
<div class="container-fluid">
|
||||
<div id="content-area" class="clearfix full-width">
|
||||
|
||||
<!-- Custom Dashboard Header with Navigation -->
|
||||
<div class="hssm-header-bar">
|
||||
<div class="hssm-header-content">
|
||||
<div class="hssm-logo-section">
|
||||
<h1 class="hssm-site-title">
|
||||
Slide Management Dashboard
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="hssm-header-nav">
|
||||
<a href="<?php echo home_url(); ?>" class="hssm-nav-btn hssm-nav-home">
|
||||
<span class="dashicons dashicons-admin-home"></span>
|
||||
Home
|
||||
</a>
|
||||
<a href="<?php echo admin_url(); ?>" class="hssm-nav-btn hssm-nav-admin">
|
||||
<span class="dashicons dashicons-admin-generic"></span>
|
||||
Admin
|
||||
</a>
|
||||
<a href="<?php echo home_url( '/slide-preview/' ); ?>" class="hssm-nav-btn hssm-nav-preview" target="_blank">
|
||||
<span class="dashicons dashicons-visibility"></span>
|
||||
Slide Preview
|
||||
</a>
|
||||
<div class="hssm-user-menu">
|
||||
<span class="hssm-user-name">
|
||||
<?php echo esc_html( wp_get_current_user()->display_name ); ?>
|
||||
</span>
|
||||
<a href="<?php echo wp_logout_url( home_url() ); ?>" class="hssm-nav-btn hssm-nav-logout">
|
||||
<span class="dashicons dashicons-exit"></span>
|
||||
Logout
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Dashboard Content -->
|
||||
<div class="hssm-dashboard-main">
|
||||
|
||||
<!-- Messages Container -->
|
||||
<div id="hssm-messages" class="hssm-messages"></div>
|
||||
|
||||
<!-- Dashboard Navigation -->
|
||||
<div class="hssm-dashboard-nav">
|
||||
<ul class="hssm-nav-tabs">
|
||||
<li class="active">
|
||||
<a href="#create-slides" data-tab="create-slides">
|
||||
<span class="dashicons dashicons-plus-alt"></span>
|
||||
Create Slides
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#manage-slides" data-tab="manage-slides">
|
||||
<span class="dashicons dashicons-admin-page"></span>
|
||||
Manage Slides
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#analytics" data-tab="analytics">
|
||||
<span class="dashicons dashicons-chart-area"></span>
|
||||
Analytics
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#notifications" data-tab="notifications">
|
||||
<span class="dashicons dashicons-email"></span>
|
||||
Notifications
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Create Slides Tab -->
|
||||
<div id="create-slides" class="hssm-tab-content active">
|
||||
<div class="hssm-tab-header">
|
||||
<h2>Create New Slides</h2>
|
||||
<div class="hssm-tab-actions">
|
||||
<button id="add-slide-form" class="hssm-btn hssm-btn-primary" data-max-forms="5">
|
||||
<span class="dashicons dashicons-plus"></span> Add New Slide Form
|
||||
</button>
|
||||
<button id="import-slides" class="hssm-btn hssm-btn-secondary">
|
||||
<span class="dashicons dashicons-upload"></span> Import Slides
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="slide-forms-container">
|
||||
<!-- Initial slide form will be inserted here -->
|
||||
</div>
|
||||
|
||||
<div class="hssm-bulk-actions">
|
||||
<button id="save-all-slides" class="hssm-btn hssm-btn-success hssm-btn-large">
|
||||
<span class="dashicons dashicons-yes"></span> Save All Slides
|
||||
</button>
|
||||
<button id="save-draft-all" class="hssm-btn hssm-btn-secondary">
|
||||
<span class="dashicons dashicons-edit"></span> Save as Drafts
|
||||
</button>
|
||||
<button id="clear-all-forms" class="hssm-btn hssm-btn-outline">
|
||||
<span class="dashicons dashicons-trash"></span> Clear All Forms
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Manage Slides Tab -->
|
||||
<div id="manage-slides" class="hssm-tab-content">
|
||||
<div class="hssm-tab-header">
|
||||
<h2>Manage Existing Slides</h2>
|
||||
<div class="hssm-filters">
|
||||
<select id="filter-site" class="hssm-select">
|
||||
<option value="">All Sites</option>
|
||||
<option value="hi-school">Hi-School Pharmacy</option>
|
||||
<option value="one-stop">One Stop Hardware</option>
|
||||
<option value="ace">Ace Hardware</option>
|
||||
</select>
|
||||
<select id="filter-client" class="hssm-select">
|
||||
<option value="">All Clients</option>
|
||||
</select>
|
||||
<select id="filter-status" class="hssm-select">
|
||||
<option value="">All Status</option>
|
||||
<option value="publish">Published</option>
|
||||
<option value="draft">Draft</option>
|
||||
<option value="scheduled">Scheduled</option>
|
||||
</select>
|
||||
<button id="apply-filters" class="hssm-btn hssm-btn-primary">
|
||||
<span class="dashicons dashicons-filter"></span> Apply Filters
|
||||
</button>
|
||||
<button id="export-slides" class="hssm-btn hssm-btn-secondary">
|
||||
<span class="dashicons dashicons-download"></span> Export
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="slides-list" class="hssm-slides-list">
|
||||
<!-- Existing slides will be loaded here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Analytics Tab -->
|
||||
<div id="analytics" class="hssm-tab-content">
|
||||
<div class="hssm-tab-header">
|
||||
<h2>Slide Analytics</h2>
|
||||
<div class="hssm-analytics-controls">
|
||||
<select id="analytics-timeframe" class="hssm-select">
|
||||
<option value="7">Last 7 Days</option>
|
||||
<option value="30">Last 30 Days</option>
|
||||
<option value="90">Last 90 Days</option>
|
||||
</select>
|
||||
<button id="generate-report" class="hssm-btn hssm-btn-primary">
|
||||
<span class="dashicons dashicons-chart-area"></span> Generate Report
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="analytics-content" class="hssm-analytics-content">
|
||||
<div class="hssm-analytics-cards">
|
||||
<div class="hssm-analytics-card">
|
||||
<h3>Total Slides Created</h3>
|
||||
<div class="hssm-analytics-number">--</div>
|
||||
</div>
|
||||
<div class="hssm-analytics-card">
|
||||
<h3>Active Campaigns</h3>
|
||||
<div class="hssm-analytics-number">--</div>
|
||||
</div>
|
||||
<div class="hssm-analytics-card">
|
||||
<h3>Scheduled Slides</h3>
|
||||
<div class="hssm-analytics-number">--</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notifications Tab -->
|
||||
<div id="notifications" class="hssm-tab-content">
|
||||
<div class="hssm-tab-header">
|
||||
<h2>Notification Settings</h2>
|
||||
</div>
|
||||
|
||||
<div class="hssm-notifications-settings">
|
||||
<form id="notification-settings-form">
|
||||
<div class="hssm-form-section">
|
||||
<h3>Editor Notifications</h3>
|
||||
<p class="description">Recipients for slide scheduling and approval requests.</p>
|
||||
<div class="hssm-field">
|
||||
<label for="editor_emails">Editor Email(s)</label>
|
||||
<textarea id="editor_emails" name="editor_emails" class="hssm-textarea" rows="3" placeholder="Enter email addresses, separated by commas or new lines"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hssm-form-section">
|
||||
<h3>I.T.C.Guys Notifications</h3>
|
||||
<p class="description">Recipients for LIVE confirmation checks.</p>
|
||||
<div class="hssm-field">
|
||||
<label for="itc_emails">I.T.C.Guys Email(s)</label>
|
||||
<textarea id="itc_emails" name="itc_emails" class="hssm-textarea" rows="3" placeholder="Enter email addresses, separated by commas or new lines"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hssm-form-actions">
|
||||
<button type="submit" id="save-notifications" class="hssm-btn hssm-btn-primary">
|
||||
<span class="dashicons dashicons-saved"></span> Save Settings
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- .hssm-dashboard-main -->
|
||||
</div> <!-- #content-area -->
|
||||
</div> <!-- .container-fluid -->
|
||||
</div> <!-- #main-content -->
|
||||
|
||||
<!-- Slide Form Template (Hidden) -->
|
||||
<script type="text/html" id="slide-form-template">
|
||||
<div class="hssm-slide-form" data-form-id="{{form_id}}">
|
||||
<div class="hssm-form-header">
|
||||
<h3><strong>New Slide #{{form_number}}</strong></h3>
|
||||
<button type="button" class="hssm-remove-form" aria-label="Remove this form">
|
||||
<span class="dashicons dashicons-no"> test</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="hssm-form-grid">
|
||||
<!-- Left Column: Basic Information -->
|
||||
<div class="hssm-form-section hssm-form-basic">
|
||||
<h4>Basic Information</h4>
|
||||
|
||||
<div class="hssm-field-row">
|
||||
<div class="hssm-field">
|
||||
<label for="title_{{form_id}}">Title *</label>
|
||||
<input type="text" id="title_{{form_id}}" name="title" class="hssm-input" required>
|
||||
</div>
|
||||
<div class="hssm-field">
|
||||
<label for="client_{{form_id}}">Client</label>
|
||||
<input type="text" id="client_{{form_id}}" name="client" class="hssm-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hssm-field">
|
||||
<label for="subtitle_{{form_id}}">Subtitle</label>
|
||||
<input type="text" id="subtitle_{{form_id}}" name="subtitle" class="hssm-input">
|
||||
</div>
|
||||
|
||||
<div class="hssm-field">
|
||||
<label for="content_{{form_id}}">Content</label>
|
||||
<textarea id="content_{{form_id}}" name="content" class="hssm-textarea" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Center Column: Image & Buttons -->
|
||||
<div class="hssm-form-section hssm-form-media">
|
||||
<h4>Background Image</h4>
|
||||
|
||||
<div class="hssm-image-upload-compact">
|
||||
<div class="hssm-image-preview-small" id="image_preview_{{form_id}}">
|
||||
<span class="hssm-placeholder">Click to upload</span>
|
||||
</div>
|
||||
<div class="hssm-image-controls">
|
||||
<input type="file" id="image_upload_{{form_id}}" name="background_image" accept="image/*" style="display: none;">
|
||||
<input type="hidden" id="image_id_{{form_id}}" name="featured_image_id" value="">
|
||||
<button type="button" class="hssm-btn hssm-btn-small hssm-upload-btn" data-target="{{form_id}}">
|
||||
Choose Image
|
||||
</button>
|
||||
<button type="button" class="hssm-btn hssm-btn-small hssm-btn-text hssm-remove-image" data-target="{{form_id}}" style="display: none;">
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>Call-to-Action Buttons</h4>
|
||||
<div class="hssm-buttons-container-compact" id="buttons_{{form_id}}">
|
||||
<div class="hssm-button-row-compact">
|
||||
<input type="text" name="buttons[0][text]" placeholder="Button Text" class="hssm-input-small">
|
||||
<input type="url" name="buttons[0][url]" placeholder="Button URL" class="hssm-input-small">
|
||||
<button type="button" class="hssm-btn hssm-btn-tiny hssm-remove-button">×</button>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="hssm-btn hssm-btn-small hssm-add-button" data-form="{{form_id}}">
|
||||
<span class="dashicons dashicons-plus"></span> Add Button
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Targeting & Scheduling -->
|
||||
<div class="hssm-form-section hssm-form-targeting">
|
||||
<h4>Targeting & Scheduling</h4>
|
||||
|
||||
<div class="hssm-field">
|
||||
<label>Target Sites *</label>
|
||||
<div class="hssm-checkboxes-compact">
|
||||
<label class="hssm-checkbox-compact">
|
||||
<input type="checkbox" name="target_sites[]" value="hi-school">
|
||||
Hi-School Pharmacy
|
||||
</label>
|
||||
<label class="hssm-checkbox-compact">
|
||||
<input type="checkbox" name="target_sites[]" value="one-stop">
|
||||
One Stop Hardware
|
||||
</label>
|
||||
<label class="hssm-checkbox-compact">
|
||||
<input type="checkbox" name="target_sites[]" value="ace">
|
||||
Ace Hardware
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hssm-field" style="margin-top: 15px;">
|
||||
<label class="hssm-checkbox-compact hssm-hide-text-option">
|
||||
<input type="checkbox" name="hide_all_text" value="1">
|
||||
Hide All Text (Image Only)
|
||||
<small style="display: block; color: #666; margin-top: 5px;">Check this to display only the image without any overlay text</small>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="hssm-field-row">
|
||||
<div class="hssm-field">
|
||||
<label for="start_date_{{form_id}}">Start Date</label>
|
||||
<input type="date" id="start_date_{{form_id}}" name="start_date" class="hssm-input">
|
||||
</div>
|
||||
<div class="hssm-field">
|
||||
<label for="end_date_{{form_id}}">End Date</label>
|
||||
<input type="date" id="end_date_{{form_id}}" name="end_date" class="hssm-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hssm-field-row">
|
||||
<div class="hssm-field">
|
||||
<label for="order_{{form_id}}">Display Order</label>
|
||||
<input type="number" id="order_{{form_id}}" name="order" class="hssm-input" value="0" min="0">
|
||||
</div>
|
||||
<div class="hssm-field">
|
||||
<!-- Spacer for alignment -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hssm-form-actions">
|
||||
<button type="button" class="hssm-btn hssm-btn-secondary hssm-schedule-slide" data-form="{{form_id}}">
|
||||
<span class="dashicons dashicons-calendar-alt"></span> Schedule for Approval
|
||||
</button>
|
||||
<button type="button" class="hssm-btn hssm-btn-primary hssm-publish-slide" data-form="{{form_id}}">
|
||||
<span class="dashicons dashicons-yes"></span> Publish Immediately
|
||||
</button>
|
||||
<button type="button" class="hssm-btn hssm-btn-outline hssm-preview-slide" data-form="{{form_id}}">
|
||||
<span class="dashicons dashicons-visibility"></span> Preview
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
@@ -0,0 +1,498 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: Slide Preview
|
||||
* Front-end preview page for scheduled slides.
|
||||
* Can be used as a Divi page with a header/loop module,
|
||||
* while this template renders a canonical preview dashboard underneath.
|
||||
*
|
||||
* URL parameters:
|
||||
* ?hssm_date=YYYY-MM-DD
|
||||
* ?hssm_site=site-slug (matches hssm_site taxonomy slug)
|
||||
*
|
||||
* @package Hi_School_Slide_Manager
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 'Direct access forbidden.' );
|
||||
}
|
||||
|
||||
get_header();
|
||||
|
||||
/**
|
||||
* Inject dynamic CSS for carousel slide backgrounds.
|
||||
* Divi 5 group carousels use dynamic loop items.
|
||||
* We force the backgrounds based on our preview query.
|
||||
*/
|
||||
/**
|
||||
* Pass slide background data to the frontend.
|
||||
* We use JavaScript to apply backgrounds because Divi 5's loop indices
|
||||
* and cloning can make CSS targeting unreliable on the preview page.
|
||||
*/
|
||||
add_action( 'wp_footer', function() {
|
||||
$request = hssm_get_preview_request();
|
||||
// Get all possible slides for this day
|
||||
$slides = hssm_get_preview_slides_for_date( $request['date'], $request['site_slug'] );
|
||||
|
||||
if ( empty( $slides ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$bg_data = array();
|
||||
foreach ( $slides as $slide ) {
|
||||
$img_url = get_the_post_thumbnail_url( $slide->ID, 'full' );
|
||||
if ( $img_url ) {
|
||||
// We use the title to match the slide on the frontend
|
||||
$bg_data[] = array(
|
||||
'title' => html_entity_decode(get_the_title($slide)),
|
||||
'bg' => $img_url
|
||||
);
|
||||
}
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
(function($) {
|
||||
$(document).ready(function() {
|
||||
var bgData = <?php echo json_encode($bg_data); ?>;
|
||||
|
||||
function fixCarouselBgs() {
|
||||
$('.et_pb_group_carousel_slide').each(function() {
|
||||
var $slide = $(this);
|
||||
var slideText = $slide.find('.et_pb_module_header').first().text().trim();
|
||||
|
||||
if (!slideText) return;
|
||||
|
||||
$.each(bgData, function(i, item) {
|
||||
// Check if the slide heading contains the slide title (or vice versa)
|
||||
if (slideText.indexOf(item.title) !== -1 || item.title.indexOf(slideText) !== -1) {
|
||||
// Apply background to the inner group module
|
||||
$slide.find('.et_pb_group').first().css({
|
||||
'background-image': 'url(' + item.bg + ')',
|
||||
'background-size': 'cover',
|
||||
'background-position': 'center',
|
||||
'background-repeat': 'no-repeat'
|
||||
}).addClass('hssm-bg-fixed');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Run immediately and also on a interval to catch Divi 5's dynamic rendering/cloning
|
||||
fixCarouselBgs();
|
||||
setInterval(fixCarouselBgs, 1000);
|
||||
|
||||
// Also run when carousel might have re-initialized
|
||||
$(window).on('resize', fixCarouselBgs);
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
<style>
|
||||
/* Ensure the fixed backgrounds are visible */
|
||||
.hssm-bg-fixed {
|
||||
background-size: cover !important;
|
||||
background-position: center !important;
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
}, 100 );
|
||||
|
||||
/**
|
||||
* Get normalized preview inputs from the URL with sane defaults.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function hssm_get_preview_request() {
|
||||
$today = new DateTime( current_time( 'Y-m-d' ) );
|
||||
|
||||
$date_param = isset( $_GET['hssm_date'] ) ? sanitize_text_field( wp_unslash( $_GET['hssm_date'] ) ) : $today->format( 'Y-m-d' );
|
||||
$site_param = isset( $_GET['hssm_site'] ) ? sanitize_text_field( wp_unslash( $_GET['hssm_site'] ) ) : '';
|
||||
$show_past = isset( $_GET['hssm_past'] ) && $_GET['hssm_past'] === '1';
|
||||
|
||||
// Validate date (YYYY-MM-DD)
|
||||
$date_obj = DateTime::createFromFormat( 'Y-m-d', $date_param );
|
||||
if ( ! $date_obj ) {
|
||||
$date_obj = $today;
|
||||
}
|
||||
|
||||
return array(
|
||||
'date' => $date_obj->format( 'Y-m-d' ),
|
||||
'site_slug' => $site_param,
|
||||
'show_past' => $show_past,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available target sites from the hssm_site taxonomy.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function hssm_get_preview_sites() {
|
||||
// We specifically want only these three sites to appear, to match the main dashboard.
|
||||
// Also helps avoid duplicates if the taxonomy has similar terms.
|
||||
$allowed_slugs = array( 'hi-school', 'ace', 'one-stop' );
|
||||
|
||||
$terms = get_terms(
|
||||
array(
|
||||
'taxonomy' => HSSM_Slides_CPT::SITE_TAXONOMY,
|
||||
'hide_empty' => false,
|
||||
'slug' => $allowed_slugs,
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_wp_error( $terms ) || empty( $terms ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$sites = array();
|
||||
$added_slugs = array();
|
||||
|
||||
foreach ( $terms as $term ) {
|
||||
// Double check against duplicates just in case
|
||||
if ( in_array( $term->slug, $added_slugs, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sites[] = array(
|
||||
'slug' => $term->slug,
|
||||
'name' => $term->name,
|
||||
);
|
||||
$added_slugs[] = $term->slug;
|
||||
}
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get calendar events (start/end dates) for highlighting.
|
||||
*
|
||||
* @param string $site_slug Optional site slug to filter by.
|
||||
* @return array Map of date => ['start', 'end']
|
||||
*/
|
||||
function hssm_get_calendar_events( $site_slug = '' ) {
|
||||
$meta_query = array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => '_hssm_start_date',
|
||||
'compare' => 'EXISTS',
|
||||
),
|
||||
array(
|
||||
'key' => '_hssm_end_date',
|
||||
'compare' => 'EXISTS',
|
||||
),
|
||||
);
|
||||
|
||||
$tax_query = array();
|
||||
|
||||
if ( ! empty( $site_slug ) ) {
|
||||
$site_term = get_term_by( 'slug', $site_slug, HSSM_Slides_CPT::SITE_TAXONOMY );
|
||||
if ( $site_term && ! is_wp_error( $site_term ) ) {
|
||||
$tax_query[] = array(
|
||||
'taxonomy' => HSSM_Slides_CPT::SITE_TAXONOMY,
|
||||
'field' => 'term_id',
|
||||
'terms' => $site_term->term_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $tax_query ) > 1 ) {
|
||||
$tax_query['relation'] = 'AND';
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'post_type' => HSSM_Slides_CPT::POST_TYPE,
|
||||
'post_status' => array( 'publish', 'future', 'pending' ),
|
||||
'posts_per_page' => -1,
|
||||
'fields' => 'ids',
|
||||
'meta_query' => $meta_query,
|
||||
);
|
||||
|
||||
if ( ! empty( $tax_query ) ) {
|
||||
$args['tax_query'] = $tax_query;
|
||||
}
|
||||
|
||||
$slide_ids = get_posts( $args );
|
||||
$events = array();
|
||||
|
||||
foreach ( $slide_ids as $slide_id ) {
|
||||
$start_raw = get_post_meta( $slide_id, '_hssm_start_date', true );
|
||||
$end_raw = get_post_meta( $slide_id, '_hssm_end_date', true );
|
||||
|
||||
if ( ! empty( $start_raw ) ) {
|
||||
$d = substr( $start_raw, 0, 10 );
|
||||
if ( ! isset( $events[ $d ] ) ) $events[ $d ] = array();
|
||||
if ( ! in_array( 'start', $events[ $d ], true ) ) $events[ $d ][] = 'start';
|
||||
}
|
||||
|
||||
if ( ! empty( $end_raw ) ) {
|
||||
$d = substr( $end_raw, 0, 10 );
|
||||
if ( ! isset( $events[ $d ] ) ) $events[ $d ] = array();
|
||||
if ( ! in_array( 'end', $events[ $d ], true ) ) $events[ $d ][] = 'end';
|
||||
}
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query slides for a given date and optional site.
|
||||
*
|
||||
* @param string $date Date in YYYY-MM-DD format.
|
||||
* @param string $site_slug Optional site slug.
|
||||
* @return WP_Post[]
|
||||
*/
|
||||
function hssm_get_preview_slides_for_date( $date, $site_slug = '' ) {
|
||||
$meta_query = array(
|
||||
'relation' => 'AND',
|
||||
array(
|
||||
'key' => '_hssm_start_date',
|
||||
'value' => $date,
|
||||
'compare' => '<=',
|
||||
),
|
||||
array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => '_hssm_end_date',
|
||||
'value' => $date,
|
||||
'compare' => '>=',
|
||||
),
|
||||
array(
|
||||
'key' => '_hssm_end_date',
|
||||
'compare' => 'NOT EXISTS',
|
||||
),
|
||||
array(
|
||||
'key' => '_hssm_end_date',
|
||||
'value' => '',
|
||||
'compare' => '=',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$tax_query = array();
|
||||
|
||||
if ( ! empty( $site_slug ) ) {
|
||||
$site_term = get_term_by( 'slug', $site_slug, HSSM_Slides_CPT::SITE_TAXONOMY );
|
||||
if ( $site_term && ! is_wp_error( $site_term ) ) {
|
||||
$tax_query[] = array(
|
||||
'taxonomy' => HSSM_Slides_CPT::SITE_TAXONOMY,
|
||||
'field' => 'term_id',
|
||||
'terms' => $site_term->term_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $tax_query ) > 1 ) {
|
||||
$tax_query['relation'] = 'AND';
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'post_type' => HSSM_Slides_CPT::POST_TYPE,
|
||||
'post_status' => array( 'publish', 'future', 'pending' ),
|
||||
'posts_per_page' => -1,
|
||||
'orderby' => 'meta_value_num',
|
||||
'meta_key' => '_hssm_order',
|
||||
'order' => 'ASC',
|
||||
'meta_query' => $meta_query,
|
||||
);
|
||||
|
||||
if ( ! empty( $tax_query ) ) {
|
||||
$args['tax_query'] = $tax_query;
|
||||
}
|
||||
|
||||
return get_posts( $args );
|
||||
}
|
||||
|
||||
$request = hssm_get_preview_request();
|
||||
$sites = hssm_get_preview_sites();
|
||||
$events = hssm_get_calendar_events( $request['site_slug'] );
|
||||
|
||||
$current_site_name = '';
|
||||
if ( ! empty( $request['site_slug'] ) ) {
|
||||
foreach ( $sites as $site ) {
|
||||
if ( $site['slug'] === $request['site_slug'] ) {
|
||||
$current_site_name = $site['name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $current_site_name ) && ! empty( $sites ) ) {
|
||||
$current_site_name = __( 'All Sites', 'hi-school-slide-manager' );
|
||||
}
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
var hssmEvents = <?php echo json_encode( $events ); ?>;
|
||||
</script>
|
||||
|
||||
<div id="main-content">
|
||||
<div class="container-fluid">
|
||||
<div id="content-area" class="clearfix full-width">
|
||||
|
||||
<?php
|
||||
// Render the live slider preview using the modular shortcode
|
||||
echo do_shortcode( sprintf(
|
||||
'[hssm_slider site="%s" date="%s"]',
|
||||
esc_attr( $request['site_slug'] ),
|
||||
esc_attr( $request['date'] )
|
||||
) );
|
||||
|
||||
// Normal page content (Divi builder, header, etc.).
|
||||
if ( have_posts() ) :
|
||||
while ( have_posts() ) :
|
||||
the_post();
|
||||
// the_content(); // We might not want the_content if we're replacing it with the shortcode,
|
||||
// but let's keep it in case there's other content.
|
||||
endwhile;
|
||||
endif;
|
||||
?>
|
||||
|
||||
<div class="hssm-dashboard-main hssm-mt-20">
|
||||
<div class="hssm-tab-header">
|
||||
<h2>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: 1: date, 2: site name */
|
||||
esc_html__( 'Slide Preview for %1$s (%2$s)', 'hi-school-slide-manager' ),
|
||||
esc_html( date_i18n( get_option( 'date_format' ), strtotime( $request['date'] ) ) ),
|
||||
esc_html( $current_site_name )
|
||||
);
|
||||
?>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<form method="get" class="hssm-filters hssm-mt-20">
|
||||
<div>
|
||||
<label for="hssm_date"><strong><?php esc_html_e( 'Preview Date', 'hi-school-slide-manager' ); ?></strong></label><br>
|
||||
<input type="text" id="hssm_date" name="hssm_date" class="hssm-input" value="<?php echo esc_attr( $request['date'] ); ?>" autocomplete="off" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="hssm_site"><strong><?php esc_html_e( 'Site', 'hi-school-slide-manager' ); ?></strong></label><br>
|
||||
<select id="hssm_site" name="hssm_site" class="hssm-select">
|
||||
<option value=""><?php esc_html_e( 'All Sites', 'hi-school-slide-manager' ); ?></option>
|
||||
<?php foreach ( $sites as $site ) : ?>
|
||||
<option value="<?php echo esc_attr( $site['slug'] ); ?>" <?php selected( $site['slug'], $request['site_slug'] ); ?>>
|
||||
<?php echo esc_html( $site['name'] ); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label> </label><br>
|
||||
<label class="hssm-checkbox-label" style="display: inline-block; margin-top: 5px;">
|
||||
<input type="checkbox" name="hssm_past" value="1" <?php checked( $request['show_past'] ); ?>>
|
||||
<?php esc_html_e( 'Show Previously Published', 'hi-school-slide-manager' ); ?>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label> </label><br>
|
||||
<button type="submit" class="hssm-btn hssm-btn-primary">
|
||||
<span class="dashicons dashicons-filter"></span>
|
||||
<?php esc_html_e( 'Apply Filters', 'hi-school-slide-manager' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="hssm-slides-list hssm-mt-20">
|
||||
<?php
|
||||
$slides = hssm_get_preview_slides_for_date( $request['date'], $request['site_slug'] );
|
||||
|
||||
if ( empty( $slides ) ) :
|
||||
?>
|
||||
<div class="hssm-empty-state">
|
||||
<div class="hssm-empty-icon dashicons dashicons-visibility"></div>
|
||||
<h3><?php esc_html_e( 'No slides scheduled for this date/site.', 'hi-school-slide-manager' ); ?></h3>
|
||||
<p><?php esc_html_e( 'Choose another date or site above to see upcoming slides.', 'hi-school-slide-manager' ); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
else :
|
||||
foreach ( $slides as $slide ) :
|
||||
$subtitle = get_post_meta( $slide->ID, '_hssm_subtitle', true );
|
||||
$start_date = get_post_meta( $slide->ID, '_hssm_start_date', true );
|
||||
$end_date = get_post_meta( $slide->ID, '_hssm_end_date', true );
|
||||
$sites_terms = wp_get_post_terms( $slide->ID, HSSM_Slides_CPT::SITE_TAXONOMY );
|
||||
$site_names = array();
|
||||
if ( ! is_wp_error( $sites_terms ) && ! empty( $sites_terms ) ) {
|
||||
foreach ( $sites_terms as $term ) {
|
||||
$site_names[] = $term->name;
|
||||
}
|
||||
}
|
||||
$thumb_url = get_the_post_thumbnail_url( $slide->ID, 'thumbnail' );
|
||||
?>
|
||||
<div class="hssm-slide-item">
|
||||
<div class="hssm-slide-info">
|
||||
<div class="hssm-list-slide-title">
|
||||
<?php echo esc_html( get_the_title( $slide ) ); ?>
|
||||
</div>
|
||||
<?php if ( ! empty( $subtitle ) ) : ?>
|
||||
<div class="hssm-slide-subtitle">
|
||||
<?php echo esc_html( $subtitle ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="hssm-slide-meta">
|
||||
<?php if ( $slide->post_status === 'pending' ) : ?>
|
||||
<span class="hssm-status-badge hssm-status-pending"><?php esc_html_e( 'Pending Approval', 'hi-school-slide-manager' ); ?></span><br>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $site_names ) ) : ?>
|
||||
<span><?php esc_html_e( 'Sites:', 'hi-school-slide-manager' ); ?> <?php echo esc_html( implode( ', ', $site_names ) ); ?></span><br>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $start_date ) ) : ?>
|
||||
<span>
|
||||
<?php esc_html_e( 'Start:', 'hi-school-slide-manager' ); ?>
|
||||
<?php echo esc_html( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $start_date ) ) ); ?>
|
||||
</span><br>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $end_date ) ) : ?>
|
||||
<span>
|
||||
<?php esc_html_e( 'End:', 'hi-school-slide-manager' ); ?>
|
||||
<?php echo esc_html( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $end_date ) ) ); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( $slide->post_status === 'pending' && current_user_can( 'edit_others_posts' ) ) : ?>
|
||||
<div class="hssm-slide-actions hssm-mt-10">
|
||||
<button type="button" class="hssm-btn hssm-btn-success hssm-approve-slide" data-id="<?php echo esc_attr( $slide->ID ); ?>">
|
||||
<span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Approve Slide', 'hi-school-slide-manager' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( $thumb_url ) : ?>
|
||||
<div class="hssm-slide-thumbnail" style="background-image:url('<?php echo esc_url( $thumb_url ); ?>');">
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
endforeach;
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="hssm-preview-actions hssm-mt-20" style="text-align: center; margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee;">
|
||||
<button id="email-preview" class="hssm-btn hssm-btn-secondary">
|
||||
<span class="dashicons dashicons-email"></span> <?php esc_html_e( 'Email Preview', 'hi-school-slide-manager' ); ?>
|
||||
</button>
|
||||
<button id="download-screenshot" class="hssm-btn hssm-btn-secondary">
|
||||
<span class="dashicons dashicons-download"></span> <?php esc_html_e( 'Download Screenshot', 'hi-school-slide-manager' ); ?>
|
||||
</button>
|
||||
<button id="copy-preview-link" class="hssm-btn hssm-btn-secondary">
|
||||
<span class="dashicons dashicons-admin-links"></span> <?php esc_html_e( 'Copy Link', 'hi-school-slide-manager' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- #content-area -->
|
||||
</div><!-- .container-fluid -->
|
||||
</div><!-- #main-content -->
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
|
||||
Reference in New Issue
Block a user