552 lines
21 KiB
PHP
552 lines
21 KiB
PHP
<?php
|
|
/**
|
|
* HSSM Admin Class
|
|
*
|
|
* Handles admin functionality including settings pages and API key management
|
|
*
|
|
* @package Hi_School_Slide_Manager
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit( 'Direct access forbidden.' );
|
|
}
|
|
|
|
/**
|
|
* HSSM Admin Class
|
|
*
|
|
* Admin interface and settings management
|
|
*/
|
|
class HSSM_Admin {
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function __construct() {
|
|
// Hook is registered in main class
|
|
}
|
|
|
|
/**
|
|
* Initialize admin functionality
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function init() {
|
|
// This is called during the admin_init hook from HSSM_Main
|
|
$this->register_settings();
|
|
}
|
|
|
|
/**
|
|
* Add admin menus
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function add_menus() {
|
|
// Add settings page under the Slides menu
|
|
add_submenu_page(
|
|
'edit.php?post_type=hssm_slide',
|
|
__( 'Slide Manager Settings', 'hi-school-slide-manager' ),
|
|
__( 'Settings', 'hi-school-slide-manager' ),
|
|
'manage_options',
|
|
'hssm-settings',
|
|
array( $this, 'settings_page' )
|
|
);
|
|
|
|
// Add API documentation page
|
|
add_submenu_page(
|
|
'edit.php?post_type=hssm_slide',
|
|
__( 'API Documentation', 'hi-school-slide-manager' ),
|
|
__( 'API Docs', 'hi-school-slide-manager' ),
|
|
'manage_options',
|
|
'hssm-api-docs',
|
|
array( $this, 'api_docs_page' )
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Register plugin settings
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function register_settings() {
|
|
// Register settings
|
|
register_setting( 'hssm_settings', 'hssm_plugin_mode' );
|
|
register_setting( 'hssm_settings', 'hssm_api_url' );
|
|
register_setting( 'hssm_settings', 'hssm_client_site_slug' );
|
|
register_setting( 'hssm_settings', 'hssm_notification_emails' );
|
|
register_setting( 'hssm_settings', 'hssm_cache_duration' );
|
|
register_setting( 'hssm_settings', 'hssm_api_keys' );
|
|
|
|
// Add settings sections
|
|
add_settings_section(
|
|
'hssm_general',
|
|
__( 'General Settings', 'hi-school-slide-manager' ),
|
|
array( $this, 'general_section_callback' ),
|
|
'hssm-settings'
|
|
);
|
|
|
|
add_settings_section(
|
|
'hssm_notifications',
|
|
__( 'Email Notifications', 'hi-school-slide-manager' ),
|
|
array( $this, 'notifications_section_callback' ),
|
|
'hssm-settings'
|
|
);
|
|
|
|
add_settings_section(
|
|
'hssm_api',
|
|
__( 'API Settings', 'hi-school-slide-manager' ),
|
|
array( $this, 'api_section_callback' ),
|
|
'hssm-settings'
|
|
);
|
|
|
|
// Add settings fields
|
|
add_settings_field(
|
|
'hssm_plugin_mode',
|
|
__( 'Plugin Mode', 'hi-school-slide-manager' ),
|
|
array( $this, 'plugin_mode_field' ),
|
|
'hssm-settings',
|
|
'hssm_general'
|
|
);
|
|
|
|
add_settings_field(
|
|
'hssm_api_url',
|
|
__( 'Manager API URL', 'hi-school-slide-manager' ),
|
|
array( $this, 'api_url_field' ),
|
|
'hssm-settings',
|
|
'hssm_general'
|
|
);
|
|
|
|
add_settings_field(
|
|
'hssm_client_site_slug',
|
|
__( 'Client Site Slug', 'hi-school-slide-manager' ),
|
|
array( $this, 'client_site_slug_field' ),
|
|
'hssm-settings',
|
|
'hssm_general'
|
|
);
|
|
|
|
add_settings_field(
|
|
'hssm_cache_duration',
|
|
__( 'Cache Duration', 'hi-school-slide-manager' ),
|
|
array( $this, 'cache_duration_field' ),
|
|
'hssm-settings',
|
|
'hssm_general'
|
|
);
|
|
|
|
add_settings_field(
|
|
'hssm_notification_emails',
|
|
__( 'Notification Recipients', 'hi-school-slide-manager' ),
|
|
array( $this, 'notification_emails_field' ),
|
|
'hssm-settings',
|
|
'hssm_notifications'
|
|
);
|
|
|
|
add_settings_field(
|
|
'hssm_api_keys',
|
|
__( 'API Keys', 'hi-school-slide-manager' ),
|
|
array( $this, 'api_keys_field' ),
|
|
'hssm-settings',
|
|
'hssm_api'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Settings page callback
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function settings_page() {
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
return;
|
|
}
|
|
|
|
// Handle form submission
|
|
if ( isset( $_POST['submit'] ) || isset( $_POST['generate_api_key'] ) || isset( $_POST['delete_api_key'] ) ) {
|
|
check_admin_referer( 'hssm_settings' );
|
|
$this->handle_settings_save();
|
|
}
|
|
|
|
?>
|
|
<div class="wrap">
|
|
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
|
|
|
|
<?php settings_errors(); ?>
|
|
|
|
<form method="post" action="">
|
|
<?php
|
|
wp_nonce_field( 'hssm_settings' );
|
|
// Use a consistent page slug for do_settings_sections
|
|
do_settings_sections( 'hssm-settings' );
|
|
submit_button();
|
|
?>
|
|
</form>
|
|
|
|
<div class="hssm-api-endpoint-info" style="margin-top: 30px; padding: 20px; background: #f9f9f9; border: 1px solid #ddd;">
|
|
<h3><?php _e( 'API Endpoints', 'hi-school-slide-manager' ); ?></h3>
|
|
<p><?php _e( 'Use these endpoints for companion sites:', 'hi-school-slide-manager' ); ?></p>
|
|
<ul>
|
|
<li><code><?php echo esc_html( rest_url( 'hssm/v1/slides/{site}' ) ); ?></code> - Get slides for a site</li>
|
|
<li><code><?php echo esc_html( rest_url( 'hssm/v1/sites' ) ); ?></code> - Get available sites</li>
|
|
<li><code><?php echo esc_html( rest_url( 'hssm/v1/slide/{id}' ) ); ?></code> - Get single slide</li>
|
|
<li><code><?php echo esc_html( rest_url( 'hssm/v1/health' ) ); ?></code> - Health check (no auth required)</li>
|
|
</ul>
|
|
<p><strong><?php _e( 'Authentication:', 'hi-school-slide-manager' ); ?></strong> <?php _e( 'Include API key in X-HSSM-API-Key header or api_key parameter', 'hi-school-slide-manager' ); ?></p>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* API documentation page
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function api_docs_page() {
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
return;
|
|
}
|
|
|
|
?>
|
|
<div class="wrap">
|
|
<h1><?php _e( 'Hi-School Slide Manager API Documentation', 'hi-school-slide-manager' ); ?></h1>
|
|
|
|
<div class="hssm-api-docs">
|
|
<h2><?php _e( 'Authentication', 'hi-school-slide-manager' ); ?></h2>
|
|
<p><?php _e( 'All API endpoints (except health check) require authentication using an API key.', 'hi-school-slide-manager' ); ?></p>
|
|
<p><?php _e( 'Include the API key in one of these ways:', 'hi-school-slide-manager' ); ?></p>
|
|
<ul>
|
|
<li><?php _e( 'Header:', 'hi-school-slide-manager' ); ?> <code>X-HSSM-API-Key: your-api-key</code></li>
|
|
<li><?php _e( 'Query parameter:', 'hi-school-slide-manager' ); ?> <code>?api_key=your-api-key</code></li>
|
|
</ul>
|
|
|
|
<h2><?php _e( 'Endpoints', 'hi-school-slide-manager' ); ?></h2>
|
|
|
|
<h3><code>GET /wp-json/hssm/v1/slides/{site}</code></h3>
|
|
<p><?php _e( 'Get slides for a specific site.', 'hi-school-slide-manager' ); ?></p>
|
|
<h4><?php _e( 'Parameters:', 'hi-school-slide-manager' ); ?></h4>
|
|
<ul>
|
|
<li><code>site</code> (required) - Site slug: hi-school, one-stop, or ace</li>
|
|
<li><code>date</code> (optional) - Date to filter by (YYYY-MM-DD)</li>
|
|
<li><code>limit</code> (optional) - Max slides to return (1-50, default: 10)</li>
|
|
<li><code>status</code> (optional) - Filter by status: active, scheduled, all (default: active)</li>
|
|
</ul>
|
|
<h4><?php _e( 'Example:', 'hi-school-slide-manager' ); ?></h4>
|
|
<pre><code>GET <?php echo esc_html( rest_url( 'hssm/v1/slides/hi-school?limit=5&date=2025-12-01' ) ); ?>
|
|
Headers: X-HSSM-API-Key: your-api-key</code></pre>
|
|
|
|
<h3><code>GET /wp-json/hssm/v1/sites</code></h3>
|
|
<p><?php _e( 'Get all available sites.', 'hi-school-slide-manager' ); ?></p>
|
|
<h4><?php _e( 'Example:', 'hi-school-slide-manager' ); ?></h4>
|
|
<pre><code>GET <?php echo esc_html( rest_url( 'hssm/v1/sites' ) ); ?>
|
|
Headers: X-HSSM-API-Key: your-api-key</code></pre>
|
|
|
|
<h3><code>GET /wp-json/hssm/v1/slide/{id}</code></h3>
|
|
<p><?php _e( 'Get a specific slide by ID.', 'hi-school-slide-manager' ); ?></p>
|
|
<h4><?php _e( 'Parameters:', 'hi-school-slide-manager' ); ?></h4>
|
|
<ul>
|
|
<li><code>id</code> (required) - Slide ID</li>
|
|
</ul>
|
|
|
|
<h3><code>GET /wp-json/hssm/v1/health</code></h3>
|
|
<p><?php _e( 'Health check endpoint (no authentication required).', 'hi-school-slide-manager' ); ?></p>
|
|
|
|
<h2><?php _e( 'Response Format', 'hi-school-slide-manager' ); ?></h2>
|
|
<p><?php _e( 'All responses are in JSON format. Slide objects include:', 'hi-school-slide-manager' ); ?></p>
|
|
<pre><code>{
|
|
"id": 123,
|
|
"title": "Slide Title",
|
|
"subtitle": "Slide Subtitle",
|
|
"content": "Slide content...",
|
|
"buttons": [
|
|
{
|
|
"text": "Learn More",
|
|
"url": "https://example.com"
|
|
}
|
|
],
|
|
"order": 0,
|
|
"background_image": {
|
|
"id": 456,
|
|
"url": "https://example.com/image.jpg",
|
|
"width": 1920,
|
|
"height": 800,
|
|
"alt": "Image description",
|
|
"sizes": {
|
|
"full": "https://example.com/image.jpg",
|
|
"large": "https://example.com/image-1024x428.jpg"
|
|
}
|
|
},
|
|
"schedule": {
|
|
"start_date": "2025-01-01 00:00:00",
|
|
"end_date": "2025-12-31 23:59:59",
|
|
"auto_publish": true,
|
|
"auto_unpublish": true
|
|
},
|
|
"target_sites": [
|
|
{
|
|
"slug": "hi-school",
|
|
"name": "Hi-School Pharmacy"
|
|
}
|
|
],
|
|
"client": {
|
|
"slug": "client-name",
|
|
"name": "Client Name"
|
|
},
|
|
"status": "publish",
|
|
"created": "2025-01-01 12:00:00",
|
|
"modified": "2025-01-01 12:00:00"
|
|
}
|
|
</code></pre>
|
|
</div>
|
|
|
|
<style>
|
|
.hssm-api-docs {
|
|
max-width: 800px;
|
|
}
|
|
.hssm-api-docs h3 {
|
|
background: #f0f0f0;
|
|
padding: 10px;
|
|
border-left: 4px solid #0073aa;
|
|
}
|
|
.hssm-api-docs pre {
|
|
background: #f9f9f9;
|
|
padding: 15px;
|
|
border: 1px solid #ddd;
|
|
overflow-x: auto;
|
|
}
|
|
.hssm-api-docs code {
|
|
background: #f9f9f9;
|
|
padding: 2px 4px;
|
|
border-radius: 3px;
|
|
}
|
|
.hssm-api-docs pre code {
|
|
background: none;
|
|
padding: 0;
|
|
}
|
|
</style>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Enqueue admin assets
|
|
*
|
|
* @since 1.0.0
|
|
* @param string $hook Current admin page hook
|
|
*/
|
|
public function enqueue_assets( $hook ) {
|
|
// Enqueue general admin styles for all HSSM admin pages
|
|
if ( strpos( $hook, 'hssm' ) !== false || ( isset($_GET['post_type']) && $_GET['post_type'] === 'hssm_slide' ) ) {
|
|
wp_enqueue_style(
|
|
'hssm-admin',
|
|
HSSM_PLUGIN_URL . 'assets/css/admin.css',
|
|
array(),
|
|
HSSM_VERSION
|
|
);
|
|
wp_enqueue_script(
|
|
'hssm-admin',
|
|
HSSM_PLUGIN_URL . 'assets/js/admin.js',
|
|
array( 'jquery' ),
|
|
HSSM_VERSION,
|
|
true
|
|
);
|
|
}
|
|
|
|
// Conditionally enqueue dashboard-specific slide styles and dequeue public slider styles
|
|
global $pagenow;
|
|
if ( ( $pagenow === 'edit.php' && isset($_GET['post_type']) && $_GET['post_type'] === 'hssm_slide' ) || is_page_template('page-slide-dashboard.php') || is_page_template('page-slide-preview.php') ) {
|
|
wp_enqueue_style(
|
|
'hssm-admin-slides-dashboard',
|
|
HSSM_PLUGIN_URL . 'assets/css/admin-slides-dashboard.css',
|
|
array(),
|
|
HSSM_VERSION
|
|
);
|
|
// Dequeue the public slider styles on these admin-facing pages to prevent conflicts
|
|
// This is largely redundant after changes in HSSM_Main::enqueue_frontend_assets,
|
|
// but harmless to keep as a failsafe.
|
|
wp_dequeue_style('hssm-slider');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle settings save
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function handle_settings_save() {
|
|
// Handle general settings save
|
|
if ( isset( $_POST['submit'] ) ) {
|
|
if ( isset( $_POST['hssm_plugin_mode'] ) ) {
|
|
update_option( 'hssm_plugin_mode', sanitize_text_field( $_POST['hssm_plugin_mode'] ) );
|
|
}
|
|
if ( isset( $_POST['hssm_api_url'] ) ) {
|
|
update_option( 'hssm_api_url', esc_url_raw( $_POST['hssm_api_url'] ) );
|
|
}
|
|
if ( isset( $_POST['hssm_client_site_slug'] ) ) {
|
|
update_option( 'hssm_client_site_slug', sanitize_text_field( $_POST['hssm_client_site_slug'] ) );
|
|
}
|
|
if ( isset( $_POST['hssm_cache_duration'] ) ) {
|
|
update_option( 'hssm_cache_duration', absint( $_POST['hssm_cache_duration'] ) );
|
|
}
|
|
if ( isset( $_POST['hssm_notification_emails'] ) ) {
|
|
$emails = explode( "\n", str_replace( "\r", "", $_POST['hssm_notification_emails'] ) );
|
|
$emails = array_map( 'sanitize_email', $emails );
|
|
$emails = array_filter( $emails );
|
|
update_option( 'hssm_notification_emails', $emails );
|
|
}
|
|
add_settings_error( 'hssm_settings', 'settings_saved', __( 'Settings saved successfully.', 'hi-school-slide-manager' ), 'success' );
|
|
}
|
|
|
|
// Handle API key generation
|
|
if ( isset( $_POST['generate_api_key'] ) ) {
|
|
$api_keys = get_option( 'hssm_api_keys', array() );
|
|
$api_keys[] = wp_generate_password( 32, false );
|
|
update_option( 'hssm_api_keys', $api_keys );
|
|
add_settings_error( 'hssm_settings', 'api_key_generated', __( 'New API key generated successfully.', 'hi-school-slide-manager' ), 'success' );
|
|
}
|
|
|
|
// Handle API key deletion
|
|
if ( isset( $_POST['delete_api_key'] ) && isset( $_POST['api_key_index'] ) ) {
|
|
$api_keys = get_option( 'hssm_api_keys', array() );
|
|
$index = (int) $_POST['api_key_index'];
|
|
if ( isset( $api_keys[ $index ] ) ) {
|
|
unset( $api_keys[ $index ] );
|
|
$api_keys = array_values( $api_keys ); // Reindex array
|
|
update_option( 'hssm_api_keys', $api_keys );
|
|
add_settings_error( 'hssm_settings', 'api_key_deleted', __( 'API key deleted successfully.', 'hi-school-slide-manager' ), 'success' );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* General section callback
|
|
*/
|
|
public function general_section_callback() {
|
|
echo '<p>' . __( 'General plugin settings.', 'hi-school-slide-manager' ) . '</p>';
|
|
}
|
|
|
|
/**
|
|
* Notifications section callback
|
|
*/
|
|
public function notifications_section_callback() {
|
|
echo '<p>' . __( 'Configure email notifications for new slides.', 'hi-school-slide-manager' ) . '</p>';
|
|
}
|
|
|
|
/**
|
|
* API section callback
|
|
*/
|
|
public function api_section_callback() {
|
|
echo '<p>' . __( 'Manage API keys for companion sites.', 'hi-school-slide-manager' ) . '</p>';
|
|
}
|
|
|
|
/**
|
|
* Plugin mode field
|
|
*/
|
|
public function plugin_mode_field() {
|
|
$value = get_option( 'hssm_plugin_mode', 'manager' );
|
|
?>
|
|
<select name="hssm_plugin_mode" id="hssm_plugin_mode">
|
|
<option value="manager" <?php selected( $value, 'manager' ); ?>><?php _e( 'Manager (Source Site)', 'hi-school-slide-manager' ); ?></option>
|
|
<option value="client" <?php selected( $value, 'client' ); ?>><?php _e( 'Client (Companion Site)', 'hi-school-slide-manager' ); ?></option>
|
|
</select>
|
|
<p class="description"><?php _e( 'Choose "Manager" for the main site where slides are created, or "Client" for sites that just display slides from the manager.', 'hi-school-slide-manager' ); ?></p>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* API URL field
|
|
*/
|
|
public function api_url_field() {
|
|
$value = get_option( 'hssm_api_url', '' );
|
|
echo '<input type="url" name="hssm_api_url" value="' . esc_attr( $value ) . '" class="regular-text" placeholder="https://main-site.com/wp-json/" /> ';
|
|
echo '<p class="description">' . __( 'The REST API base URL of the Manager site.', 'hi-school-slide-manager' ) . '</p>';
|
|
}
|
|
|
|
/**
|
|
* Client site slug field
|
|
*/
|
|
public function client_site_slug_field() {
|
|
$value = get_option( 'hssm_client_site_slug', '' );
|
|
?>
|
|
<select name="hssm_client_site_slug" id="hssm_client_site_slug">
|
|
<option value=""><?php _e( 'Select site...', 'hi-school-slide-manager' ); ?></option>
|
|
<?php
|
|
$sites = HSSM_Main::get_companion_sites();
|
|
foreach ( $sites as $site ) {
|
|
echo '<option value="' . esc_attr( $site['slug'] ) . '" ' . selected( $value, $site['slug'], false ) . '>' . esc_html( $site['name'] ) . '</option>';
|
|
}
|
|
?>
|
|
</select>
|
|
<p class="description"><?php _e( 'Identify this site to the Manager API.', 'hi-school-slide-manager' ); ?></p>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Cache duration field
|
|
*/
|
|
public function cache_duration_field() {
|
|
$value = get_option( 'hssm_cache_duration', 3600 );
|
|
echo '<input type="number" name="hssm_cache_duration" value="' . esc_attr( $value ) . '" min="300" max="86400" /> ';
|
|
echo '<span class="description">' . __( 'Recommended cache duration for API responses (seconds)', 'hi-school-slide-manager' ) . '</span>';
|
|
}
|
|
|
|
/**
|
|
* Notification emails field
|
|
*/
|
|
public function notification_emails_field() {
|
|
$emails = get_option( 'hssm_notification_emails', array() );
|
|
echo '<textarea name="hssm_notification_emails" rows="5" class="regular-text">' . esc_textarea( implode( "\n", $emails ) ) . '</textarea><br>';
|
|
echo '<span class="description">' . __( 'Enter email addresses (one per line) to receive notifications when new slides are published.', 'hi-school-slide-manager' ) . '</span>';
|
|
}
|
|
|
|
/**
|
|
* API keys field
|
|
*/
|
|
public function api_keys_field() {
|
|
$api_keys = get_option( 'hssm_api_keys', array() );
|
|
|
|
echo '<div class="hssm-api-keys">';
|
|
|
|
if ( empty( $api_keys ) ) {
|
|
echo '<p>' . __( 'No API keys generated yet.', 'hi-school-slide-manager' ) . '</p>';
|
|
} else {
|
|
echo '<table class="widefat">';
|
|
echo '<thead><tr><th>' . __( 'API Key', 'hi-school-slide-manager' ) . '</th><th>' . __( 'Actions', 'hi-school-slide-manager' ) . '</th></tr></thead>';
|
|
echo '<tbody>';
|
|
|
|
foreach ( $api_keys as $index => $key ) {
|
|
echo '<tr>';
|
|
echo '<td><code>' . esc_html( $key ) . '</code></td>';
|
|
echo '<td>';
|
|
echo '<button type="button" class="button copy-api-key" data-key="' . esc_attr( $key ) . '">' . __( 'Copy', 'hi-school-slide-manager' ) . '</button> ';
|
|
echo '<button type="submit" name="delete_api_key" value="1" class="button button-link-delete" onclick="return confirm(\'' . esc_js( __( 'Are you sure you want to delete this API key?', 'hi-school-slide-manager' ) ) . '\')">' . __( 'Delete', 'hi-school-slide-manager' ) . '</button>';
|
|
echo '<input type="hidden" name="api_key_index" value="' . esc_attr( $index ) . '" />';
|
|
echo '</td>';
|
|
echo '</tr>';
|
|
}
|
|
|
|
echo '</tbody></table>';
|
|
}
|
|
|
|
echo '<p><button type="submit" name="generate_api_key" value="1" class="button button-secondary">' . __( 'Generate New API Key', 'hi-school-slide-manager' ) . '</button></p>';
|
|
echo '<p class="description">' . __( 'API keys are used by companion sites to authenticate and fetch slides.', 'hi-school-slide-manager' ) . '</p>';
|
|
|
|
echo '</div>';
|
|
|
|
// Add JavaScript for copy functionality
|
|
?>
|
|
<script>
|
|
jQuery(document).ready(function($) {
|
|
$(".copy-api-key").on("click", function() {
|
|
var key = $(this).data("key");
|
|
navigator.clipboard.writeText(key).then(function() {
|
|
alert("API key copied to clipboard!");
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
}
|