_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',
);
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' => '' )
);
}
?>
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 );
?>
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,
) );
?>
description ) : ?>
description ); ?>
'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 '';
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 '' . __( 'No sites selected', 'hi-school-slide-manager' ) . '';
}
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 '' . __( 'No client', 'hi-school-slide-manager' ) . '';
}
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 '';
if ( $start_date ) {
echo '' . __( 'Start:', 'hi-school-slide-manager' ) . ' ' . esc_html( date( 'M j, Y g:i A', strtotime( $start_date ) ) ) . '
';
}
if ( $end_date ) {
echo '' . __( 'End:', 'hi-school-slide-manager' ) . ' ' . esc_html( date( 'M j, Y g:i A', strtotime( $end_date ) ) );
}
echo '
';
} else {
echo '' . __( 'No schedule set', 'hi-school-slide-manager' ) . '';
}
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
$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
if ( ! wp_verify_nonce( $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' ) ) );
}
}