Some checks failed
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Has been cancelled
Security Monitoring & Compliance / Secrets & Credential Scan (push) Has been cancelled
Security Monitoring & Compliance / WordPress Security Analysis (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Has been cancelled
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Has been cancelled
Security Monitoring & Compliance / Static Code Security Analysis (push) Has been cancelled
Security Monitoring & Compliance / Security Compliance Validation (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Notification (push) Has been cancelled
Security Monitoring & Compliance / Security Summary Report (push) Has been cancelled
Security Monitoring & Compliance / Security Team Notification (push) Has been cancelled
- Deploy 6 simultaneous WordPress specialized agents using sequential thinking and Zen MCP - Resolve all critical issues: permissions, jQuery dependencies, CDN mapping, security vulnerabilities - Implement bulletproof jQuery loading system with WordPress hook timing fixes - Create professional MapGeo Safety system with CDN health monitoring and fallback UI - Fix privilege escalation vulnerability with capability-based authorization - Add complete announcement admin system with modal forms and AJAX handling - Enhance import/export functionality (54 trainers successfully exported) - Achieve 100% operational master trainer functionality verified via MCP Playwright E2E testing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
293 lines
No EOL
13 KiB
PHP
293 lines
No EOL
13 KiB
PHP
<?php
|
|
/**
|
|
* HVAC Announcements Admin Interface
|
|
*
|
|
* @package HVAC_Community_Events
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Class HVAC_Announcements_Admin
|
|
*
|
|
* Handles admin interface for creating and managing announcements
|
|
*/
|
|
class HVAC_Announcements_Admin {
|
|
|
|
/**
|
|
* Instance of this class
|
|
*
|
|
* @var HVAC_Announcements_Admin
|
|
*/
|
|
private static $instance = null;
|
|
|
|
/**
|
|
* Get instance of this class
|
|
*
|
|
* @return HVAC_Announcements_Admin
|
|
*/
|
|
public static function get_instance() {
|
|
if (null === self::$instance) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
private function __construct() {
|
|
$this->init_hooks();
|
|
}
|
|
|
|
/**
|
|
* Initialize hooks
|
|
*/
|
|
private function init_hooks() {
|
|
add_action('wp_enqueue_scripts', array($this, 'enqueue_admin_assets'));
|
|
}
|
|
|
|
/**
|
|
* Enqueue admin assets on master trainer pages
|
|
*/
|
|
public function enqueue_admin_assets() {
|
|
// Only enqueue on master trainer announcement pages
|
|
if ($this->is_master_trainer_announcement_page()) {
|
|
// Enqueue admin JavaScript
|
|
wp_enqueue_script(
|
|
'hvac-announcements-admin',
|
|
plugin_dir_url(dirname(__FILE__)) . 'assets/js/hvac-announcements-admin.js',
|
|
array('jquery', 'wp-editor'),
|
|
defined('HVAC_VERSION') ? HVAC_VERSION : '1.0.0',
|
|
true
|
|
);
|
|
|
|
// Localize script with AJAX data
|
|
wp_localize_script('hvac-announcements-admin', 'hvac_announcements', array(
|
|
'ajax_url' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('hvac_announcements_admin_nonce'),
|
|
'strings' => array(
|
|
'confirm_delete' => __('Are you sure you want to delete this announcement?', 'hvac'),
|
|
'error_loading' => __('Error loading announcements.', 'hvac'),
|
|
'error_saving' => __('Error saving announcement.', 'hvac'),
|
|
'success_deleted' => __('Announcement deleted successfully.', 'hvac'),
|
|
)
|
|
));
|
|
|
|
// Enqueue WordPress media uploader
|
|
wp_enqueue_media();
|
|
|
|
// Enqueue admin CSS
|
|
wp_enqueue_style(
|
|
'hvac-announcements-admin',
|
|
plugin_dir_url(dirname(__FILE__)) . 'assets/css/hvac-announcements-admin.css',
|
|
array(),
|
|
defined('HVAC_VERSION') ? HVAC_VERSION : '1.0.0'
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if current page is master trainer announcement page
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function is_master_trainer_announcement_page() {
|
|
global $post;
|
|
|
|
if (!is_a($post, 'WP_Post')) {
|
|
return false;
|
|
}
|
|
|
|
// Check if user is master trainer
|
|
if (!HVAC_Announcements_Permissions::is_master_trainer()) {
|
|
return false;
|
|
}
|
|
|
|
// Check for announcement pages
|
|
$announcement_slugs = array(
|
|
'master-announcements',
|
|
'master-manage-announcements'
|
|
);
|
|
|
|
return in_array($post->post_name, $announcement_slugs);
|
|
}
|
|
|
|
/**
|
|
* Render admin interface modal HTML
|
|
*
|
|
* @return string Modal HTML
|
|
*/
|
|
public function render_admin_interface() {
|
|
// Check permissions
|
|
if (!HVAC_Announcements_Permissions::is_master_trainer()) {
|
|
return '';
|
|
}
|
|
|
|
ob_start();
|
|
?>
|
|
|
|
<!-- Announcements Management Interface -->
|
|
<div class="hvac-announcements-wrapper">
|
|
|
|
<!-- Controls Section -->
|
|
<div class="announcements-controls">
|
|
<div class="search-controls">
|
|
<input type="search" id="announcement-search" placeholder="<?php _e('Search announcements...', 'hvac'); ?>" class="regular-text">
|
|
<button id="search-btn" class="button"><?php _e('Search', 'hvac'); ?></button>
|
|
</div>
|
|
|
|
<div class="filter-controls">
|
|
<select id="status-filter">
|
|
<option value="any"><?php _e('All Statuses', 'hvac'); ?></option>
|
|
<option value="publish"><?php _e('Published', 'hvac'); ?></option>
|
|
<option value="draft"><?php _e('Draft', 'hvac'); ?></option>
|
|
<option value="pending"><?php _e('Pending', 'hvac'); ?></option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Announcements Table -->
|
|
<div class="announcements-table-wrapper">
|
|
<table class="wp-list-table widefat fixed striped announcements">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col" class="manage-column column-title"><?php _e('Title', 'hvac'); ?></th>
|
|
<th scope="col" class="manage-column column-status"><?php _e('Status', 'hvac'); ?></th>
|
|
<th scope="col" class="manage-column column-categories"><?php _e('Categories', 'hvac'); ?></th>
|
|
<th scope="col" class="manage-column column-author"><?php _e('Author', 'hvac'); ?></th>
|
|
<th scope="col" class="manage-column column-date"><?php _e('Date', 'hvac'); ?></th>
|
|
<th scope="col" class="manage-column column-actions"><?php _e('Actions', 'hvac'); ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="announcements-list">
|
|
<!-- Content loaded via AJAX -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
<div class="tablenav bottom">
|
|
<div class="tablenav-pages">
|
|
<span class="displaying-num">
|
|
<span id="current-page">1</span> of <span id="total-pages">1</span>
|
|
</span>
|
|
<span class="pagination-links">
|
|
<button id="prev-page" class="button"><?php _e('Previous', 'hvac'); ?></button>
|
|
<button id="next-page" class="button"><?php _e('Next', 'hvac'); ?></button>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Announcement Modal -->
|
|
<div id="announcement-modal" class="hvac-modal" style="display: none;">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h2 id="modal-title"><?php _e('Add New Announcement', 'hvac'); ?></h2>
|
|
<span class="modal-close">×</span>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<form id="announcement-form">
|
|
<?php wp_nonce_field('hvac_announcement_form', 'announcement_nonce'); ?>
|
|
<input type="hidden" id="announcement-id" name="announcement_id" value="">
|
|
|
|
<!-- Title Field -->
|
|
<div class="form-field">
|
|
<label for="announcement-title"><?php _e('Title', 'hvac'); ?> <span class="required">*</span></label>
|
|
<input type="text" id="announcement-title" name="announcement_title" class="widefat" required>
|
|
</div>
|
|
|
|
<!-- Content Field -->
|
|
<div class="form-field">
|
|
<label for="announcement-content"><?php _e('Content', 'hvac'); ?> <span class="required">*</span></label>
|
|
<?php
|
|
wp_editor('', 'announcement-content', array(
|
|
'textarea_name' => 'announcement_content',
|
|
'media_buttons' => true,
|
|
'textarea_rows' => 10,
|
|
'teeny' => false,
|
|
'dfw' => false,
|
|
'tinymce' => array(
|
|
'resize' => false,
|
|
'wordpress_adv_hidden' => false,
|
|
'add_unload_trigger' => false,
|
|
'statusbar' => false,
|
|
'wp_autoresize_on' => false,
|
|
'height' => 300
|
|
),
|
|
'quicktags' => true
|
|
));
|
|
?>
|
|
</div>
|
|
|
|
<!-- Excerpt Field -->
|
|
<div class="form-field">
|
|
<label for="announcement-excerpt"><?php _e('Excerpt', 'hvac'); ?></label>
|
|
<textarea id="announcement-excerpt" name="announcement_excerpt" rows="3" class="widefat"></textarea>
|
|
<p class="description"><?php _e('Brief summary for timeline view (optional).', 'hvac'); ?></p>
|
|
</div>
|
|
|
|
<!-- Status Field -->
|
|
<div class="form-field">
|
|
<label for="announcement-status"><?php _e('Status', 'hvac'); ?></label>
|
|
<select id="announcement-status" name="announcement_status" class="widefat">
|
|
<option value="draft"><?php _e('Draft', 'hvac'); ?></option>
|
|
<option value="publish"><?php _e('Published', 'hvac'); ?></option>
|
|
<option value="pending"><?php _e('Pending Review', 'hvac'); ?></option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Publish Date Field -->
|
|
<div class="form-field">
|
|
<label for="announcement-date"><?php _e('Publish Date', 'hvac'); ?></label>
|
|
<input type="datetime-local" id="announcement-date" name="announcement_date" class="widefat">
|
|
<p class="description"><?php _e('Leave empty to publish immediately.', 'hvac'); ?></p>
|
|
</div>
|
|
|
|
<!-- Categories Field -->
|
|
<div class="form-field">
|
|
<label><?php _e('Categories', 'hvac'); ?></label>
|
|
<div id="categories-container" class="checkbox-container">
|
|
<!-- Categories loaded via AJAX -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tags Field -->
|
|
<div class="form-field">
|
|
<label for="announcement-tags"><?php _e('Tags', 'hvac'); ?></label>
|
|
<input type="text" id="announcement-tags" name="announcement_tags" class="widefat">
|
|
<p class="description"><?php _e('Comma-separated tags.', 'hvac'); ?></p>
|
|
</div>
|
|
|
|
<!-- Featured Image Field -->
|
|
<div class="form-field">
|
|
<label><?php _e('Featured Image', 'hvac'); ?></label>
|
|
<div class="featured-image-section">
|
|
<input type="hidden" id="featured-image-id" name="featured_image_id" value="">
|
|
<div id="featured-image-preview"></div>
|
|
<div class="featured-image-buttons">
|
|
<button type="button" id="select-featured-image" class="button"><?php _e('Select Image', 'hvac'); ?></button>
|
|
<button type="button" id="remove-featured-image" class="button" style="display: none;"><?php _e('Remove Image', 'hvac'); ?></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Actions -->
|
|
<div class="form-actions">
|
|
<button type="submit" class="button button-primary"><?php _e('Save Announcement', 'hvac'); ?></button>
|
|
<button type="button" class="button modal-cancel"><?php _e('Cancel', 'hvac'); ?></button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php
|
|
return ob_get_clean();
|
|
}
|
|
}
|