732 lines
24 KiB
PHP
732 lines
24 KiB
PHP
<?php
|
|
/**
|
|
* Admin Interface Class
|
|
*
|
|
* Handles all admin functionality
|
|
*
|
|
* @package Igny8Bridge
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Igny8Admin Class
|
|
*/
|
|
class Igny8Admin {
|
|
|
|
/**
|
|
* Single instance of the class
|
|
*
|
|
* @var Igny8Admin
|
|
*/
|
|
private static $instance = null;
|
|
|
|
/**
|
|
* Get single instance
|
|
*
|
|
* @return Igny8Admin
|
|
*/
|
|
public static function get_instance() {
|
|
if (null === self::$instance) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
private function __construct() {
|
|
add_action('admin_menu', array($this, 'add_menu_pages'));
|
|
add_action('admin_init', array($this, 'register_settings'));
|
|
add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts'));
|
|
}
|
|
|
|
/**
|
|
* Add admin menu pages
|
|
*/
|
|
public function add_menu_pages() {
|
|
// Add main menu page with dashicons (most reliable method)
|
|
add_menu_page(
|
|
__('IGNY8', 'igny8-bridge'),
|
|
__('IGNY8', 'igny8-bridge'),
|
|
'manage_options',
|
|
'igny8-connection',
|
|
array($this, 'render_page'),
|
|
'dashicons-cloud-saved',
|
|
58
|
|
);
|
|
|
|
// Add submenu pages - Dashboard is the main page (connection.php)
|
|
add_submenu_page(
|
|
'igny8-connection',
|
|
__('Dashboard', 'igny8-bridge'),
|
|
__('Dashboard', 'igny8-bridge'),
|
|
'manage_options',
|
|
'igny8-connection',
|
|
array($this, 'render_page')
|
|
);
|
|
|
|
add_submenu_page(
|
|
'igny8-connection',
|
|
__('Settings', 'igny8-bridge'),
|
|
__('Settings', 'igny8-bridge'),
|
|
'manage_options',
|
|
'igny8-settings',
|
|
array($this, 'render_page')
|
|
);
|
|
|
|
add_submenu_page(
|
|
'igny8-connection',
|
|
__('Logs', 'igny8-bridge'),
|
|
__('Logs', 'igny8-bridge'),
|
|
'manage_options',
|
|
'igny8-logs',
|
|
array($this, 'render_page')
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Register settings
|
|
*/
|
|
public function register_settings() {
|
|
// Email/password settings removed - using API key only
|
|
register_setting('igny8_settings', 'igny8_site_id');
|
|
register_setting('igny8_bridge_connection', 'igny8_connection_enabled', array(
|
|
'type' => 'boolean',
|
|
'sanitize_callback' => array($this, 'sanitize_boolean'),
|
|
'default' => 1
|
|
));
|
|
|
|
register_setting('igny8_bridge_connection', 'igny8_connection_enabled', array(
|
|
'type' => 'boolean',
|
|
'sanitize_callback' => array($this, 'sanitize_boolean'),
|
|
'default' => 1
|
|
));
|
|
|
|
register_setting('igny8_bridge_controls', 'igny8_enabled_post_types', array(
|
|
'type' => 'array',
|
|
'sanitize_callback' => array($this, 'sanitize_post_types'),
|
|
'default' => array_keys(igny8_get_supported_post_types())
|
|
));
|
|
|
|
register_setting('igny8_bridge_controls', 'igny8_enabled_taxonomies', array(
|
|
'type' => 'array',
|
|
'sanitize_callback' => array($this, 'sanitize_taxonomies'),
|
|
'default' => array('category', 'post_tag', 'product_cat', 'igny8_sectors', 'igny8_clusters')
|
|
));
|
|
|
|
register_setting('igny8_bridge_controls', 'igny8_enable_woocommerce', array(
|
|
'type' => 'boolean',
|
|
'sanitize_callback' => array($this, 'sanitize_boolean'),
|
|
'default' => class_exists('WooCommerce') ? 1 : 0
|
|
));
|
|
|
|
register_setting('igny8_bridge_controls', 'igny8_control_mode', array(
|
|
'type' => 'string',
|
|
'sanitize_callback' => array($this, 'sanitize_control_mode'),
|
|
'default' => 'mirror'
|
|
));
|
|
|
|
register_setting('igny8_bridge_controls', 'igny8_enabled_modules', array(
|
|
'type' => 'array',
|
|
'sanitize_callback' => array($this, 'sanitize_modules'),
|
|
'default' => array_keys(igny8_get_available_modules())
|
|
));
|
|
|
|
// Default post status for IGNY8 published content
|
|
register_setting('igny8_bridge_controls', 'igny8_default_post_status', array(
|
|
'type' => 'string',
|
|
'sanitize_callback' => array($this, 'sanitize_post_status'),
|
|
'default' => 'draft'
|
|
));
|
|
|
|
// Sync enabled toggle
|
|
register_setting('igny8_bridge_controls', 'igny8_sync_enabled', array(
|
|
'type' => 'boolean',
|
|
'sanitize_callback' => 'absint',
|
|
'default' => 1
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Enqueue admin scripts and styles
|
|
*
|
|
* @param string $hook Current admin page hook
|
|
*/
|
|
public function enqueue_scripts($hook) {
|
|
// Enqueue on IGNY8 pages
|
|
if (strpos($hook, 'igny8-') !== false || strpos($hook, 'toplevel_page_igny8') !== false) {
|
|
// Load modern design system CSS
|
|
wp_enqueue_style(
|
|
'igny8-modern-style',
|
|
IGNY8_BRIDGE_PLUGIN_URL . 'admin/assets/css/igny8-modern.css',
|
|
array(),
|
|
IGNY8_BRIDGE_VERSION
|
|
);
|
|
|
|
// Load legacy admin CSS for backwards compatibility
|
|
wp_enqueue_style(
|
|
'igny8-admin-style',
|
|
IGNY8_BRIDGE_PLUGIN_URL . 'admin/assets/css/admin.css',
|
|
array(),
|
|
IGNY8_BRIDGE_VERSION
|
|
);
|
|
|
|
wp_enqueue_script(
|
|
'igny8-admin-script',
|
|
IGNY8_BRIDGE_PLUGIN_URL . 'admin/assets/js/admin.js',
|
|
array('jquery'),
|
|
IGNY8_BRIDGE_VERSION,
|
|
true
|
|
);
|
|
|
|
wp_localize_script('igny8-admin-script', 'igny8Admin', array(
|
|
'ajaxUrl' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('igny8_admin_nonce'),
|
|
));
|
|
}
|
|
|
|
// Enqueue on post/page/product list pages
|
|
if (strpos($hook, 'edit.php') !== false) {
|
|
$screen = get_current_screen();
|
|
if ($screen && in_array($screen->post_type, array('post', 'page', 'product', ''))) {
|
|
wp_enqueue_style(
|
|
'igny8-admin-style',
|
|
IGNY8_BRIDGE_PLUGIN_URL . 'admin/assets/css/admin.css',
|
|
array(),
|
|
IGNY8_BRIDGE_VERSION
|
|
);
|
|
|
|
wp_enqueue_script(
|
|
'igny8-admin-script',
|
|
IGNY8_BRIDGE_PLUGIN_URL . 'admin/assets/js/admin.js',
|
|
array('jquery'),
|
|
IGNY8_BRIDGE_VERSION,
|
|
true
|
|
);
|
|
|
|
wp_localize_script('igny8-admin-script', 'igny8Admin', array(
|
|
'ajaxUrl' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('igny8_admin_nonce'),
|
|
));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render page based on current menu slug
|
|
*/
|
|
public function render_page() {
|
|
// Handle form submissions for connection page
|
|
if (isset($_POST['igny8_connect'])) {
|
|
if (empty($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'igny8_settings_nonce')) {
|
|
add_settings_error(
|
|
'igny8_settings',
|
|
'igny8_nonce',
|
|
__('Security check failed. Please refresh the page and try again.', 'igny8-bridge'),
|
|
'error'
|
|
);
|
|
} else {
|
|
$this->handle_connection();
|
|
}
|
|
}
|
|
|
|
// Handle revoke API key
|
|
if (isset($_POST['igny8_revoke_api_key'])) {
|
|
if (empty($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'igny8_revoke_api_key')) {
|
|
add_settings_error(
|
|
'igny8_settings',
|
|
'igny8_nonce_revoke',
|
|
__('Security check failed. Could not revoke API key.', 'igny8-bridge'),
|
|
'error'
|
|
);
|
|
} else {
|
|
self::revoke_api_key();
|
|
add_settings_error(
|
|
'igny8_settings',
|
|
'igny8_api_key_revoked',
|
|
__('API key revoked and removed from this site.', 'igny8-bridge'),
|
|
'updated'
|
|
);
|
|
}
|
|
}
|
|
|
|
// Determine which page to render
|
|
$page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : 'igny8-connection';
|
|
|
|
// Add wrapper class for modern design
|
|
echo '<div class="igny8-admin-page">';
|
|
|
|
// Include the appropriate page template
|
|
$template_file = '';
|
|
switch ($page) {
|
|
case 'igny8-dashboard':
|
|
case 'igny8-connection':
|
|
// Dashboard is now the connection page
|
|
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/connection.php';
|
|
break;
|
|
case 'igny8-settings':
|
|
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/settings.php';
|
|
break;
|
|
case 'igny8-logs':
|
|
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/logs.php';
|
|
break;
|
|
default:
|
|
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/connection.php';
|
|
}
|
|
|
|
// If the template file doesn't exist, fall back to the old settings page
|
|
if (file_exists($template_file)) {
|
|
include $template_file;
|
|
} else {
|
|
// Fallback to old settings page during transition
|
|
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/settings.php';
|
|
}
|
|
|
|
echo '</div>';
|
|
}
|
|
|
|
/**
|
|
* Render settings page - DEPRECATED, keeping for backwards compatibility
|
|
*/
|
|
public function render_settings_page() {
|
|
// Redirect to new render_page method
|
|
$this->render_page();
|
|
}
|
|
|
|
/**
|
|
* Handle API connection - API key only
|
|
* Calls /v1/integration/integrations/test-connection/ endpoint
|
|
*/
|
|
private function handle_connection() {
|
|
$api_key = sanitize_text_field($_POST['igny8_api_key'] ?? '');
|
|
|
|
// API key is required
|
|
if (empty($api_key)) {
|
|
add_settings_error(
|
|
'igny8_settings',
|
|
'igny8_error',
|
|
__('API key is required to connect to IGNY8.', 'igny8-bridge'),
|
|
'error'
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Extract site_id from API key format: igny8_site_{site_id}_{timestamp}_{random}
|
|
$site_id = null;
|
|
if (preg_match('/^igny8_site_(\d+)_/', $api_key, $matches)) {
|
|
$site_id = (int) $matches[1];
|
|
}
|
|
|
|
if (empty($site_id)) {
|
|
add_settings_error(
|
|
'igny8_settings',
|
|
'igny8_error',
|
|
__('Invalid API key format. Please copy the complete API key from IGNY8 app.', 'igny8-bridge'),
|
|
'error'
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Get site URL
|
|
$site_url = get_site_url();
|
|
|
|
// Test connection using the correct integration test endpoint
|
|
// The API class will handle authentication for test-connection endpoint
|
|
// by using the API key from the request body
|
|
$api = new Igny8API();
|
|
|
|
$test_response = $api->post('/v1/integration/integrations/test-connection/', array(
|
|
'site_id' => $site_id,
|
|
'api_key' => $api_key,
|
|
'site_url' => $site_url
|
|
));
|
|
|
|
if (!$test_response['success']) {
|
|
$error_message = $test_response['error'] ?? 'Unknown error';
|
|
|
|
// Provide more user-friendly message for throttling errors
|
|
if (isset($test_response['http_status']) && $test_response['http_status'] === 429) {
|
|
$error_message = __('Rate limit exceeded. The plugin will automatically retry, but if this persists, please wait a moment and try again.', 'igny8-bridge');
|
|
}
|
|
|
|
add_settings_error(
|
|
'igny8_settings',
|
|
'igny8_error',
|
|
sprintf(
|
|
__('Failed to connect to IGNY8 API: %s', 'igny8-bridge'),
|
|
$error_message
|
|
),
|
|
'error'
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Store API key securely
|
|
if (function_exists('igny8_store_secure_option')) {
|
|
igny8_store_secure_option('igny8_api_key', $api_key);
|
|
} else {
|
|
update_option('igny8_api_key', $api_key);
|
|
}
|
|
|
|
// Store site ID and last communication timestamp
|
|
update_option('igny8_site_id', sanitize_text_field($site_id));
|
|
update_option('igny8_last_communication', current_time('timestamp'));
|
|
|
|
add_settings_error(
|
|
'igny8_settings',
|
|
'igny8_connected',
|
|
__('Successfully connected to IGNY8 API. Site registered.', 'igny8-bridge'),
|
|
'updated'
|
|
);
|
|
|
|
// Sync site structure to backend (post types, taxonomies, etc.)
|
|
// Pass integration_id if available to avoid querying
|
|
igny8_sync_site_structure_to_backend($integration_id);
|
|
}
|
|
|
|
/**
|
|
* Revoke stored API key (secure delete)
|
|
*
|
|
* Public so tests can call it directly.
|
|
*/
|
|
public static function revoke_api_key() {
|
|
if (function_exists('igny8_delete_secure_option')) {
|
|
igny8_delete_secure_option('igny8_api_key');
|
|
} else {
|
|
delete_option('igny8_api_key');
|
|
}
|
|
|
|
// Clear connection data
|
|
delete_option('igny8_site_id');
|
|
delete_option('igny8_last_communication');
|
|
|
|
// Clean up deprecated options (for older installations)
|
|
delete_option('igny8_access_token');
|
|
delete_option('igny8_access_token_issued');
|
|
delete_option('igny8_integration_id');
|
|
delete_option('igny8_last_structure_sync');
|
|
delete_option('igny8_refresh_token');
|
|
delete_option('igny8_token_refreshed_at');
|
|
}
|
|
|
|
/**
|
|
* Test API connection (AJAX handler)
|
|
*/
|
|
public static function test_connection() {
|
|
check_ajax_referer('igny8_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => 'Unauthorized'));
|
|
}
|
|
|
|
if (!igny8_is_connection_enabled()) {
|
|
wp_send_json_error(array('message' => 'Connection is disabled. Enable sync operations to test.'));
|
|
}
|
|
|
|
$api = new Igny8API();
|
|
|
|
if (!$api->is_authenticated()) {
|
|
wp_send_json_error(array('message' => 'Not authenticated'));
|
|
}
|
|
|
|
// Get site ID
|
|
$site_id = get_option('igny8_site_id');
|
|
if (empty($site_id)) {
|
|
wp_send_json_error(array('message' => 'Site ID not configured. Connect to IGNY8 first.'));
|
|
}
|
|
|
|
// Test connection using the integration test endpoint
|
|
$api_key = function_exists('igny8_get_secure_option') ? igny8_get_secure_option('igny8_api_key') : get_option('igny8_api_key');
|
|
|
|
$test_response = $api->post('/v1/integration/integrations/test-connection/', array(
|
|
'site_id' => (int) $site_id,
|
|
'api_key' => $api_key,
|
|
'site_url' => get_site_url()
|
|
));
|
|
|
|
if ($test_response['success']) {
|
|
$checked_at = current_time('timestamp');
|
|
update_option('igny8_last_api_health_check', $checked_at);
|
|
wp_send_json_success(array(
|
|
'message' => __('Connection successful! IGNY8 API is responsive.', 'igny8-bridge'),
|
|
'checked_at' => $checked_at
|
|
));
|
|
return;
|
|
}
|
|
|
|
// Connection failed
|
|
$error_message = $test_response['error'] ?? 'Unknown error';
|
|
wp_send_json_error(array(
|
|
'message' => __('Connection failed: ', 'igny8-bridge') . $error_message,
|
|
'http_status' => $test_response['http_status'] ?? 0,
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Sync posts to IGNY8 (AJAX handler)
|
|
*/
|
|
public static function sync_posts() {
|
|
check_ajax_referer('igny8_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => 'Unauthorized'));
|
|
}
|
|
|
|
if (!igny8_is_connection_enabled()) {
|
|
wp_send_json_error(array('message' => 'Connection is disabled. Enable sync operations first.'));
|
|
}
|
|
|
|
$result = igny8_batch_sync_post_statuses();
|
|
|
|
wp_send_json_success(array(
|
|
'message' => sprintf('Synced %d posts, %d failed', $result['synced'], $result['failed']),
|
|
'data' => $result
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Sync taxonomies (AJAX handler)
|
|
*/
|
|
public static function sync_taxonomies() {
|
|
check_ajax_referer('igny8_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => 'Unauthorized'));
|
|
}
|
|
|
|
if (!igny8_is_connection_enabled()) {
|
|
wp_send_json_error(array('message' => 'Connection is disabled. Enable sync operations first.'));
|
|
}
|
|
|
|
$api = new Igny8API();
|
|
if (!$api->is_authenticated()) {
|
|
wp_send_json_error(array('message' => 'Not authenticated'));
|
|
}
|
|
|
|
// Sync sectors and clusters from IGNY8
|
|
$sectors_result = igny8_sync_igny8_sectors_to_wp();
|
|
$clusters_result = igny8_sync_igny8_clusters_to_wp();
|
|
|
|
wp_send_json_success(array(
|
|
'message' => sprintf('Synced %d sectors, %d clusters',
|
|
$sectors_result['synced'] ?? 0,
|
|
$clusters_result['synced'] ?? 0
|
|
),
|
|
'data' => array(
|
|
'sectors' => $sectors_result,
|
|
'clusters' => $clusters_result
|
|
)
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Sync from IGNY8 (AJAX handler)
|
|
*/
|
|
public static function sync_from_igny8() {
|
|
check_ajax_referer('igny8_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => 'Unauthorized'));
|
|
}
|
|
|
|
if (!igny8_is_connection_enabled()) {
|
|
wp_send_json_error(array('message' => 'Connection is disabled. Enable sync operations first.'));
|
|
}
|
|
|
|
$result = igny8_sync_igny8_tasks_to_wp();
|
|
|
|
if ($result['success']) {
|
|
wp_send_json_success(array(
|
|
'message' => sprintf('Created %d posts, updated %d posts',
|
|
$result['created'],
|
|
$result['updated']
|
|
),
|
|
'data' => $result
|
|
));
|
|
} else {
|
|
wp_send_json_error(array(
|
|
'message' => $result['error'] ?? 'Sync failed'
|
|
));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Collect and send site data (AJAX handler)
|
|
*/
|
|
public static function collect_site_data() {
|
|
check_ajax_referer('igny8_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => 'Unauthorized'));
|
|
}
|
|
|
|
if (!igny8_is_connection_enabled()) {
|
|
wp_send_json_error(array('message' => 'Connection is disabled. Enable sync operations first.'));
|
|
}
|
|
|
|
$site_id = get_option('igny8_site_id');
|
|
if (!$site_id) {
|
|
wp_send_json_error(array('message' => 'Site ID not set'));
|
|
}
|
|
|
|
$result = igny8_send_site_data_to_igny8($site_id);
|
|
|
|
if ($result) {
|
|
wp_send_json_success(array(
|
|
'message' => 'Site data collected and sent successfully',
|
|
'data' => $result
|
|
));
|
|
} else {
|
|
wp_send_json_error(array('message' => 'Failed to send site data'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get sync statistics (AJAX handler)
|
|
*/
|
|
public static function get_stats() {
|
|
check_ajax_referer('igny8_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => 'Unauthorized'));
|
|
}
|
|
|
|
global $wpdb;
|
|
|
|
// Count synced posts
|
|
$synced_posts = $wpdb->get_var("
|
|
SELECT COUNT(DISTINCT post_id)
|
|
FROM {$wpdb->postmeta}
|
|
WHERE meta_key = '_igny8_task_id'
|
|
");
|
|
|
|
// Get last sync time
|
|
$last_sync = get_option('igny8_last_site_sync', 0);
|
|
$last_sync_formatted = $last_sync ? date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $last_sync) : 'Never';
|
|
|
|
wp_send_json_success(array(
|
|
'synced_posts' => intval($synced_posts),
|
|
'last_sync' => $last_sync_formatted
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Sanitize post types option
|
|
*
|
|
* @param mixed $value Raw value
|
|
* @return array
|
|
*/
|
|
public function sanitize_post_types($value) {
|
|
$supported = array_keys(igny8_get_supported_post_types());
|
|
|
|
if (!is_array($value)) {
|
|
return $supported;
|
|
}
|
|
|
|
$clean = array();
|
|
foreach ($value as $post_type) {
|
|
$post_type = sanitize_key($post_type);
|
|
if (in_array($post_type, $supported, true)) {
|
|
$clean[] = $post_type;
|
|
}
|
|
}
|
|
|
|
return !empty($clean) ? $clean : $supported;
|
|
}
|
|
|
|
/**
|
|
* Sanitize taxonomies option
|
|
*
|
|
* @param mixed $value Raw value
|
|
* @return array
|
|
*/
|
|
public function sanitize_taxonomies($value) {
|
|
$supported = array_keys(igny8_get_supported_taxonomies());
|
|
|
|
if (!is_array($value)) {
|
|
return array('category', 'post_tag', 'product_cat', 'igny8_sectors', 'igny8_clusters');
|
|
}
|
|
|
|
$clean = array();
|
|
foreach ($value as $taxonomy) {
|
|
$taxonomy = sanitize_key($taxonomy);
|
|
if (in_array($taxonomy, $supported, true)) {
|
|
$clean[] = $taxonomy;
|
|
}
|
|
}
|
|
|
|
// Return defaults if nothing selected
|
|
return !empty($clean) ? $clean : array('category', 'post_tag');
|
|
}
|
|
|
|
/**
|
|
* Sanitize boolean option
|
|
*
|
|
* @param mixed $value Raw value
|
|
* @return int
|
|
*/
|
|
public function sanitize_boolean($value) {
|
|
return $value ? 1 : 0;
|
|
}
|
|
|
|
/**
|
|
* Sanitize control mode
|
|
*
|
|
* @param mixed $value Raw value
|
|
* @return string
|
|
*/
|
|
public function sanitize_control_mode($value) {
|
|
$value = is_string($value) ? strtolower($value) : 'mirror';
|
|
return in_array($value, array('mirror', 'hybrid'), true) ? $value : 'mirror';
|
|
}
|
|
|
|
/**
|
|
* Sanitize module toggles
|
|
*
|
|
* @param mixed $value Raw value
|
|
* @return array
|
|
*/
|
|
public function sanitize_modules($value) {
|
|
$supported = array_keys(igny8_get_available_modules());
|
|
|
|
if (!is_array($value)) {
|
|
return $supported;
|
|
}
|
|
|
|
$clean = array();
|
|
foreach ($value as $module) {
|
|
$module = sanitize_key($module);
|
|
if (in_array($module, $supported, true)) {
|
|
$clean[] = $module;
|
|
}
|
|
}
|
|
|
|
return !empty($clean) ? $clean : $supported;
|
|
}
|
|
|
|
/**
|
|
* Sanitize post status
|
|
*
|
|
* @param string $value Post status value
|
|
* @return string Sanitized post status
|
|
*/
|
|
public function sanitize_post_status($value) {
|
|
$allowed = array('draft', 'publish');
|
|
return in_array($value, $allowed, true) ? $value : 'draft';
|
|
}
|
|
}
|
|
|
|
// Register AJAX handlers
|
|
add_action('wp_ajax_igny8_test_connection', array('Igny8Admin', 'test_connection'));
|
|
add_action('wp_ajax_igny8_sync_posts', array('Igny8Admin', 'sync_posts'));
|
|
add_action('wp_ajax_igny8_sync_taxonomies', array('Igny8Admin', 'sync_taxonomies'));
|
|
add_action('wp_ajax_igny8_sync_from_igny8', array('Igny8Admin', 'sync_from_igny8'));
|
|
add_action('wp_ajax_igny8_collect_site_data', array('Igny8Admin', 'collect_site_data'));
|
|
add_action('wp_ajax_igny8_get_stats', array('Igny8Admin', 'get_stats'));
|
|
|