999c2cc866
dry up redundencies
946 lines
40 KiB
PHP
946 lines
40 KiB
PHP
<?php
|
|
/**
|
|
* HSSM Slides Custom Post Type
|
|
*
|
|
* Manages the custom post type for slides with detailed fields for multi-site management
|
|
*
|
|
* @package Hi_School_Slide_Manager
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit( 'Direct access forbidden.' );
|
|
}
|
|
|
|
/**
|
|
* HSSM Slides CPT Class
|
|
*
|
|
* Handles the slides custom post type and its meta fields
|
|
*/
|
|
class HSSM_Slides_CPT {
|
|
|
|
/**
|
|
* Post type slug
|
|
*
|
|
* @since 1.0.0
|
|
* @var string
|
|
*/
|
|
const POST_TYPE = 'hssm_slide';
|
|
|
|
/**
|
|
* Site taxonomy slug
|
|
*
|
|
* @since 1.0.0
|
|
* @var string
|
|
*/
|
|
const SITE_TAXONOMY = 'hssm_site';
|
|
|
|
/**
|
|
* Client taxonomy slug
|
|
*
|
|
* @since 1.0.0
|
|
* @var string
|
|
*/
|
|
const CLIENT_TAXONOMY = 'hssm_client';
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function __construct() {
|
|
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
|
|
add_action( 'save_post', array( $this, 'save_meta_fields' ) );
|
|
add_filter( 'manage_' . self::POST_TYPE . '_posts_columns', array( $this, 'add_custom_columns' ) );
|
|
add_action( 'manage_' . self::POST_TYPE . '_posts_custom_column', array( $this, 'custom_column_content' ), 10, 2 );
|
|
|
|
// Add drag-and-drop ordering functionality
|
|
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
|
|
add_action( 'wp_ajax_hssm_update_slide_order', array( $this, 'ajax_update_slide_order' ) );
|
|
}
|
|
|
|
/**
|
|
* Register the slides custom post type
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function register() {
|
|
$labels = array(
|
|
'name' => _x( 'Slides', 'Post type general name', 'hi-school-slide-manager' ),
|
|
'singular_name' => _x( 'Slide', 'Post type singular name', 'hi-school-slide-manager' ),
|
|
'menu_name' => _x( 'Slides', 'Admin Menu text', 'hi-school-slide-manager' ),
|
|
'name_admin_bar' => _x( 'Slide', 'Add New on Toolbar', 'hi-school-slide-manager' ),
|
|
'add_new' => __( 'Add New', 'hi-school-slide-manager' ),
|
|
'add_new_item' => __( 'Add New Slide', 'hi-school-slide-manager' ),
|
|
'new_item' => __( 'New Slide', 'hi-school-slide-manager' ),
|
|
'edit_item' => __( 'Edit Slide', 'hi-school-slide-manager' ),
|
|
'view_item' => __( 'View Slide', 'hi-school-slide-manager' ),
|
|
'all_items' => __( 'All Slides', 'hi-school-slide-manager' ),
|
|
'search_items' => __( 'Search Slides', 'hi-school-slide-manager' ),
|
|
'parent_item_colon' => __( 'Parent Slides:', 'hi-school-slide-manager' ),
|
|
'not_found' => __( 'No slides found.', 'hi-school-slide-manager' ),
|
|
'not_found_in_trash' => __( 'No slides found in Trash.', 'hi-school-slide-manager' ),
|
|
'featured_image' => _x( 'Background Image', 'Overrides the "Featured Image" phrase', 'hi-school-slide-manager' ),
|
|
'set_featured_image' => _x( 'Set background image', 'Overrides the "Set featured image" phrase', 'hi-school-slide-manager' ),
|
|
'remove_featured_image' => _x( 'Remove background image', 'Overrides the "Remove featured image" phrase', 'hi-school-slide-manager' ),
|
|
'use_featured_image' => _x( 'Use as background image', 'Overrides the "Use as featured image" phrase', 'hi-school-slide-manager' ),
|
|
'archives' => _x( 'Slide archives', 'The post type archive label used in nav menus', 'hi-school-slide-manager' ),
|
|
'insert_into_item' => _x( 'Insert into slide', 'Overrides the "Insert into post" phrase', 'hi-school-slide-manager' ),
|
|
'uploaded_to_this_item' => _x( 'Uploaded to this slide', 'Overrides the "Uploaded to this post" phrase', 'hi-school-slide-manager' ),
|
|
'filter_items_list' => _x( 'Filter slides list', 'Screen reader text for the filter links', 'hi-school-slide-manager' ),
|
|
'items_list_navigation' => _x( 'Slides list navigation', 'Screen reader text for the pagination', 'hi-school-slide-manager' ),
|
|
'items_list' => _x( 'Slides list', 'Screen reader text for the items list', 'hi-school-slide-manager' ),
|
|
);
|
|
|
|
$args = array(
|
|
'labels' => $labels,
|
|
'public' => true,
|
|
'publicly_queryable' => true,
|
|
'show_ui' => true,
|
|
'show_in_menu' => true,
|
|
'query_var' => true,
|
|
'rewrite' => array( 'slug' => 'slide' ),
|
|
'capability_type' => 'post',
|
|
'has_archive' => true,
|
|
'hierarchical' => false,
|
|
'menu_position' => 20,
|
|
'menu_icon' => 'dashicons-slides',
|
|
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
|
|
'show_in_rest' => true,
|
|
'rest_base' => 'slides',
|
|
'rest_controller_class' => 'HSSM_REST_Slides_Controller',
|
|
);
|
|
|
|
register_post_type( self::POST_TYPE, $args );
|
|
}
|
|
|
|
/**
|
|
* Register custom taxonomies
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function register_taxonomies() {
|
|
// Site taxonomy for organizing slides by target site
|
|
$site_labels = array(
|
|
'name' => _x( 'Target Sites', 'taxonomy general name', 'hi-school-slide-manager' ),
|
|
'singular_name' => _x( 'Target Site', 'taxonomy singular name', 'hi-school-slide-manager' ),
|
|
'search_items' => __( 'Search Sites', 'hi-school-slide-manager' ),
|
|
'all_items' => __( 'All Sites', 'hi-school-slide-manager' ),
|
|
'parent_item' => __( 'Parent Site', 'hi-school-slide-manager' ),
|
|
'parent_item_colon' => __( 'Parent Site:', 'hi-school-slide-manager' ),
|
|
'edit_item' => __( 'Edit Site', 'hi-school-slide-manager' ),
|
|
'update_item' => __( 'Update Site', 'hi-school-slide-manager' ),
|
|
'add_new_item' => __( 'Add New Site', 'hi-school-slide-manager' ),
|
|
'new_item_name' => __( 'New Site Name', 'hi-school-slide-manager' ),
|
|
'menu_name' => __( 'Target Sites', 'hi-school-slide-manager' ),
|
|
);
|
|
|
|
$site_args = array(
|
|
'hierarchical' => false,
|
|
'labels' => $site_labels,
|
|
'show_ui' => true,
|
|
'show_admin_column' => true,
|
|
'query_var' => true,
|
|
'rewrite' => array( 'slug' => 'slide-site' ),
|
|
'show_in_rest' => true,
|
|
);
|
|
|
|
register_taxonomy( self::SITE_TAXONOMY, array( self::POST_TYPE ), $site_args );
|
|
|
|
// Client taxonomy for organizing slides by client (optional)
|
|
$client_labels = array(
|
|
'name' => _x( 'Clients', 'taxonomy general name', 'hi-school-slide-manager' ),
|
|
'singular_name' => _x( 'Client', 'taxonomy singular name', 'hi-school-slide-manager' ),
|
|
'search_items' => __( 'Search Clients', 'hi-school-slide-manager' ),
|
|
'all_items' => __( 'All Clients', 'hi-school-slide-manager' ),
|
|
'parent_item' => __( 'Parent Client', 'hi-school-slide-manager' ),
|
|
'parent_item_colon' => __( 'Parent Client:', 'hi-school-slide-manager' ),
|
|
'edit_item' => __( 'Edit Client', 'hi-school-slide-manager' ),
|
|
'update_item' => __( 'Update Client', 'hi-school-slide-manager' ),
|
|
'add_new_item' => __( 'Add New Client', 'hi-school-slide-manager' ),
|
|
'new_item_name' => __( 'New Client Name', 'hi-school-slide-manager' ),
|
|
'menu_name' => __( 'Clients', 'hi-school-slide-manager' ),
|
|
);
|
|
|
|
$client_args = array(
|
|
'hierarchical' => false,
|
|
'labels' => $client_labels,
|
|
'show_ui' => true,
|
|
'show_admin_column' => true,
|
|
'query_var' => true,
|
|
'rewrite' => array( 'slug' => 'slide-client' ),
|
|
'show_in_rest' => true,
|
|
);
|
|
|
|
register_taxonomy( self::CLIENT_TAXONOMY, array( self::POST_TYPE ), $client_args );
|
|
|
|
// Add default terms for the three companion sites
|
|
$this->create_default_site_terms();
|
|
}
|
|
|
|
/**
|
|
* Create default site terms for the three companion sites
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function create_default_site_terms() {
|
|
$default_sites = array();
|
|
|
|
// Use centralized method from HSSM_Main if available
|
|
if ( class_exists( 'HSSM_Main' ) && method_exists( 'HSSM_Main', 'get_companion_sites' ) ) {
|
|
$default_sites = HSSM_Main::get_companion_sites();
|
|
} else {
|
|
// Fallback
|
|
$default_sites = array(
|
|
array(
|
|
'slug' => 'hi-school',
|
|
'name' => 'Hi-School Pharmacy',
|
|
'description' => 'Hi-School Pharmacy companion site'
|
|
),
|
|
array(
|
|
'slug' => 'one-stop',
|
|
'name' => 'One Stop Hardware',
|
|
'description' => 'One Stop Hardware companion site'
|
|
),
|
|
array(
|
|
'slug' => 'ace',
|
|
'name' => 'Ace Hardware',
|
|
'description' => 'Ace Hardware companion site'
|
|
)
|
|
);
|
|
}
|
|
|
|
foreach ( $default_sites as $site ) {
|
|
if ( ! term_exists( $site['slug'], self::SITE_TAXONOMY ) ) {
|
|
wp_insert_term(
|
|
$site['name'],
|
|
self::SITE_TAXONOMY,
|
|
array(
|
|
'slug' => $site['slug'],
|
|
'description' => $site['description']
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add meta boxes for slide fields
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function add_meta_boxes() {
|
|
add_meta_box(
|
|
'hssm_slide_details',
|
|
__( 'Slide Details', 'hi-school-slide-manager' ),
|
|
array( $this, 'slide_details_meta_box' ),
|
|
self::POST_TYPE,
|
|
'normal',
|
|
'high'
|
|
);
|
|
|
|
add_meta_box(
|
|
'hssm_background_image_help',
|
|
__( 'Background Image Guidelines', 'hi-school-slide-manager' ),
|
|
array( $this, 'background_image_help_meta_box' ),
|
|
self::POST_TYPE,
|
|
'side',
|
|
'high'
|
|
);
|
|
|
|
add_meta_box(
|
|
'hssm_slide_scheduling',
|
|
__( 'Slide Scheduling', 'hi-school-slide-manager' ),
|
|
array( $this, 'slide_scheduling_meta_box' ),
|
|
self::POST_TYPE,
|
|
'side',
|
|
'default'
|
|
);
|
|
|
|
add_meta_box(
|
|
'hssm_slide_targeting',
|
|
__( 'Site Targeting', 'hi-school-slide-manager' ),
|
|
array( $this, 'slide_targeting_meta_box' ),
|
|
self::POST_TYPE,
|
|
'side',
|
|
'default'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Render slide details meta box
|
|
*
|
|
* @since 1.0.0
|
|
* @param WP_Post $post Current post object
|
|
*/
|
|
public function slide_details_meta_box( $post ) {
|
|
wp_nonce_field( 'hssm_save_slide_meta', 'hssm_slide_meta_nonce' );
|
|
|
|
$subtitle = get_post_meta( $post->ID, '_hssm_subtitle', true );
|
|
$buttons = get_post_meta( $post->ID, '_hssm_buttons', true );
|
|
$order = get_post_meta( $post->ID, '_hssm_order', true );
|
|
$hide_all_text = get_post_meta( $post->ID, '_hssm_hide_all_text', true );
|
|
|
|
// Initialize buttons array if empty
|
|
if ( ! is_array( $buttons ) || empty( $buttons ) ) {
|
|
$buttons = array(
|
|
array( 'text' => 'Learn More', 'url' => '' )
|
|
);
|
|
}
|
|
|
|
?>
|
|
<table class="form-table">
|
|
<tr>
|
|
<th scope="row">
|
|
<label for="hssm_subtitle"><?php _e( 'Subtitle', 'hi-school-slide-manager' ); ?></label>
|
|
</th>
|
|
<td>
|
|
<input type="text" id="hssm_subtitle" name="hssm_subtitle" value="<?php echo esc_attr( $subtitle ); ?>" class="regular-text" />
|
|
<p class="description"><?php _e( 'Optional subtitle for the slide', 'hi-school-slide-manager' ); ?></p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">
|
|
<label><?php _e( 'Call-to-Action Buttons', 'hi-school-slide-manager' ); ?></label>
|
|
</th>
|
|
<td>
|
|
<div id="hssm-buttons-container">
|
|
<?php foreach ( $buttons as $index => $button ) : ?>
|
|
<div class="hssm-button-row" data-index="<?php echo esc_attr( $index ); ?>">
|
|
<div class="hssm-button-fields">
|
|
<label><?php _e( 'Button Text:', 'hi-school-slide-manager' ); ?></label>
|
|
<input type="text" name="hssm_buttons[<?php echo esc_attr( $index ); ?>][text]" value="<?php echo esc_attr( $button['text'] ?: 'Learn More' ); ?>" class="regular-text" placeholder="Learn More" />
|
|
|
|
<label><?php _e( 'Button URL:', 'hi-school-slide-manager' ); ?></label>
|
|
<input type="url" name="hssm_buttons[<?php echo esc_attr( $index ); ?>][url]" value="<?php echo esc_url( $button['url'] ?: '' ); ?>" class="regular-text" placeholder="https://example.com" />
|
|
|
|
<button type="button" class="button hssm-remove-button" <?php echo count( $buttons ) <= 1 ? 'style="display:none;"' : ''; ?>><?php _e( 'Remove', 'hi-school-slide-manager' ); ?></button>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<p>
|
|
<button type="button" id="hssm-add-button" class="button button-secondary"><?php _e( 'Add Another Button', 'hi-school-slide-manager' ); ?></button>
|
|
<span class="description"><?php _e( '(Maximum 5 buttons)', 'hi-school-slide-manager' ); ?></span>
|
|
</p>
|
|
|
|
<p class="description"><?php _e( 'Add call-to-action buttons for the slide. The first button is typically the primary action.', 'hi-school-slide-manager' ); ?></p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">
|
|
<label for="hssm_order"><?php _e( 'Display Order', 'hi-school-slide-manager' ); ?></label>
|
|
</th>
|
|
<td>
|
|
<input type="number" id="hssm_order" name="hssm_order" value="<?php echo esc_attr( $order ?: 0 ); ?>" min="0" />
|
|
<p class="description"><?php _e( 'Display order for the slide (lower numbers show first). You can also drag and drop to reorder slides in the list view.', 'hi-school-slide-manager' ); ?></p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">
|
|
<label for="hssm_hide_all_text"><?php _e( 'Text Visibility', 'hi-school-slide-manager' ); ?></label>
|
|
</th>
|
|
<td>
|
|
<label>
|
|
<input type="checkbox" id="hssm_hide_all_text" name="hssm_hide_all_text" value="1" <?php checked( $hide_all_text, '1' ); ?> />
|
|
<?php _e( 'Hide All Text (Image Only)', 'hi-school-slide-manager' ); ?>
|
|
</label>
|
|
<p class="description"><?php _e( 'If checked, the title, subtitle, and buttons will not be displayed on the slide.', 'hi-school-slide-manager' ); ?></p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<style>
|
|
.hssm-button-row {
|
|
margin-bottom: 15px;
|
|
padding: 15px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
background: #f9f9f9;
|
|
}
|
|
|
|
.hssm-button-fields label {
|
|
display: inline-block;
|
|
width: 100px;
|
|
font-weight: 600;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
.hssm-button-fields input {
|
|
margin-bottom: 8px;
|
|
margin-left: 10px;
|
|
}
|
|
|
|
.hssm-remove-button {
|
|
margin-top: 5px;
|
|
color: #a00;
|
|
border-color: #a00;
|
|
}
|
|
|
|
.hssm-remove-button:hover {
|
|
background: #a00;
|
|
color: #fff;
|
|
}
|
|
</style>
|
|
|
|
<script type="text/javascript">
|
|
jQuery(document).ready(function($) {
|
|
let buttonIndex = <?php echo count( $buttons ); ?>;
|
|
const maxButtons = 5;
|
|
|
|
// Add button functionality
|
|
$('#hssm-add-button').on('click', function() {
|
|
if ($('.hssm-button-row').length >= maxButtons) {
|
|
alert('<?php _e( 'Maximum 5 buttons allowed', 'hi-school-slide-manager' ); ?>');
|
|
return;
|
|
}
|
|
|
|
const newRow = `
|
|
<div class="hssm-button-row" data-index="${buttonIndex}">
|
|
<div class="hssm-button-fields">
|
|
<label><?php _e( 'Button Text:', 'hi-school-slide-manager' ); ?></label>
|
|
<input type="text" name="hssm_buttons[${buttonIndex}][text]" value="Learn More" class="regular-text" placeholder="Learn More" />
|
|
|
|
<label><?php _e( 'Button URL:', 'hi-school-slide-manager' ); ?></label>
|
|
<input type="url" name="hssm_buttons[${buttonIndex}][url]" value="" class="regular-text" placeholder="https://example.com" />
|
|
|
|
<button type="button" class="button hssm-remove-button"><?php _e( 'Remove', 'hi-school-slide-manager' ); ?></button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
$('#hssm-buttons-container').append(newRow);
|
|
buttonIndex++;
|
|
|
|
// Show remove buttons if we have more than 1
|
|
if ($('.hssm-button-row').length > 1) {
|
|
$('.hssm-remove-button').show();
|
|
}
|
|
|
|
// Hide add button if we've reached the maximum
|
|
if ($('.hssm-button-row').length >= maxButtons) {
|
|
$('#hssm-add-button').hide();
|
|
}
|
|
});
|
|
|
|
// Remove button functionality
|
|
$(document).on('click', '.hssm-remove-button', function() {
|
|
$(this).closest('.hssm-button-row').remove();
|
|
|
|
// Hide remove buttons if we only have 1 left
|
|
if ($('.hssm-button-row').length <= 1) {
|
|
$('.hssm-remove-button').hide();
|
|
}
|
|
|
|
// Show add button if we're under the maximum
|
|
if ($('.hssm-button-row').length < maxButtons) {
|
|
$('#hssm-add-button').show();
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Render background image help meta box
|
|
*
|
|
* @since 1.0.0
|
|
* @param WP_Post $post Current post object
|
|
*/
|
|
public function background_image_help_meta_box( $post ) {
|
|
?>
|
|
<div class="hssm-background-help">
|
|
<h4><?php _e( 'Background Image Requirements:', 'hi-school-slide-manager' ); ?></h4>
|
|
<ul>
|
|
<li><?php _e( 'Recommended size: 1920x800px or larger', 'hi-school-slide-manager' ); ?></li>
|
|
<li><?php _e( 'Aspect ratio: 16:9 or similar wide format', 'hi-school-slide-manager' ); ?></li>
|
|
<li><?php _e( 'Format: JPG, PNG, or WebP', 'hi-school-slide-manager' ); ?></li>
|
|
<li><?php _e( 'File size: Under 1MB for best performance', 'hi-school-slide-manager' ); ?></li>
|
|
</ul>
|
|
|
|
<h4><?php _e( 'Design Tips:', 'hi-school-slide-manager' ); ?></h4>
|
|
<ul>
|
|
<li><?php _e( 'Keep important content away from edges', 'hi-school-slide-manager' ); ?></li>
|
|
<li><?php _e( 'Ensure good contrast for text overlay', 'hi-school-slide-manager' ); ?></li>
|
|
<li><?php _e( 'Consider mobile viewing (image will be cropped)', 'hi-school-slide-manager' ); ?></li>
|
|
</ul>
|
|
|
|
<p><strong><?php _e( 'Note:', 'hi-school-slide-manager' ); ?></strong> <?php _e( 'This image will be used as a full-width background for the header slide on the selected companion sites.', 'hi-school-slide-manager' ); ?></p>
|
|
</div>
|
|
|
|
<style>
|
|
.hssm-background-help ul {
|
|
margin-left: 20px;
|
|
}
|
|
.hssm-background-help li {
|
|
margin-bottom: 5px;
|
|
font-size: 13px;
|
|
}
|
|
.hssm-background-help h4 {
|
|
margin-bottom: 8px;
|
|
margin-top: 15px;
|
|
color: #23282d;
|
|
}
|
|
.hssm-background-help h4:first-child {
|
|
margin-top: 0;
|
|
}
|
|
</style>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Render slide scheduling meta box
|
|
*
|
|
* @since 1.0.0
|
|
* @param WP_Post $post Current post object
|
|
*/
|
|
public function slide_scheduling_meta_box( $post ) {
|
|
$start_date = get_post_meta( $post->ID, '_hssm_start_date', true );
|
|
$end_date = get_post_meta( $post->ID, '_hssm_end_date', true );
|
|
$auto_publish = get_post_meta( $post->ID, '_hssm_auto_publish', true );
|
|
$auto_unpublish = get_post_meta( $post->ID, '_hssm_auto_unpublish', true );
|
|
|
|
?>
|
|
<p>
|
|
<label for="hssm_start_date"><strong><?php _e( 'Start Date', 'hi-school-slide-manager' ); ?></strong></label><br>
|
|
<input type="datetime-local" id="hssm_start_date" name="hssm_start_date" value="<?php echo esc_attr( $start_date ); ?>" style="width: 100%;" />
|
|
</p>
|
|
<p>
|
|
<label for="hssm_end_date"><strong><?php _e( 'End Date', 'hi-school-slide-manager' ); ?></strong></label><br>
|
|
<input type="datetime-local" id="hssm_end_date" name="hssm_end_date" value="<?php echo esc_attr( $end_date ); ?>" style="width: 100%;" />
|
|
</p>
|
|
<p>
|
|
<label>
|
|
<input type="checkbox" name="hssm_auto_publish" value="1" <?php checked( $auto_publish, '1' ); ?> />
|
|
<?php _e( 'Auto-publish on start date', 'hi-school-slide-manager' ); ?>
|
|
</label>
|
|
</p>
|
|
<p>
|
|
<label>
|
|
<input type="checkbox" name="hssm_auto_unpublish" value="1" <?php checked( $auto_unpublish, '1' ); ?> />
|
|
<?php _e( 'Auto-unpublish on end date', 'hi-school-slide-manager' ); ?>
|
|
</label>
|
|
</p>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Render slide targeting meta box
|
|
*
|
|
* @since 1.0.0
|
|
* @param WP_Post $post Current post object
|
|
*/
|
|
public function slide_targeting_meta_box( $post ) {
|
|
// Get current terms
|
|
$current_sites = wp_get_post_terms( $post->ID, self::SITE_TAXONOMY, array( 'fields' => 'ids' ) );
|
|
$current_clients = wp_get_post_terms( $post->ID, self::CLIENT_TAXONOMY, array( 'fields' => 'ids' ) );
|
|
|
|
// Get all available site terms
|
|
$site_terms = get_terms( array(
|
|
'taxonomy' => self::SITE_TAXONOMY,
|
|
'hide_empty' => false,
|
|
) );
|
|
|
|
// Get all available client terms
|
|
$client_terms = get_terms( array(
|
|
'taxonomy' => self::CLIENT_TAXONOMY,
|
|
'hide_empty' => false,
|
|
) );
|
|
|
|
?>
|
|
<div class="hssm-targeting-section">
|
|
<p><strong><?php _e( 'Target Sites', 'hi-school-slide-manager' ); ?></strong></p>
|
|
<?php if ( ! empty( $site_terms ) && ! is_wp_error( $site_terms ) ) : ?>
|
|
<?php foreach ( $site_terms as $term ) : ?>
|
|
<p>
|
|
<label>
|
|
<input type="checkbox" name="hssm_target_sites[]" value="<?php echo esc_attr( $term->term_id ); ?>" <?php checked( in_array( $term->term_id, $current_sites ) ); ?> />
|
|
<?php echo esc_html( $term->name ); ?>
|
|
</label>
|
|
<?php if ( $term->description ) : ?>
|
|
<br><small class="description"><?php echo esc_html( $term->description ); ?></small>
|
|
<?php endif; ?>
|
|
</p>
|
|
<?php endforeach; ?>
|
|
<?php else : ?>
|
|
<p class="description"><?php _e( 'No sites available. Sites will be created automatically.', 'hi-school-slide-manager' ); ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="hssm-targeting-section" style="margin-top: 20px; padding-top: 15px; border-top: 1px solid #ddd;">
|
|
<p><strong><?php _e( 'Client (Optional)', 'hi-school-slide-manager' ); ?></strong></p>
|
|
<?php if ( ! empty( $client_terms ) && ! is_wp_error( $client_terms ) ) : ?>
|
|
<select name="hssm_client" style="width: 100%;">
|
|
<option value=""><?php _e( 'Select a client (optional)', 'hi-school-slide-manager' ); ?></option>
|
|
<?php foreach ( $client_terms as $term ) : ?>
|
|
<option value="<?php echo esc_attr( $term->term_id ); ?>" <?php selected( in_array( $term->term_id, $current_clients ) ); ?>>
|
|
<?php echo esc_html( $term->name ); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<?php else : ?>
|
|
<p class="description">
|
|
<?php _e( 'No clients available.', 'hi-school-slide-manager' ); ?>
|
|
<a href="<?php echo admin_url( 'edit-tags.php?taxonomy=' . self::CLIENT_TAXONOMY . '&post_type=' . self::POST_TYPE ); ?>">
|
|
<?php _e( 'Add clients here', 'hi-school-slide-manager' ); ?>
|
|
</a>
|
|
</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<style>
|
|
.hssm-targeting-section label {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 8px;
|
|
}
|
|
.hssm-targeting-section input[type="checkbox"] {
|
|
margin: 0;
|
|
flex-shrink: 0;
|
|
}
|
|
</style>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Save meta field data
|
|
*
|
|
* @since 1.0.0
|
|
* @param int $post_id Post ID
|
|
*/
|
|
public function save_meta_fields( $post_id ) {
|
|
// Verify nonce
|
|
if ( ! isset( $_POST['hssm_slide_meta_nonce'] ) || ! wp_verify_nonce( $_POST['hssm_slide_meta_nonce'], 'hssm_save_slide_meta' ) ) {
|
|
return;
|
|
}
|
|
|
|
// Check if this is an autosave
|
|
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
|
return;
|
|
}
|
|
|
|
// Check post type
|
|
if ( get_post_type( $post_id ) !== self::POST_TYPE ) {
|
|
return;
|
|
}
|
|
|
|
// Check permissions
|
|
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
|
return;
|
|
}
|
|
|
|
// Save meta fields
|
|
$meta_fields = array(
|
|
'hssm_subtitle' => 'sanitize_text_field',
|
|
'hssm_order' => 'intval',
|
|
'hssm_start_date' => 'sanitize_text_field',
|
|
'hssm_end_date' => 'sanitize_text_field',
|
|
);
|
|
|
|
foreach ( $meta_fields as $field => $sanitize_function ) {
|
|
if ( isset( $_POST[ $field ] ) ) {
|
|
$value = call_user_func( $sanitize_function, $_POST[ $field ] );
|
|
update_post_meta( $post_id, '_' . $field, $value );
|
|
}
|
|
}
|
|
|
|
// Save buttons array
|
|
if ( isset( $_POST['hssm_buttons'] ) && is_array( $_POST['hssm_buttons'] ) ) {
|
|
$buttons = array();
|
|
foreach ( $_POST['hssm_buttons'] as $button_data ) {
|
|
if ( ! empty( $button_data['text'] ) || ! empty( $button_data['url'] ) ) {
|
|
$buttons[] = array(
|
|
'text' => sanitize_text_field( $button_data['text'] ),
|
|
'url' => esc_url_raw( $button_data['url'] )
|
|
);
|
|
}
|
|
}
|
|
// Limit to 5 buttons maximum
|
|
$buttons = array_slice( $buttons, 0, 5 );
|
|
update_post_meta( $post_id, '_hssm_buttons', $buttons );
|
|
} else {
|
|
// If no buttons, set default
|
|
update_post_meta( $post_id, '_hssm_buttons', array(
|
|
array( 'text' => 'Learn More', 'url' => '' )
|
|
) );
|
|
}
|
|
|
|
// Save checkbox fields
|
|
$checkbox_fields = array( 'hssm_auto_publish', 'hssm_auto_unpublish', 'hssm_hide_all_text' );
|
|
foreach ( $checkbox_fields as $field ) {
|
|
$value = isset( $_POST[ $field ] ) ? '1' : '0';
|
|
update_post_meta( $post_id, '_' . $field, $value );
|
|
}
|
|
|
|
// Save target sites taxonomy
|
|
if ( isset( $_POST['hssm_target_sites'] ) && is_array( $_POST['hssm_target_sites'] ) ) {
|
|
$target_sites = array_map( 'intval', $_POST['hssm_target_sites'] );
|
|
wp_set_post_terms( $post_id, $target_sites, self::SITE_TAXONOMY );
|
|
} else {
|
|
wp_set_post_terms( $post_id, array(), self::SITE_TAXONOMY );
|
|
}
|
|
|
|
// Save client taxonomy
|
|
if ( isset( $_POST['hssm_client'] ) && ! empty( $_POST['hssm_client'] ) ) {
|
|
$client_id = intval( $_POST['hssm_client'] );
|
|
wp_set_post_terms( $post_id, array( $client_id ), self::CLIENT_TAXONOMY );
|
|
} else {
|
|
wp_set_post_terms( $post_id, array(), self::CLIENT_TAXONOMY );
|
|
}
|
|
|
|
// Send email notification for new slides
|
|
if ( get_post_status( $post_id ) === 'publish' && ! get_post_meta( $post_id, '_hssm_notification_sent', true ) ) {
|
|
$this->send_new_slide_notification( $post_id );
|
|
update_post_meta( $post_id, '_hssm_notification_sent', '1' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add custom columns to the slides list table
|
|
*
|
|
* @since 1.0.0
|
|
* @param array $columns Current columns
|
|
* @return array Modified columns
|
|
*/
|
|
public function add_custom_columns( $columns ) {
|
|
$new_columns = array();
|
|
$new_columns['cb'] = $columns['cb'];
|
|
$new_columns['title'] = $columns['title'];
|
|
$new_columns['target_sites'] = __( 'Target Sites', 'hi-school-slide-manager' );
|
|
$new_columns['client'] = __( 'Client', 'hi-school-slide-manager' );
|
|
$new_columns['schedule'] = __( 'Schedule', 'hi-school-slide-manager' );
|
|
$new_columns['order'] = __( 'Order', 'hi-school-slide-manager' );
|
|
$new_columns['date'] = $columns['date'];
|
|
|
|
return $new_columns;
|
|
}
|
|
|
|
/**
|
|
* Display custom column content
|
|
*
|
|
* @since 1.0.0
|
|
* @param string $column Column name
|
|
* @param int $post_id Post ID
|
|
*/
|
|
public function custom_column_content( $column, $post_id ) {
|
|
switch ( $column ) {
|
|
case 'title':
|
|
// Add drag handle to title column
|
|
echo '<span class="hssm-drag-handle dashicons dashicons-menu" title="' . esc_attr__( 'Drag to reorder', 'hi-school-slide-manager' ) . '"></span>';
|
|
break;
|
|
|
|
case 'target_sites':
|
|
$site_terms = wp_get_post_terms( $post_id, self::SITE_TAXONOMY );
|
|
if ( ! empty( $site_terms ) && ! is_wp_error( $site_terms ) ) {
|
|
$site_names = wp_list_pluck( $site_terms, 'name' );
|
|
echo esc_html( implode( ', ', $site_names ) );
|
|
} else {
|
|
echo '<em>' . __( 'No sites selected', 'hi-school-slide-manager' ) . '</em>';
|
|
}
|
|
break;
|
|
|
|
case 'client':
|
|
$client_terms = wp_get_post_terms( $post_id, self::CLIENT_TAXONOMY );
|
|
if ( ! empty( $client_terms ) && ! is_wp_error( $client_terms ) ) {
|
|
echo esc_html( $client_terms[0]->name );
|
|
} else {
|
|
echo '<em>' . __( 'No client', 'hi-school-slide-manager' ) . '</em>';
|
|
}
|
|
break;
|
|
|
|
case 'schedule':
|
|
$start_date = get_post_meta( $post_id, '_hssm_start_date', true );
|
|
$end_date = get_post_meta( $post_id, '_hssm_end_date', true );
|
|
|
|
if ( $start_date || $end_date ) {
|
|
echo '<div>';
|
|
if ( $start_date ) {
|
|
echo '<strong>' . __( 'Start:', 'hi-school-slide-manager' ) . '</strong> ' . esc_html( date( 'M j, Y g:i A', strtotime( $start_date ) ) ) . '<br>';
|
|
}
|
|
if ( $end_date ) {
|
|
echo '<strong>' . __( 'End:', 'hi-school-slide-manager' ) . '</strong> ' . esc_html( date( 'M j, Y g:i A', strtotime( $end_date ) ) );
|
|
}
|
|
echo '</div>';
|
|
} else {
|
|
echo '<em>' . __( 'No schedule set', 'hi-school-slide-manager' ) . '</em>';
|
|
}
|
|
break;
|
|
|
|
case 'order':
|
|
$order = get_post_meta( $post_id, '_hssm_order', true );
|
|
echo esc_html( $order ?: '0' );
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send email notification for new slide
|
|
*
|
|
* @since 1.0.0
|
|
* @param int $post_id Post ID
|
|
*/
|
|
private function send_new_slide_notification( $post_id ) {
|
|
$notification_emails = get_option( 'hssm_notification_emails', array() );
|
|
|
|
if ( empty( $notification_emails ) ) {
|
|
return;
|
|
}
|
|
|
|
$post = get_post( $post_id );
|
|
$subject = sprintf( __( 'New Slide Created: %s', 'hi-school-slide-manager' ), $post->post_title );
|
|
|
|
$message = sprintf(
|
|
__( 'A new slide has been created and published on %s.' . "\n\n" .
|
|
'Title: %s' . "\n" .
|
|
'Content: %s' . "\n" .
|
|
'Edit URL: %s', 'hi-school-slide-manager' ),
|
|
get_bloginfo( 'name' ),
|
|
$post->post_title,
|
|
wp_strip_all_tags( $post->post_content ),
|
|
admin_url( 'post.php?post=' . $post_id . '&action=edit' )
|
|
);
|
|
|
|
$headers = array( 'Content-Type: text/plain; charset=UTF-8' );
|
|
|
|
foreach ( $notification_emails as $email ) {
|
|
wp_mail( $email, $subject, $message, $headers );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check for scheduled slides that need status updates
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function check_scheduled_slides() {
|
|
$current_time = current_time( 'mysql' );
|
|
|
|
// Auto-publish slides that should start now
|
|
$slides_to_publish = get_posts( array(
|
|
'post_type' => self::POST_TYPE,
|
|
'post_status' => 'draft',
|
|
'meta_query' => array(
|
|
'relation' => 'AND',
|
|
array(
|
|
'key' => '_hssm_auto_publish',
|
|
'value' => '1',
|
|
'compare' => '='
|
|
),
|
|
array(
|
|
'key' => '_hssm_start_date',
|
|
'value' => $current_time,
|
|
'compare' => '<='
|
|
)
|
|
),
|
|
'numberposts' => -1
|
|
) );
|
|
|
|
foreach ( $slides_to_publish as $slide ) {
|
|
wp_update_post( array(
|
|
'ID' => $slide->ID,
|
|
'post_status' => 'publish'
|
|
) );
|
|
}
|
|
|
|
// Auto-unpublish slides that should end now
|
|
$slides_to_unpublish = get_posts( array(
|
|
'post_type' => self::POST_TYPE,
|
|
'post_status' => 'publish',
|
|
'meta_query' => array(
|
|
'relation' => 'AND',
|
|
array(
|
|
'key' => '_hssm_auto_unpublish',
|
|
'value' => '1',
|
|
'compare' => '='
|
|
),
|
|
array(
|
|
'key' => '_hssm_end_date',
|
|
'value' => $current_time,
|
|
'compare' => '<='
|
|
)
|
|
),
|
|
'numberposts' => -1
|
|
) );
|
|
|
|
foreach ( $slides_to_unpublish as $slide ) {
|
|
wp_update_post( array(
|
|
'ID' => $slide->ID,
|
|
'post_status' => 'draft'
|
|
) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enqueue admin scripts for drag-and-drop functionality
|
|
*
|
|
* @since 1.0.0
|
|
* @param string $hook Current admin page hook
|
|
*/
|
|
public function enqueue_admin_scripts( $hook ) {
|
|
global $post_type;
|
|
|
|
if ( $hook === 'edit.php' && $post_type === self::POST_TYPE ) {
|
|
wp_enqueue_script( 'jquery-ui-sortable' );
|
|
wp_enqueue_script(
|
|
'hssm-admin-sortable',
|
|
HSSM_PLUGIN_URL . 'assets/js/admin-sortable.js',
|
|
array( 'jquery', 'jquery-ui-sortable' ),
|
|
HSSM_VERSION,
|
|
true
|
|
);
|
|
|
|
wp_localize_script( 'hssm-admin-sortable', 'hssmAjax', array(
|
|
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
|
'nonce' => wp_create_nonce( 'hssm_update_slide_order' ),
|
|
'postType' => self::POST_TYPE
|
|
) );
|
|
|
|
// Add drag handle styles
|
|
wp_add_inline_style( 'wp-admin', '
|
|
.wp-list-table .hssm-drag-handle {
|
|
cursor: move;
|
|
color: #666;
|
|
margin-right: 5px;
|
|
}
|
|
.wp-list-table .hssm-drag-handle:hover {
|
|
color: #000;
|
|
}
|
|
.wp-list-table tbody tr.ui-sortable-helper {
|
|
background: #f0f0f0;
|
|
border: 2px dashed #0073aa;
|
|
}
|
|
.wp-list-table tbody tr.ui-sortable-placeholder {
|
|
background: #e0e0e0;
|
|
height: 40px;
|
|
}
|
|
' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AJAX handler for updating slide order
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function ajax_update_slide_order() {
|
|
// Verify nonce and permissions
|
|
if ( ! wp_verify_nonce( $_POST['nonce'], 'hssm_update_slide_order' ) || ! current_user_can( 'edit_posts' ) ) {
|
|
wp_send_json_error( 'Unauthorized' );
|
|
}
|
|
|
|
if ( isset( $_POST['slide_ids'] ) && is_array( $_POST['slide_ids'] ) ) {
|
|
$slide_ids = array_map( 'intval', $_POST['slide_ids'] );
|
|
|
|
foreach ( $slide_ids as $index => $slide_id ) {
|
|
update_post_meta( $slide_id, '_hssm_order', $index );
|
|
}
|
|
|
|
wp_send_json_success( array( 'message' => __( 'Slide order updated successfully', 'hi-school-slide-manager' ) ) );
|
|
}
|
|
|
|
wp_send_json_error( array( 'message' => __( 'Failed to update slide order', 'hi-school-slide-manager' ) ) );
|
|
}
|
|
}
|