reference plugin and image gen analysis
This commit is contained in:
676
igny8-ai-seo-wp-plugin/modules/settings/general-settings.php
Normal file
676
igny8-ai-seo-wp-plugin/modules/settings/general-settings.php
Normal file
@@ -0,0 +1,676 @@
|
||||
<?php
|
||||
/**
|
||||
* ==========================
|
||||
* 🔐 IGNY8 FILE RULE HEADER
|
||||
* ==========================
|
||||
* @file : general-settings.php
|
||||
* @location : /modules/settings/general-settings.php
|
||||
* @type : Admin Page
|
||||
* @scope : Module Only
|
||||
* @allowed : Settings configuration, subpage routing, plugin preferences
|
||||
* @reusability : Single Use
|
||||
* @notes : Main settings page with subpage routing for settings module
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Initialize module manager and render the complete page
|
||||
$module_manager = igny8_module_manager();
|
||||
|
||||
// Handle URL parameters for subpages
|
||||
$subpage = $_GET['sp'] ?? 'general';
|
||||
|
||||
// Start output buffering
|
||||
ob_start();
|
||||
|
||||
switch ($subpage) {
|
||||
case 'status':
|
||||
include plugin_dir_path(__FILE__) . 'status.php';
|
||||
break;
|
||||
case 'integration':
|
||||
include plugin_dir_path(__FILE__) . 'integration.php';
|
||||
break;
|
||||
case 'schedules':
|
||||
include plugin_dir_path(__FILE__) . 'schedules.php';
|
||||
break;
|
||||
case 'import-export':
|
||||
include plugin_dir_path(__FILE__) . 'import-export.php';
|
||||
break;
|
||||
case 'general':
|
||||
default:
|
||||
// General settings content
|
||||
|
||||
// Handle image generation settings form submission
|
||||
if (isset($_POST['igny8_image_settings_nonce']) && wp_verify_nonce($_POST['igny8_image_settings_nonce'], 'igny8_image_settings')) {
|
||||
$image_type = sanitize_text_field($_POST['igny8_image_type'] ?? 'realistic');
|
||||
$desktop_enabled = isset($_POST['igny8_desktop_enabled']) ? '1' : '0';
|
||||
$mobile_enabled = isset($_POST['igny8_mobile_enabled']) ? '1' : '0';
|
||||
$max_in_article_images = intval($_POST['igny8_max_in_article_images'] ?? 1);
|
||||
$image_format = sanitize_text_field($_POST['igny8_image_format'] ?? 'jpg');
|
||||
|
||||
update_option('igny8_image_type', $image_type);
|
||||
update_option('igny8_desktop_enabled', $desktop_enabled);
|
||||
update_option('igny8_mobile_enabled', $mobile_enabled);
|
||||
update_option('igny8_max_in_article_images', $max_in_article_images);
|
||||
update_option('igny8_image_format', $image_format);
|
||||
|
||||
echo '<div class="notice notice-success"><p>Image generation settings saved successfully!</p></div>';
|
||||
} elseif (isset($_POST['igny8_image_settings_nonce'])) {
|
||||
echo '<div class="notice notice-error"><p>Security check failed. Please try again.</p></div>';
|
||||
}
|
||||
|
||||
// Handle editor type settings form submission
|
||||
if (isset($_POST['igny8_editor_type_nonce']) && wp_verify_nonce($_POST['igny8_editor_type_nonce'], 'igny8_editor_type_settings')) {
|
||||
$editor_type = isset($_POST['igny8_editor_type']) ? sanitize_text_field($_POST['igny8_editor_type']) : 'block';
|
||||
update_option('igny8_editor_type', $editor_type);
|
||||
echo '<div class="notice notice-success"><p>Editor type settings saved successfully! Selected: ' . esc_html($editor_type) . '</p></div>';
|
||||
} elseif (isset($_POST['igny8_editor_type_nonce'])) {
|
||||
echo '<div class="notice notice-error"><p>Security check failed. Please try again.</p></div>';
|
||||
}
|
||||
|
||||
// Handle image metabox settings form submission
|
||||
if (isset($_POST['igny8_image_metabox_nonce']) && wp_verify_nonce($_POST['igny8_image_metabox_nonce'], 'igny8_image_metabox_settings')) {
|
||||
$enabled_types = isset($_POST['igny8_enable_image_metabox']) ? $_POST['igny8_enable_image_metabox'] : [];
|
||||
$enabled_types = array_map('sanitize_text_field', $enabled_types);
|
||||
update_option('igny8_enable_image_metabox', $enabled_types);
|
||||
echo '<div class="notice notice-success"><p>Image metabox settings saved successfully!</p></div>';
|
||||
}
|
||||
|
||||
// Handle module settings form submission (only if not editor type or image metabox form)
|
||||
if (isset($_POST['submit']) && !isset($_POST['igny8_editor_type_nonce']) && !isset($_POST['igny8_image_metabox_nonce'])) {
|
||||
$module_manager->save_module_settings();
|
||||
}
|
||||
|
||||
// Debug: Log form submission data (remove in production)
|
||||
if (isset($_POST['submit']) && current_user_can('manage_options')) {
|
||||
error_log('Igny8 Settings Debug - POST data: ' . print_r($_POST, true));
|
||||
}
|
||||
|
||||
|
||||
$settings = get_option('igny8_module_settings', []);
|
||||
?>
|
||||
<div class="igny8-settings-section">
|
||||
<!-- Module Manager Section -->
|
||||
<div class="igny8-settings-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Module Manager</h3>
|
||||
<p class="igny8-card-subtitle">Enable or disable plugin modules and features</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-tools igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Module Settings -->
|
||||
<div class="igny8-settings-section">
|
||||
<div class="igny8-settings">
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('igny8_module_settings', 'igny8_module_nonce'); ?>
|
||||
|
||||
<!-- Main Modules Section -->
|
||||
<div class="igny8-settings-section">
|
||||
|
||||
|
||||
<div class="igny8-module-cards-grid">
|
||||
<?php foreach ($module_manager->get_modules() as $module_key => $module): ?>
|
||||
<?php if ($module['category'] === 'main'): ?>
|
||||
<div class="igny8-card igny8-module-card">
|
||||
<div class="igny8-module-header">
|
||||
<div class="igny8-card-title">
|
||||
<span class="dashicons <?php echo esc_attr($module['icon']); ?>" style="color: var(--blue); font-size: 20px; margin-right: 10px;"></span>
|
||||
<h6><?php echo esc_html($module['name']); ?></h6>
|
||||
</div>
|
||||
<div class="igny8-module-toggle">
|
||||
<label class="igny8-toggle-switch">
|
||||
<input type="checkbox"
|
||||
id="module_<?php echo esc_attr($module_key); ?>"
|
||||
name="igny8_module_settings[<?php echo esc_attr($module_key); ?>]"
|
||||
value="1"
|
||||
<?php checked($module_manager->is_module_enabled($module_key)); ?>>
|
||||
<span class="igny8-toggle-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-module-description">
|
||||
<p><?php echo esc_html($module['description']); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Admin & Analytics Section -->
|
||||
<div class="igny8-settings-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Admin & Analytics</h3>
|
||||
<p class="igny8-card-subtitle">Administrative tools and analytics modules</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-chart-bar igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-module-cards-grid">
|
||||
<?php foreach ($module_manager->get_modules() as $module_key => $module): ?>
|
||||
<?php if ($module['category'] === 'admin'): ?>
|
||||
<div class="igny8-card igny8-module-card">
|
||||
<div class="igny8-module-header">
|
||||
<div class="igny8-card-title">
|
||||
<span class="dashicons <?php echo esc_attr($module['icon']); ?>" style="color: var(--green); font-size: 20px; margin-right: 10px;"></span>
|
||||
<h6><?php echo esc_html($module['name']); ?></h6>
|
||||
</div>
|
||||
<div class="igny8-module-toggle">
|
||||
<label class="igny8-toggle-switch">
|
||||
<input type="checkbox"
|
||||
id="module_<?php echo esc_attr($module_key); ?>"
|
||||
name="igny8_module_settings[<?php echo esc_attr($module_key); ?>]"
|
||||
value="1"
|
||||
<?php checked($module_manager->is_module_enabled($module_key)); ?>>
|
||||
<span class="igny8-toggle-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-module-description">
|
||||
<p><?php echo esc_html($module['description']); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php submit_button('Save Module Settings', 'primary', 'submit', true, ['style' => 'margin-top: 20px;']); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Editor Type Selection Section -->
|
||||
<div class="igny8-settings-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Content Editor Type</h3>
|
||||
<p class="igny8-card-subtitle">Choose between Classic editor or Block (Gutenberg) editor for AI-generated content</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-edit-page igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-settings">
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('igny8_editor_type_settings', 'igny8_editor_type_nonce'); ?>
|
||||
|
||||
<div class="igny8-form-group">
|
||||
<label for="igny8_editor_type"><strong>Select Editor Type:</strong></label>
|
||||
<div style="margin-top: 15px;">
|
||||
<?php
|
||||
$current_editor_type = get_option('igny8_editor_type', 'block');
|
||||
?>
|
||||
|
||||
<!-- Current Setting Display -->
|
||||
<div style="background: #e8f4fd; border: 1px solid #0073aa; padding: 10px; border-radius: 4px; margin-bottom: 15px;">
|
||||
<strong>Current Setting:</strong>
|
||||
<span style="color: #0073aa; font-weight: 600;">
|
||||
<?php echo $current_editor_type === 'block' ? 'Block Editor (Gutenberg)' : 'Classic Editor'; ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label class="igny8-editor-option <?php echo $current_editor_type === 'block' ? 'selected' : ''; ?>">
|
||||
<input type="radio" name="igny8_editor_type" value="block" <?php checked($current_editor_type, 'block'); ?>>
|
||||
<div class="igny8-editor-option-content">
|
||||
<div class="igny8-editor-option-title">Block Editor (Gutenberg)</div>
|
||||
<div class="igny8-editor-option-description">
|
||||
Modern block-based editor with advanced formatting options. Recommended for better content structure and WordPress compatibility.
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label class="igny8-editor-option <?php echo $current_editor_type === 'classic' ? 'selected' : ''; ?>">
|
||||
<input type="radio" name="igny8_editor_type" value="classic" <?php checked($current_editor_type, 'classic'); ?>>
|
||||
<div class="igny8-editor-option-content">
|
||||
<div class="igny8-editor-option-title">Classic Editor</div>
|
||||
<div class="igny8-editor-option-description">
|
||||
Traditional WYSIWYG editor. Choose this if you prefer the classic WordPress editing experience.
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style="background: #f8f9fa; border: 1px solid #e9ecef; padding: 15px; border-radius: 6px; margin-top: 20px;">
|
||||
<p style="margin: 0 0 10px 0; font-weight: bold; color: #495057;">📝 <strong>How this affects your content:</strong></p>
|
||||
<ul style="margin: 0; padding-left: 20px; color: #6c757d; font-size: 14px;">
|
||||
<li><strong>Block Editor:</strong> AI content will be converted to WordPress blocks for better formatting and structure</li>
|
||||
<li><strong>Classic Editor:</strong> AI content will be saved as HTML and displayed in the classic editor</li>
|
||||
<li>You can change this setting anytime and it will apply to all new AI-generated content</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php submit_button('Save Editor Settings', 'primary', 'submit', true, ['style' => 'margin-top: 20px;']); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Enhanced editor selection interaction
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const editorOptions = document.querySelectorAll('.igny8-editor-option');
|
||||
|
||||
editorOptions.forEach(option => {
|
||||
const radio = option.querySelector('input[type="radio"]');
|
||||
|
||||
// Add click handler to the entire label
|
||||
option.addEventListener('click', function(e) {
|
||||
if (e.target !== radio) {
|
||||
radio.checked = true;
|
||||
updateSelection();
|
||||
}
|
||||
});
|
||||
|
||||
// Add change handler to radio buttons
|
||||
radio.addEventListener('change', function() {
|
||||
updateSelection();
|
||||
});
|
||||
});
|
||||
|
||||
function updateSelection() {
|
||||
editorOptions.forEach(option => {
|
||||
const radio = option.querySelector('input[type="radio"]');
|
||||
if (radio.checked) {
|
||||
option.classList.add('selected');
|
||||
} else {
|
||||
option.classList.remove('selected');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize selection on page load
|
||||
updateSelection();
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Image Generation Settings Section -->
|
||||
<div class="igny8-settings-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Image Generation</h3>
|
||||
<p class="igny8-card-subtitle">Configure AI image generation settings and preferences</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-format-image igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-settings">
|
||||
<form method="post" action="" id="igny8-image-generation-form">
|
||||
<?php wp_nonce_field('igny8_image_settings', 'igny8_image_settings_nonce'); ?>
|
||||
|
||||
<div class="igny8-form-group">
|
||||
<label><strong>Image Settings</strong></label>
|
||||
<div style="display: flex; gap: 20px; align-items: end; margin-top: 10px;">
|
||||
<div style="flex: 1;">
|
||||
<label for="igny8_image_type" style="display: block; margin-bottom: 5px; font-weight: 500;">Image Type</label>
|
||||
<select id="igny8_image_type" name="igny8_image_type" class="igny8-form-control">
|
||||
<option value="realistic" <?php selected(get_option('igny8_image_type', 'realistic'), 'realistic'); ?>>Realistic</option>
|
||||
<option value="illustration" <?php selected(get_option('igny8_image_type', 'realistic'), 'illustration'); ?>>Illustration</option>
|
||||
<option value="3D render" <?php selected(get_option('igny8_image_type', 'realistic'), '3D render'); ?>>3D Render</option>
|
||||
<option value="minimalist" <?php selected(get_option('igny8_image_type', 'realistic'), 'minimalist'); ?>>Minimalist</option>
|
||||
<option value="cartoon" <?php selected(get_option('igny8_image_type', 'realistic'), 'cartoon'); ?>>Cartoon</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div style="flex: 1;">
|
||||
<label for="igny8_max_in_article_images" style="display: block; margin-bottom: 5px; font-weight: 500;">Max In-Article Images</label>
|
||||
<select id="igny8_max_in_article_images" name="igny8_max_in_article_images" class="igny8-form-control">
|
||||
<option value="1" <?php selected(get_option('igny8_max_in_article_images', '1'), '1'); ?>>1 Image</option>
|
||||
<option value="2" <?php selected(get_option('igny8_max_in_article_images', '1'), '2'); ?>>2 Images</option>
|
||||
<option value="3" <?php selected(get_option('igny8_max_in_article_images', '1'), '3'); ?>>3 Images</option>
|
||||
<option value="4" <?php selected(get_option('igny8_max_in_article_images', '1'), '4'); ?>>4 Images</option>
|
||||
<option value="5" <?php selected(get_option('igny8_max_in_article_images', '1'), '5'); ?>>5 Images</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div style="flex: 1;">
|
||||
<label for="igny8_image_format" style="display: block; margin-bottom: 5px; font-weight: 500;">Image Format</label>
|
||||
<select id="igny8_image_format" name="igny8_image_format" class="igny8-form-control">
|
||||
<option value="jpg" <?php selected(get_option('igny8_image_format', 'jpg'), 'jpg'); ?>>JPG</option>
|
||||
<option value="png" <?php selected(get_option('igny8_image_format', 'jpg'), 'png'); ?>>PNG</option>
|
||||
<option value="webp" <?php selected(get_option('igny8_image_format', 'jpg'), 'webp'); ?>>WEBP</option>
|
||||
</select>
|
||||
<div id="igny8-selected-format" style="margin-top: 5px; font-weight: bold; color: #0073aa;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-form-group">
|
||||
<label><strong>Current Image Provider & Model</strong></label>
|
||||
<div style="background: #f8f9fa; border: 1px solid #e9ecef; padding: 15px; border-radius: 6px; margin-top: 10px;">
|
||||
<?php
|
||||
$current_service = get_option('igny8_image_service', 'openai');
|
||||
$current_model = get_option('igny8_image_model', 'dall-e-3');
|
||||
$current_runware_model = get_option('igny8_runware_model', 'runware:97@1');
|
||||
|
||||
if ($current_service === 'openai') {
|
||||
$model_names = [
|
||||
'dall-e-3' => 'DALL·E 3',
|
||||
'dall-e-2' => 'DALL·E 2',
|
||||
'gpt-image-1' => 'GPT Image 1 (Full)',
|
||||
'gpt-image-1-mini' => 'GPT Image 1 Mini'
|
||||
];
|
||||
$model_name = $model_names[$current_model] ?? $current_model;
|
||||
echo '<div style="display: flex; align-items: center; margin-bottom: 8px;">';
|
||||
echo '<span style="font-weight: bold; color: #0073aa; margin-right: 10px;">Provider:</span>';
|
||||
echo '<span style="color: #495057;">OpenAI</span>';
|
||||
echo '</div>';
|
||||
echo '<div style="display: flex; align-items: center;">';
|
||||
echo '<span style="font-weight: bold; color: #0073aa; margin-right: 10px;">Model:</span>';
|
||||
echo '<span style="color: #495057;">' . esc_html($model_name) . '</span>';
|
||||
echo '</div>';
|
||||
} else {
|
||||
echo '<div style="display: flex; align-items: center; margin-bottom: 8px;">';
|
||||
echo '<span style="font-weight: bold; color: #0073aa; margin-right: 10px;">Provider:</span>';
|
||||
echo '<span style="color: #495057;">Runware</span>';
|
||||
echo '</div>';
|
||||
echo '<div style="display: flex; align-items: center;">';
|
||||
echo '<span style="font-weight: bold; color: #0073aa; margin-right: 10px;">Model:</span>';
|
||||
echo '<span style="color: #495057;">HiDream-I1 Full</span>';
|
||||
echo '</div>';
|
||||
}
|
||||
?>
|
||||
<div style="margin-top: 10px; padding-top: 10px; border-top: 1px solid #dee2e6;">
|
||||
<small style="color: #6c757d;">
|
||||
<strong>Note:</strong> To change the image provider or model, go to
|
||||
<a href="<?php echo admin_url('admin.php?page=igny8-settings&sp=integration'); ?>" style="color: #0073aa;">Integration Settings</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-form-group">
|
||||
<label><strong>Image Size Options</strong></label>
|
||||
<div class="igny8-size-checkbox-container">
|
||||
<!-- Featured Image - Simple row without checkbox/count -->
|
||||
<div class="igny8-size-option igny8-featured-image-row">
|
||||
<div class="igny8-size-info igny8-size-featured">Featured Image</div>
|
||||
<div class="igny8-size-info" id="featured-size-info">1280×832 pixels</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-size-option">
|
||||
<label class="igny8-checkbox-label">
|
||||
<input type="checkbox" id="igny8_desktop_enabled" name="igny8_desktop_enabled" value="1" <?php checked(get_option('igny8_desktop_enabled', '1'), '1'); ?>>
|
||||
<span class="igny8-checkbox-text">Desktop Images</span>
|
||||
</label>
|
||||
<div class="igny8-size-info" id="desktop-size-info">1024×1024 pixels</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-size-option">
|
||||
<label class="igny8-checkbox-label">
|
||||
<input type="checkbox" id="igny8_mobile_enabled" name="igny8_mobile_enabled" value="1" <?php checked(get_option('igny8_mobile_enabled', '0'), '1'); ?>>
|
||||
<span class="igny8-checkbox-text">Mobile Images</span>
|
||||
</label>
|
||||
<div class="igny8-size-info" id="mobile-size-info">960×1280 pixels</div>
|
||||
</div>
|
||||
</div>
|
||||
<small class="form-help">Choose which image sizes to generate and how many of each type.</small>
|
||||
</div>
|
||||
|
||||
<?php submit_button('Save Image Settings', 'primary', 'submit', true, ['style' => 'margin-top: 20px;']); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Image generation settings JavaScript
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Get current provider from integration settings
|
||||
const currentProvider = '<?php echo esc_js(get_option('igny8_image_service', 'openai')); ?>';
|
||||
|
||||
function updateSizeInfo(provider) {
|
||||
const sizeInfo = {
|
||||
'runware': {
|
||||
featured: '1280×832 pixels',
|
||||
desktop: '1024×1024 pixels',
|
||||
mobile: '960×1280 pixels'
|
||||
},
|
||||
'openai': {
|
||||
featured: '1024×1024 pixels',
|
||||
desktop: '1024×1024 pixels',
|
||||
mobile: '1024×1024 pixels'
|
||||
},
|
||||
'dalle': {
|
||||
featured: '1024×1024 pixels',
|
||||
desktop: '1024×1024 pixels',
|
||||
mobile: '1024×1024 pixels'
|
||||
}
|
||||
};
|
||||
|
||||
if (sizeInfo[provider]) {
|
||||
$('#featured-size-info').text(sizeInfo[provider].featured);
|
||||
$('#desktop-size-info').text(sizeInfo[provider].desktop);
|
||||
$('#mobile-size-info').text(sizeInfo[provider].mobile);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize with current provider
|
||||
updateSizeInfo(currentProvider);
|
||||
|
||||
// Image format selector functionality
|
||||
const $formatSelector = $('#igny8_image_format');
|
||||
const $formatDisplay = $('#igny8-selected-format');
|
||||
|
||||
$formatSelector.on('change', function() {
|
||||
const selectedFormat = $(this).val().toUpperCase();
|
||||
$formatDisplay.text(selectedFormat + ' format');
|
||||
});
|
||||
|
||||
// Initialize format display with saved value
|
||||
const savedFormat = '<?php echo esc_js(get_option('igny8_image_format', 'jpg')); ?>';
|
||||
$formatSelector.val(savedFormat);
|
||||
$formatSelector.trigger('change');
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Image Generation Settings Styles */
|
||||
.igny8-size-checkbox-container {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #e9ecef;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.igny8-size-option {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.igny8-size-option:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.igny8-featured-image-row {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border-radius: 6px;
|
||||
padding: 15px 20px;
|
||||
margin-bottom: 15px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.igny8-size-featured {
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.igny8-checkbox-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.igny8-checkbox-label input[type="checkbox"] {
|
||||
margin-right: 10px;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.igny8-size-info {
|
||||
font-size: 14px;
|
||||
color: #6c757d;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.igny8-featured-image-row .igny8-size-info {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.form-help {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
font-size: 13px;
|
||||
color: #6c757d;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Image Metabox Settings Section -->
|
||||
<div class="igny8-settings-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>In-Article Image Meta Box</h3>
|
||||
<p class="igny8-card-subtitle">Enable image metabox for specific post types</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-format-image igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-settings">
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('igny8_image_metabox_settings', 'igny8_image_metabox_nonce'); ?>
|
||||
|
||||
<div class="igny8-form-group">
|
||||
<label for="igny8_enable_image_metabox"><strong>Enable In-Article Image Meta Box For:</strong></label>
|
||||
<div style="max-height: 200px; overflow-y: auto; border: 1px solid #ddd; padding: 15px; background: #f9f9f9; border-radius: 4px; margin-top: 10px;">
|
||||
<?php
|
||||
$all_post_types = get_post_types(['public' => true], 'objects');
|
||||
$enabled_types = (array) get_option('igny8_enable_image_metabox', []);
|
||||
|
||||
foreach ($all_post_types as $pt => $obj) {
|
||||
$checked = in_array($pt, $enabled_types) ? 'checked' : '';
|
||||
echo '<label style="display: block; margin-bottom: 8px; padding: 5px;">';
|
||||
echo '<input type="checkbox" name="igny8_enable_image_metabox[]" value="' . esc_attr($pt) . '" ' . $checked . ' style="margin-right: 8px;"> ';
|
||||
echo '<strong>' . esc_html($obj->label) . '</strong> <em>(' . esc_html($pt) . ')</em>';
|
||||
echo '</label>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<p class="description" style="margin-top: 10px;">Select which post types should display the In-Article Image metabox in the WordPress editor.</p>
|
||||
</div>
|
||||
|
||||
<!-- Shortcode Usage Examples -->
|
||||
<div class="igny8-form-group" style="margin-top: 25px;">
|
||||
<label><strong>Shortcode Usage Examples:</strong></label>
|
||||
<div style="background: #f8f9fa; border: 1px solid #e9ecef; padding: 15px; border-radius: 4px; margin-top: 10px;">
|
||||
<p style="margin: 0 0 10px 0; font-weight: bold; color: #495057;">Use these shortcodes in your posts/pages to display the selected images:</p>
|
||||
|
||||
<div style="margin-bottom: 12px;">
|
||||
<code style="background: #fff; padding: 4px 8px; border: 1px solid #ddd; border-radius: 3px; font-size: 13px;">[igny8-images]</code>
|
||||
<span style="margin-left: 8px; color: #6c757d; font-size: 13px;">Display all images</span>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 12px;">
|
||||
<code style="background: #fff; padding: 4px 8px; border: 1px solid #ddd; border-radius: 3px; font-size: 13px;">[igny8-image id="desktop-1"]</code>
|
||||
<span style="margin-left: 8px; color: #6c757d; font-size: 13px;">Display specific image by ID</span>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 12px;">
|
||||
<code style="background: #fff; padding: 4px 8px; border: 1px solid #ddd; border-radius: 3px; font-size: 13px;">[igny8-desktop-images]</code>
|
||||
<span style="margin-left: 8px; color: #6c757d; font-size: 13px;">Display only desktop images</span>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 12px;">
|
||||
<code style="background: #fff; padding: 4px 8px; border: 1px solid #ddd; border-radius: 3px; font-size: 13px;">[igny8-mobile-images]</code>
|
||||
<span style="margin-left: 8px; color: #6c757d; font-size: 13px;">Display only mobile images</span>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 12px;">
|
||||
<code style="background: #fff; padding: 4px 8px; border: 1px solid #ddd; border-radius: 3px; font-size: 13px;">[igny8-responsive-gallery]</code>
|
||||
<span style="margin-left: 8px; color: #6c757d; font-size: 13px;">Responsive gallery (desktop on large screens, mobile on small screens)</span>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 0;">
|
||||
<code style="background: #fff; padding: 4px 8px; border: 1px solid #ddd; border-radius: 3px; font-size: 13px;">[igny8-image-count]</code>
|
||||
<span style="margin-left: 8px; color: #6c757d; font-size: 13px;">Display count of images</span>
|
||||
</div>
|
||||
|
||||
<p style="margin: 15px 0 0 0; font-size: 12px; color: #6c757d; font-style: italic;">
|
||||
💡 <strong>Tip:</strong> After selecting images in the metabox, use these shortcodes in your post content to display them on the frontend.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php submit_button('Save Image Metabox Settings', 'primary', 'submit', true, ['style' => 'margin-top: 20px;']); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Table Settings Section -->
|
||||
<div class="igny8-settings-section">
|
||||
<form method="post" action="options.php">
|
||||
<?php settings_fields('igny8_table_settings'); ?>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_records_per_page">Records Per Page</label>
|
||||
</th>
|
||||
<td>
|
||||
<select name="igny8_records_per_page" id="igny8_records_per_page">
|
||||
<option value="10" <?php selected(get_option('igny8_records_per_page', 20), 10); ?>>10</option>
|
||||
<option value="20" <?php selected(get_option('igny8_records_per_page', 20), 20); ?>>20</option>
|
||||
<option value="50" <?php selected(get_option('igny8_records_per_page', 20), 50); ?>>50</option>
|
||||
<option value="100" <?php selected(get_option('igny8_records_per_page', 20), 100); ?>>100</option>
|
||||
</select>
|
||||
<p class="description">Default number of records to display per page across all tables in the plugin.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php submit_button('Save Settings'); ?>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
break;
|
||||
}
|
||||
|
||||
// Capture page content
|
||||
$igny8_page_content = ob_get_clean();
|
||||
|
||||
// Include global layout
|
||||
include plugin_dir_path(__FILE__) . '../../core/global-layout.php';
|
||||
?>
|
||||
267
igny8-ai-seo-wp-plugin/modules/settings/import-export.php
Normal file
267
igny8-ai-seo-wp-plugin/modules/settings/import-export.php
Normal file
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
/**
|
||||
* ==========================
|
||||
* 🔐 IGNY8 FILE RULE HEADER
|
||||
* ==========================
|
||||
* @file : import-export.php
|
||||
* @location : /modules/settings/import-export.php
|
||||
* @type : Admin Page
|
||||
* @scope : Module Only
|
||||
* @allowed : Data import/export, backup operations, data transfer
|
||||
* @reusability : Single Use
|
||||
* @notes : Import/export settings page for settings module
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Start output buffering
|
||||
ob_start();
|
||||
|
||||
// Get current import/export settings
|
||||
$import_export_settings = get_option('igny8_import_export_settings', [
|
||||
'default_format' => 'csv',
|
||||
'overwrite_existing' => false,
|
||||
'include_metrics' => true,
|
||||
'file_naming_pattern' => 'igny8_export_[date].csv'
|
||||
]);
|
||||
|
||||
// Get recent import/export logs
|
||||
$recent_logs = get_option('igny8_import_export_logs', []);
|
||||
$recent_logs = array_slice($recent_logs, 0, 10); // Last 10 entries
|
||||
|
||||
// Script localization will be done in the JavaScript section below
|
||||
?>
|
||||
<div class="igny8-import-export-page">
|
||||
<div class="igny8-container">
|
||||
|
||||
|
||||
<!-- Import Data Section -->
|
||||
<div class="igny8-card igny8-mb-20">
|
||||
<div class="igny8-card-header igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Import Data</h3>
|
||||
<div class="igny8-card-subtitle">Download CSV templates and import your data into the Planner module</div>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-upload igny8-dashboard-icon-sm"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
|
||||
<!-- Template Downloads -->
|
||||
<div class="igny8-mb-20">
|
||||
<h4>Download Templates</h4>
|
||||
<div class="igny8-grid-2 igny8-gap-10">
|
||||
<a href="<?php echo admin_url('admin-ajax.php?action=igny8_download_template&template_type=keywords&nonce=' . wp_create_nonce('igny8_import_export_nonce')); ?>" class="igny8-btn igny8-btn-outline">
|
||||
<span class="dashicons dashicons-download"></span> Keywords Template
|
||||
</a>
|
||||
<a href="<?php echo admin_url('admin-ajax.php?action=igny8_download_template&template_type=clusters&nonce=' . wp_create_nonce('igny8_import_export_nonce')); ?>" class="igny8-btn igny8-btn-outline">
|
||||
<span class="dashicons dashicons-download"></span> Clusters Template
|
||||
</a>
|
||||
<a href="<?php echo admin_url('admin-ajax.php?action=igny8_download_template&template_type=ideas&nonce=' . wp_create_nonce('igny8_import_export_nonce')); ?>" class="igny8-btn igny8-btn-outline">
|
||||
<span class="dashicons dashicons-download"></span> Ideas Template
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Import Form -->
|
||||
<form id="igny8-import-form" enctype="multipart/form-data" action="<?php echo admin_url('admin-ajax.php'); ?>" method="post">
|
||||
<input type="hidden" name="action" value="igny8_run_import">
|
||||
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce('igny8_import_export_nonce'); ?>">
|
||||
<div class="igny8-form-group">
|
||||
<label for="import-file">Select CSV File</label>
|
||||
<input type="file" id="import-file" name="import_file" accept=".csv" required>
|
||||
<p class="description">Upload a CSV file with your data. Use the templates above for proper format.</p>
|
||||
</div>
|
||||
|
||||
<div class="igny8-form-group">
|
||||
<label for="import-type">Import Type</label>
|
||||
<select id="import-type" name="import_type" required>
|
||||
<option value="">Select import type...</option>
|
||||
<option value="keywords">Keywords</option>
|
||||
<option value="clusters">Clusters</option>
|
||||
<option value="ideas">Content Ideas</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="igny8-form-actions">
|
||||
<button type="submit" class="igny8-btn igny8-btn-success">
|
||||
<span class="dashicons dashicons-upload"></span> Run Import
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Import Results -->
|
||||
<div id="import-results" class="igny8-mt-20" style="display: none;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Export Data Section -->
|
||||
<div class="igny8-card igny8-mb-20">
|
||||
<div class="igny8-card-header igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Export Data</h3>
|
||||
<div class="igny8-card-subtitle">Export your data in various formats for backup and migration</div>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-download igny8-dashboard-icon-sm"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
|
||||
<form id="igny8-export-form" action="<?php echo admin_url('admin-ajax.php'); ?>" method="post">
|
||||
<input type="hidden" name="action" value="igny8_run_export">
|
||||
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce('igny8_import_export_nonce'); ?>">
|
||||
<div class="igny8-form-group">
|
||||
<label for="export-type">Export Type</label>
|
||||
<select id="export-type" name="export_type" required>
|
||||
<option value="">Select export type...</option>
|
||||
<option value="keywords">Keywords</option>
|
||||
<option value="clusters">Clusters</option>
|
||||
<option value="ideas">Content Ideas</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="igny8-form-group">
|
||||
<h4>Export Options</h4>
|
||||
<div class="igny8-checkbox-group">
|
||||
<label class="igny8-checkbox-label">
|
||||
<input type="checkbox" id="include-metrics" name="include_metrics" <?php checked($import_export_settings['include_metrics'], true); ?>>
|
||||
<span class="igny8-checkbox-text">Include Metrics</span>
|
||||
</label>
|
||||
<label class="igny8-checkbox-label">
|
||||
<input type="checkbox" id="include-relationships" name="include_relationships">
|
||||
<span class="igny8-checkbox-text">Include Relationships</span>
|
||||
</label>
|
||||
<label class="igny8-checkbox-label">
|
||||
<input type="checkbox" id="include-timestamps" name="include_timestamps">
|
||||
<span class="igny8-checkbox-text">Include Timestamps</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-form-actions">
|
||||
<button type="submit" class="igny8-btn igny8-btn-primary">
|
||||
<span class="dashicons dashicons-download"></span> Export CSV
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Export Results -->
|
||||
<div id="export-results" class="igny8-mt-20" style="display: none;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings & Logging Section -->
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-card-header igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Import / Export Preferences</h3>
|
||||
<div class="igny8-card-subtitle">Configure import/export settings and view operation logs</div>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-generic igny8-dashboard-icon-sm"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<form id="igny8-settings-form" action="<?php echo admin_url('admin-ajax.php'); ?>" method="post">
|
||||
<input type="hidden" name="action" value="igny8_save_import_export_settings">
|
||||
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce('igny8_import_export_nonce'); ?>">
|
||||
<div class="igny8-grid-2 igny8-gap-20">
|
||||
<div class="igny8-form-group">
|
||||
<label for="default-format">Default Format</label>
|
||||
<select id="default-format" name="default_format">
|
||||
<option value="csv" <?php selected($import_export_settings['default_format'], 'csv'); ?>>CSV</option>
|
||||
<option value="json" <?php selected($import_export_settings['default_format'], 'json'); ?>>JSON</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="igny8-form-group">
|
||||
<label for="file-naming">File Naming Pattern</label>
|
||||
<input type="text" id="file-naming" name="file_naming_pattern" value="<?php echo esc_attr($import_export_settings['file_naming_pattern']); ?>" placeholder="igny8_export_[date].csv">
|
||||
<p class="description">Use [date], [type], [time] placeholders</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-form-group">
|
||||
<h4>Default Options</h4>
|
||||
<div class="igny8-checkbox-group">
|
||||
<label class="igny8-checkbox-label">
|
||||
<input type="checkbox" id="overwrite-existing" name="overwrite_existing" <?php checked($import_export_settings['overwrite_existing'], true); ?>>
|
||||
<span class="igny8-checkbox-text">Overwrite Existing Records</span>
|
||||
</label>
|
||||
<label class="igny8-checkbox-label">
|
||||
<input type="checkbox" id="include-metrics-default" name="include_metrics" <?php checked($import_export_settings['include_metrics'], true); ?>>
|
||||
<span class="igny8-checkbox-text">Include Metrics in Export by Default</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-form-actions">
|
||||
<button type="submit" class="igny8-btn igny8-btn-success">Save Preferences</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Recent Logs -->
|
||||
<?php if (!empty($recent_logs)): ?>
|
||||
<div class="igny8-mt-30">
|
||||
<h4>Recent Import/Export Activity</h4>
|
||||
<div class="igny8-logs-container" style="max-height: 300px; overflow-y: auto; border: 1px solid #ddd; border-radius: 4px; padding: 10px; background: #f9f9f9;">
|
||||
<?php foreach ($recent_logs as $log): ?>
|
||||
<div class="igny8-log-entry" style="border-bottom: 1px solid #eee; padding: 8px 0; font-size: 12px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<span style="font-weight: bold; color: <?php echo $log['status'] === 'success' ? 'green' : 'red'; ?>;">
|
||||
<?php echo $log['status'] === 'success' ? '✓' : '✗'; ?>
|
||||
<?php echo esc_html($log['operation']); ?>
|
||||
</span>
|
||||
<span style="color: #666;"><?php echo esc_html($log['timestamp']); ?></span>
|
||||
</div>
|
||||
<div style="color: #666; margin-top: 2px;">
|
||||
<?php echo esc_html($log['message']); ?>
|
||||
<?php if (isset($log['details'])): ?>
|
||||
<br><small><?php echo esc_html($log['details']); ?></small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Localize script variables
|
||||
window.IGNY8_IMPORT_EXPORT = {
|
||||
ajaxUrl: '<?php echo admin_url('admin-ajax.php'); ?>',
|
||||
nonce: '<?php echo wp_create_nonce('igny8_import_export_nonce'); ?>',
|
||||
settings: <?php echo json_encode($import_export_settings); ?>
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('Import/Export page loaded');
|
||||
console.log('IGNY8_IMPORT_EXPORT:', window.IGNY8_IMPORT_EXPORT);
|
||||
|
||||
// Initialize Import/Export functionality
|
||||
if (typeof window.initializeImportExport === 'function') {
|
||||
console.log('Initializing Import/Export functionality');
|
||||
window.initializeImportExport();
|
||||
} else {
|
||||
console.error('initializeImportExport function not found');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
744
igny8-ai-seo-wp-plugin/modules/settings/integration.php
Normal file
744
igny8-ai-seo-wp-plugin/modules/settings/integration.php
Normal file
@@ -0,0 +1,744 @@
|
||||
<?php
|
||||
/**
|
||||
* ==========================
|
||||
* 🔐 IGNY8 FILE RULE HEADER
|
||||
* ==========================
|
||||
* @file : integration.php
|
||||
* @location : /modules/settings/integration.php
|
||||
* @type : Admin Page
|
||||
* @scope : Module Only
|
||||
* @allowed : API integration, connection management, external service settings
|
||||
* @reusability : Single Use
|
||||
* @notes : API integration settings page for settings module
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Start output buffering
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<!-- API Integration Section -->
|
||||
<div class="igny8-dashboard-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>API Integration</h3>
|
||||
<p class="igny8-card-subtitle">Configure external API connections and integrations</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-site igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- API Services Grid -->
|
||||
<div class="igny8-grid-2 igny8-dashboard-section" style="display: flex; flex-direction: row;">
|
||||
|
||||
<!-- OpenAI API Card -->
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>OpenAI API</h3>
|
||||
<p class="igny8-card-subtitle">AI-powered content generation and analysis</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-site igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<form method="post" action="options.php">
|
||||
<?php settings_fields('igny8_api_settings'); ?>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_api_key">OpenAI API Key</label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="password" name="igny8_api_key" id="igny8_api_key" value="<?php echo esc_attr(get_option('igny8_api_key', '')); ?>" class="regular-text" />
|
||||
<p class="description">Your OpenAI API key for DALL-E 3 image generation and text AI features.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_runware_api_key">Runware API Key</label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="password" name="igny8_runware_api_key" id="igny8_runware_api_key" value="<?php echo esc_attr(get_option('igny8_runware_api_key', '')); ?>" class="regular-text" />
|
||||
<p class="description">Your Runware API key for high-quality image generation. <a href="https://runware.com" target="_blank">Get your API key here</a>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label>AI Model</label>
|
||||
</th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<label style="display: block; margin-bottom: 10px;">
|
||||
<input type="radio" name="igny8_model" value="gpt-4.1" <?php checked(get_option('igny8_model', 'gpt-4.1'), 'gpt-4.1'); ?> />
|
||||
<strong>GPT-4.1</strong> — $2.00 / $8.00 per 1M tokens<br>
|
||||
<span style="color: #666; font-size: 12px;">Content creation, coding, analysis, high-quality content generation</span>
|
||||
</label>
|
||||
<label style="display: block; margin-bottom: 10px;">
|
||||
<input type="radio" name="igny8_model" value="gpt-4o-mini" <?php checked(get_option('igny8_model', 'gpt-4.1'), 'gpt-4o-mini'); ?> />
|
||||
<strong>GPT-4o mini</strong> — $0.15 / $0.60 per 1M tokens<br>
|
||||
<span style="color: #666; font-size: 12px;">Bulk tasks, lightweight AI, cost-effective for high-volume operations</span>
|
||||
</label>
|
||||
<label style="display: block;">
|
||||
<input type="radio" name="igny8_model" value="gpt-4o" <?php checked(get_option('igny8_model', 'gpt-4.1'), 'gpt-4o'); ?> />
|
||||
<strong>GPT-4o</strong> — $2.50 / $10.00 per 1M tokens<br>
|
||||
<span style="color: #666; font-size: 12px;">Advanced AI for general and multimodal tasks, faster than GPT-4.1</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
<p class="description">Select the AI model to use for content generation. Pricing shown per 1M tokens.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Image Generation Service</th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<label style="display: block; margin-bottom: 10px;">
|
||||
<input type="radio" name="igny8_image_service" value="openai" <?php checked(get_option('igny8_image_service', 'openai'), 'openai'); ?> />
|
||||
<strong>OpenAI</strong> — Multiple models available<br>
|
||||
<span style="color: #666; font-size: 12px;">High-quality image generation with OpenAI's models</span>
|
||||
</label>
|
||||
<label style="display: block;">
|
||||
<input type="radio" name="igny8_image_service" value="runware" <?php checked(get_option('igny8_image_service', 'openai'), 'runware'); ?> />
|
||||
<strong>Runware</strong> — $0.036 per image<br>
|
||||
<span style="color: #666; font-size: 12px;">High-quality AI image generation with Runware's models</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
<p class="description">Select the image generation service to use. Each service requires its own API key.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="igny8-openai-models-row" style="display: none;">
|
||||
<th scope="row">OpenAI Image Model</th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<label style="display: block; margin-bottom: 10px;">
|
||||
<input type="radio" name="igny8_image_model" value="dall-e-3" <?php checked(get_option('igny8_image_model', 'dall-e-3'), 'dall-e-3'); ?> />
|
||||
<strong>DALL·E 3</strong> — $0.040 per image<br>
|
||||
<span style="color: #666; font-size: 12px;">High-quality image generation with advanced AI capabilities</span>
|
||||
</label>
|
||||
<label style="display: block; margin-bottom: 10px;">
|
||||
<input type="radio" name="igny8_image_model" value="dall-e-2" <?php checked(get_option('igny8_image_model', 'dall-e-3'), 'dall-e-2'); ?> />
|
||||
<strong>DALL·E 2</strong> — $0.020 per image<br>
|
||||
<span style="color: #666; font-size: 12px;">Cost-effective image generation with good quality</span>
|
||||
</label>
|
||||
<label style="display: block; margin-bottom: 10px;">
|
||||
<input type="radio" name="igny8_image_model" value="gpt-image-1" <?php checked(get_option('igny8_image_model', 'dall-e-3'), 'gpt-image-1'); ?> />
|
||||
<strong>GPT Image 1 (Full)</strong> — $0.042 per image<br>
|
||||
<span style="color: #666; font-size: 12px;">Full-featured image generation with comprehensive capabilities</span>
|
||||
</label>
|
||||
<label style="display: block;">
|
||||
<input type="radio" name="igny8_image_model" value="gpt-image-1-mini" <?php checked(get_option('igny8_image_model', 'dall-e-3'), 'gpt-image-1-mini'); ?> />
|
||||
<strong>GPT Image 1 Mini</strong> — $0.011 per image<br>
|
||||
<span style="color: #666; font-size: 12px;">Lightweight, cost-effective image generation for bulk operations</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
<p class="description">Select the OpenAI image model to use. Pricing shown per image.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="igny8-runware-models-row" style="display: none;">
|
||||
<th scope="row">Runware Image Model</th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<label style="display: block;">
|
||||
<input type="radio" name="igny8_runware_model" value="runware:97@1" <?php checked(get_option('igny8_runware_model', 'runware:97@1'), 'runware:97@1'); ?> />
|
||||
<strong>HiDream-I1 Full</strong> — $0.036 per image<br>
|
||||
<span style="color: #666; font-size: 12px;">High-quality AI image generation with Runware's HiDream model</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
<p class="description">Select the Runware image model to use. Pricing shown per image.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">API Validation</th>
|
||||
<td>
|
||||
<div id="igny8-openai-validation" style="display: none;">
|
||||
<button type="button" id="igny8-test-api" class="button">Test OpenAI Connection</button>
|
||||
<button type="button" id="igny8-test-response" class="button">Test OpenAI Response (Ping)</button>
|
||||
</div>
|
||||
<div id="igny8-runware-validation" style="display: none;">
|
||||
<button type="button" id="igny8-test-runware-btn" class="button">Test Runware Connection</button>
|
||||
<div id="igny8-runware-test-result" style="margin-top: 10px;"></div>
|
||||
</div>
|
||||
<div id="igny8-api-test-result" style="margin-top: 10px;"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php submit_button('Save API Settings'); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Google Search Console API Card -->
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Google Search Console API</h3>
|
||||
<p class="igny8-card-subtitle">Search performance and ranking data integration</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-chart-bar igny8-dashboard-icon-lg igny8-dashboard-icon-orange"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<div style="background: rgba(255, 193, 7, 0.1); border: 1px solid var(--amber); border-radius: var(--radius); padding: 16px; margin-bottom: 20px;">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<span style="font-size: 24px;">⚠️</span>
|
||||
<div>
|
||||
<strong style="color: var(--amber-dark);">Coming Soon</strong><br>
|
||||
<span style="color: var(--text-dim); font-size: 14px;">
|
||||
Google Search Console API integration is currently in development.
|
||||
This will provide search performance data and ranking insights.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="color: var(--text-dim); margin-bottom: 16px;">
|
||||
<strong>Planned Features:</strong>
|
||||
<ul style="margin: 8px 0; padding-left: 20px;">
|
||||
<li>Search performance metrics</li>
|
||||
<li>Keyword ranking data</li>
|
||||
<li>Click-through rate analysis</li>
|
||||
<li>Search appearance insights</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; padding: 20px; background: var(--bg-light); border-radius: var(--radius);">
|
||||
<span style="color: var(--text-dim); font-size: 14px;">
|
||||
Integration will be available in a future update
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- API Request Logs Section -->
|
||||
<div class="igny8-dashboard-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>API Request Logs</h3>
|
||||
<p class="igny8-card-subtitle">Monitor API usage and performance metrics</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-chart-line igny8-dashboard-icon-lg igny8-dashboard-icon-purple"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-card-body">
|
||||
<div id="igny8-api-logs-container">
|
||||
<div class="tablenav top">
|
||||
<div class="alignleft actions">
|
||||
<button type="button" id="igny8-refresh-logs" class="button">Refresh Logs</button>
|
||||
<button type="button" id="igny8-clear-logs" class="button">Clear Logs</button>
|
||||
</div>
|
||||
<div class="alignright actions">
|
||||
<span class="displaying-num">
|
||||
<span id="igny8-logs-count">0</span> API calls
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="widefat fixed striped" id="igny8-api-logs">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Timestamp</th>
|
||||
<th>Status</th>
|
||||
<th>Model</th>
|
||||
<th>Tokens (In/Out)</th>
|
||||
<th>Cost</th>
|
||||
<th>API ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
global $wpdb;
|
||||
$logs = $wpdb->get_results("
|
||||
SELECT * FROM {$wpdb->prefix}igny8_logs
|
||||
WHERE source = 'openai_api'
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 20
|
||||
");
|
||||
|
||||
if ($logs) {
|
||||
foreach ($logs as $log) {
|
||||
$context = json_decode($log->context, true);
|
||||
$status_class = $log->status === 'success' ? 'success' : 'error';
|
||||
$status_icon = $log->status === 'success' ? '✅' : '❌';
|
||||
|
||||
// Debug logging for cost display
|
||||
error_log("Igny8 Display Debug: Log ID=" . $log->id . ", total_cost=" . ($context['total_cost'] ?? 'null') . ", formatted=" . igny8_format_cost($context['total_cost'] ?? 0));
|
||||
|
||||
echo "<tr>
|
||||
<td>" . esc_html($log->created_at) . "</td>
|
||||
<td><span class='igny8-status {$status_class}'>{$status_icon} " . esc_html($log->status) . "</span></td>
|
||||
<td>" . esc_html($context['model'] ?? 'Unknown') . "</td>
|
||||
<td>" . intval($context['input_tokens'] ?? 0) . " / " . intval($context['output_tokens'] ?? 0) . "</td>
|
||||
<td>" . igny8_format_cost($context['total_cost'] ?? 0) . "</td>
|
||||
<td>" . esc_html($log->api_id ? substr($log->api_id, 0, 12) . '...' : 'N/A') . "</td>
|
||||
</tr>";
|
||||
}
|
||||
} else {
|
||||
echo '<tr><td colspan="6">No API logs found.</td></tr>';
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Image Request Logs Section -->
|
||||
<div class="igny8-dashboard-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Image Request Logs</h3>
|
||||
<p class="igny8-card-subtitle">Monitor AI image generation requests and performance</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-format-image igny8-dashboard-icon-lg igny8-dashboard-icon-teal"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-card-body">
|
||||
<div id="igny8-image-logs-container">
|
||||
<div class="tablenav top">
|
||||
<div class="alignleft actions">
|
||||
<button type="button" id="igny8-refresh-image-logs" class="button">Refresh Logs</button>
|
||||
<button type="button" id="igny8-clear-image-logs" class="button">Clear Logs</button>
|
||||
</div>
|
||||
<div class="alignright actions">
|
||||
<span class="displaying-num">
|
||||
<span id="igny8-image-logs-count">0</span> image requests
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="widefat fixed striped" id="igny8-image-logs">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Timestamp</th>
|
||||
<th>Status</th>
|
||||
<th>Model</th>
|
||||
<th>Prompt Length</th>
|
||||
<th>Cost</th>
|
||||
<th>Image Size</th>
|
||||
<th>API ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$image_logs = $wpdb->get_results("
|
||||
SELECT * FROM {$wpdb->prefix}igny8_logs
|
||||
WHERE source = 'openai_image'
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 20
|
||||
");
|
||||
|
||||
if ($image_logs) {
|
||||
foreach ($image_logs as $log) {
|
||||
$context = json_decode($log->context, true);
|
||||
$status_class = $log->status === 'success' ? 'success' : 'error';
|
||||
$status_icon = $log->status === 'success' ? '✅' : '❌';
|
||||
|
||||
echo "<tr>
|
||||
<td>" . esc_html($log->created_at) . "</td>
|
||||
<td><span class='igny8-status {$status_class}'>{$status_icon} " . esc_html($log->status) . "</span></td>
|
||||
<td>" . esc_html($context['model'] ?? 'dall-e-3') . "</td>
|
||||
<td>" . intval($context['prompt_length'] ?? 0) . " chars</td>
|
||||
<td>" . igny8_format_cost($context['total_cost'] ?? 0) . "</td>
|
||||
<td>" . esc_html($context['image_size'] ?? '1024x1024') . "</td>
|
||||
<td>" . esc_html($log->api_id ? substr($log->api_id, 0, 12) . '...' : 'N/A') . "</td>
|
||||
</tr>";
|
||||
}
|
||||
} else {
|
||||
echo '<tr><td colspan="7">No image request logs found.</td></tr>';
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content Engine Settings Section -->
|
||||
<div class="igny8-dashboard-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Content Engine Settings</h3>
|
||||
<p class="igny8-card-subtitle">Personalization and content generation configuration</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-generic igny8-dashboard-icon-lg igny8-dashboard-icon-amber"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-card-body">
|
||||
<div style="background: rgba(59, 130, 246, 0.1); border: 1px solid var(--blue); border-radius: var(--radius); padding: 16px; margin-bottom: 20px;">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<span style="font-size: 24px;">ℹ️</span>
|
||||
<div>
|
||||
<strong style="color: var(--blue-dark);">Settings Moved</strong><br>
|
||||
<span style="color: var(--text-dim); font-size: 14px;">
|
||||
Content Engine settings have been moved to the Personalize module for better organization.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p><strong>Note:</strong> Content Engine settings have been moved to the <a href="<?php echo admin_url('admin.php?page=igny8-personalize&sm=settings'); ?>">Personalize module</a> for better organization.</p>
|
||||
<p>Please configure personalization settings in the Personalize → Settings section.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Third-party Integrations Section -->
|
||||
<div class="igny8-dashboard-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Third-party Integrations</h3>
|
||||
<p class="igny8-card-subtitle">Additional SEO tools and data sources</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-tools igny8-dashboard-icon-lg igny8-dashboard-icon-red"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-card-body">
|
||||
<div style="background: rgba(255, 193, 7, 0.1); border: 1px solid var(--amber); border-radius: var(--radius); padding: 16px; margin-bottom: 20px;">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<span style="font-size: 24px;">⚠️</span>
|
||||
<div>
|
||||
<strong style="color: var(--amber-dark);">Coming Soon</strong><br>
|
||||
<span style="color: var(--text-dim); font-size: 14px;">
|
||||
Additional third-party integrations are currently in development.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div style="padding: 16px; background: var(--bg-light); border-radius: var(--radius);">
|
||||
<h4 style="margin: 0 0 8px 0; color: var(--text-primary);">Ahrefs API</h4>
|
||||
<p style="margin: 0; color: var(--text-dim); font-size: 14px;">Integration with Ahrefs for keyword and backlink data.</p>
|
||||
</div>
|
||||
<div style="padding: 16px; background: var(--bg-light); border-radius: var(--radius);">
|
||||
<h4 style="margin: 0 0 8px 0; color: var(--text-primary);">SEMrush API</h4>
|
||||
<p style="margin: 0; color: var(--text-dim); font-size: 14px;">Integration with SEMrush for competitive analysis.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Handle conditional display of image model options and API validation
|
||||
const imageServiceRadios = document.querySelectorAll('input[name="igny8_image_service"]');
|
||||
const openaiModelsRow = document.getElementById('igny8-openai-models-row');
|
||||
const runwareModelsRow = document.getElementById('igny8-runware-models-row');
|
||||
const openaiValidation = document.getElementById('igny8-openai-validation');
|
||||
const runwareValidation = document.getElementById('igny8-runware-validation');
|
||||
|
||||
function toggleServiceOptions() {
|
||||
const selectedService = document.querySelector('input[name="igny8_image_service"]:checked');
|
||||
if (selectedService) {
|
||||
if (selectedService.value === 'openai') {
|
||||
openaiModelsRow.style.display = 'table-row';
|
||||
runwareModelsRow.style.display = 'none';
|
||||
openaiValidation.style.display = 'block';
|
||||
runwareValidation.style.display = 'none';
|
||||
} else if (selectedService.value === 'runware') {
|
||||
openaiModelsRow.style.display = 'none';
|
||||
runwareModelsRow.style.display = 'table-row';
|
||||
openaiValidation.style.display = 'none';
|
||||
runwareValidation.style.display = 'block';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add event listeners to image service radio buttons
|
||||
imageServiceRadios.forEach(radio => {
|
||||
radio.addEventListener('change', toggleServiceOptions);
|
||||
});
|
||||
|
||||
// Initialize display on page load
|
||||
toggleServiceOptions();
|
||||
|
||||
const testApiButton = document.getElementById('igny8-test-api');
|
||||
const testResponseButton = document.getElementById('igny8-test-response');
|
||||
const refreshLogsButton = document.getElementById('igny8-refresh-logs');
|
||||
const clearLogsButton = document.getElementById('igny8-clear-logs');
|
||||
const refreshImageLogsButton = document.getElementById('igny8-refresh-image-logs');
|
||||
const clearImageLogsButton = document.getElementById('igny8-clear-image-logs');
|
||||
const resultDiv = document.getElementById('igny8-api-test-result');
|
||||
|
||||
// Test API Connection (without I/O messages)
|
||||
if (testApiButton) {
|
||||
testApiButton.addEventListener('click', function() {
|
||||
testApiConnection(false);
|
||||
});
|
||||
}
|
||||
|
||||
// Test API Response (with "test ping")
|
||||
if (testResponseButton) {
|
||||
testResponseButton.addEventListener('click', function() {
|
||||
testApiConnection(true);
|
||||
});
|
||||
}
|
||||
|
||||
// Refresh Logs
|
||||
if (refreshLogsButton) {
|
||||
refreshLogsButton.addEventListener('click', function() {
|
||||
loadApiLogs();
|
||||
});
|
||||
}
|
||||
|
||||
// Clear Logs
|
||||
if (clearLogsButton) {
|
||||
clearLogsButton.addEventListener('click', function() {
|
||||
clearApiLogs();
|
||||
});
|
||||
}
|
||||
|
||||
// Refresh Image Logs
|
||||
if (refreshImageLogsButton) {
|
||||
refreshImageLogsButton.addEventListener('click', function() {
|
||||
loadImageLogs();
|
||||
});
|
||||
}
|
||||
|
||||
// Clear Image Logs
|
||||
if (clearImageLogsButton) {
|
||||
clearImageLogsButton.addEventListener('click', function() {
|
||||
clearImageLogs();
|
||||
});
|
||||
}
|
||||
|
||||
function testApiConnection(withResponse = false) {
|
||||
resultDiv.innerHTML = '<span style="color: blue;">Testing API connection...</span>';
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'igny8_test_api');
|
||||
formData.append('nonce', '<?php echo wp_create_nonce('igny8_ajax_nonce'); ?>');
|
||||
formData.append('with_response', withResponse ? '1' : '0');
|
||||
|
||||
fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
const modelUsed = data.data?.model_used || 'Unknown';
|
||||
const response = data.data?.response || 'No response';
|
||||
const cost = data.data?.cost || 'N/A';
|
||||
const tokens = data.data?.tokens || 'N/A';
|
||||
const tokensSent = data.data?.tokens_sent || 'N/A';
|
||||
const tokensUsed = data.data?.tokens_used || 'N/A';
|
||||
const totalTokens = data.data?.total_tokens || 'N/A';
|
||||
|
||||
resultDiv.innerHTML = `
|
||||
<div style="color: green; margin-bottom: 10px;">
|
||||
✓ API connection successful!
|
||||
</div>
|
||||
<div style="background: #f0f8ff; padding: 10px; border-radius: 4px; border-left: 4px solid #0073aa;">
|
||||
<strong>Model Used:</strong> ${modelUsed}<br>
|
||||
${withResponse ? `<strong>Expected:</strong> "OK! Ping Received"<br><strong>Actual Response:</strong> "${response}"<br>` : ''}
|
||||
<strong>Token Limit Sent:</strong> ${tokensSent} (from your settings)<br>
|
||||
<strong>Tokens Used:</strong> ${tokensUsed} (input/output)<br>
|
||||
<strong>Total Tokens:</strong> ${totalTokens}<br>
|
||||
<strong>Cost:</strong> ${cost}
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Refresh logs to show new entry
|
||||
setTimeout(() => loadApiLogs(), 1000);
|
||||
} else {
|
||||
const errorMessage = data.data?.message || 'Unknown error';
|
||||
const errorDetails = data.data?.details || '';
|
||||
resultDiv.innerHTML = `
|
||||
<div style="color: red; margin-bottom: 10px;">
|
||||
✗ API connection failed: ${errorMessage}
|
||||
</div>
|
||||
${errorDetails ? `<div style="background: #fff2f2; padding: 10px; border-radius: 4px; border-left: 4px solid #dc3232; font-size: 12px; color: #666;">
|
||||
<strong>Details:</strong> ${errorDetails}
|
||||
</div>` : ''}
|
||||
`;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
resultDiv.innerHTML = '<span style="color: red;">✗ API connection failed: ' + error.message + '</span>';
|
||||
});
|
||||
}
|
||||
|
||||
function loadApiLogs() {
|
||||
fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
action: 'igny8_get_api_logs',
|
||||
nonce: '<?php echo wp_create_nonce('igny8_ajax_nonce'); ?>'
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
const logsTable = document.querySelector('#igny8-api-logs tbody');
|
||||
const logsCount = document.getElementById('igny8-logs-count');
|
||||
|
||||
if (logsTable) {
|
||||
logsTable.innerHTML = data.data.html;
|
||||
}
|
||||
if (logsCount) {
|
||||
logsCount.textContent = data.data.total;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error loading logs:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function clearApiLogs() {
|
||||
if (!confirm('Are you sure you want to clear all API logs? This action cannot be undone.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
action: 'igny8_clear_api_logs',
|
||||
nonce: '<?php echo wp_create_nonce('igny8_ajax_nonce'); ?>'
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
loadApiLogs();
|
||||
alert('API logs cleared successfully!');
|
||||
} else {
|
||||
alert('Error clearing logs: ' + (data.data?.message || 'Unknown error'));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error clearing logs:', error);
|
||||
alert('Error clearing logs: ' + error.message);
|
||||
});
|
||||
}
|
||||
|
||||
function loadImageLogs() {
|
||||
fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
action: 'igny8_get_image_logs',
|
||||
nonce: '<?php echo wp_create_nonce('igny8_ajax_nonce'); ?>'
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
const logsTable = document.querySelector('#igny8-image-logs tbody');
|
||||
const logsCount = document.getElementById('igny8-image-logs-count');
|
||||
|
||||
if (logsTable) {
|
||||
logsTable.innerHTML = data.data.html;
|
||||
}
|
||||
if (logsCount) {
|
||||
logsCount.textContent = data.data.total;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error loading image logs:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function clearImageLogs() {
|
||||
if (!confirm('Are you sure you want to clear all image request logs? This action cannot be undone.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
action: 'igny8_clear_image_logs',
|
||||
nonce: '<?php echo wp_create_nonce('igny8_ajax_nonce'); ?>'
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
loadImageLogs();
|
||||
alert('Image request logs cleared successfully!');
|
||||
} else {
|
||||
alert('Error clearing image logs: ' + (data.data?.message || 'Unknown error'));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error clearing image logs:', error);
|
||||
alert('Error clearing image logs: ' + error.message);
|
||||
});
|
||||
}
|
||||
|
||||
// Load logs on page load
|
||||
loadApiLogs();
|
||||
loadImageLogs();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.igny8-status.success {
|
||||
color: #46b450;
|
||||
font-weight: bold;
|
||||
}
|
||||
.igny8-status.error {
|
||||
color: #dc3232;
|
||||
font-weight: bold;
|
||||
}
|
||||
#igny8-api-logs {
|
||||
margin-top: 15px;
|
||||
}
|
||||
#igny8-api-logs th {
|
||||
background: #f1f1f1;
|
||||
font-weight: bold;
|
||||
}
|
||||
#igny8-api-logs td {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
297
igny8-ai-seo-wp-plugin/modules/settings/schedules.php
Normal file
297
igny8-ai-seo-wp-plugin/modules/settings/schedules.php
Normal file
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
/**
|
||||
* ==========================
|
||||
* 🔐 IGNY8 FILE RULE HEADER
|
||||
* ==========================
|
||||
* @file : schedules.php
|
||||
* @location : /modules/settings/schedules.php
|
||||
* @type : Admin Page
|
||||
* @scope : Module Only
|
||||
* @allowed : Automation scheduling, cron configuration, timing settings
|
||||
* @reusability : Single Use
|
||||
* @notes : Automation schedules configuration page for settings module
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Start output buffering
|
||||
ob_start();
|
||||
|
||||
// Load master dispatcher functions
|
||||
if (!function_exists('igny8_get_defined_cron_jobs')) {
|
||||
include_once plugin_dir_path(__FILE__) . '../../core/cron/igny8-cron-master-dispatcher.php';
|
||||
}
|
||||
|
||||
|
||||
// Handle form submission
|
||||
if (isset($_POST['igny8_save_cron_settings']) && wp_verify_nonce($_POST['igny8_cron_nonce'], 'igny8_cron_settings')) {
|
||||
$cron_jobs = $_POST['cron_jobs'] ?? [];
|
||||
$cron_settings = get_option('igny8_cron_settings', []);
|
||||
$cron_limits = get_option('igny8_cron_limits', []);
|
||||
|
||||
// Update settings for each job
|
||||
foreach ($cron_jobs as $job_name => $job_data) {
|
||||
$cron_settings[$job_name] = [
|
||||
'enabled' => isset($job_data['enabled']),
|
||||
'last_run' => $cron_settings[$job_name]['last_run'] ?? 0
|
||||
];
|
||||
|
||||
// Update limits
|
||||
if (isset($job_data['limit'])) {
|
||||
$cron_limits[$job_name] = intval($job_data['limit']);
|
||||
}
|
||||
}
|
||||
|
||||
update_option('igny8_cron_settings', $cron_settings);
|
||||
update_option('igny8_cron_limits', $cron_limits);
|
||||
|
||||
echo '<div class="notice notice-success"><p>Settings saved successfully!</p></div>';
|
||||
}
|
||||
|
||||
// Get current data
|
||||
$defined_jobs = igny8_get_defined_cron_jobs();
|
||||
$cron_settings = get_option('igny8_cron_settings', []);
|
||||
$cron_limits = get_option('igny8_cron_limits', []);
|
||||
$last_execution = get_option('igny8_cron_last_execution', []);
|
||||
|
||||
// Initialize defaults if needed
|
||||
if (empty($cron_settings)) {
|
||||
$cron_settings = igny8_get_default_cron_settings();
|
||||
update_option('igny8_cron_settings', $cron_settings);
|
||||
}
|
||||
|
||||
if (empty($cron_limits)) {
|
||||
$cron_limits = igny8_get_default_cron_limits();
|
||||
update_option('igny8_cron_limits', $cron_limits);
|
||||
}
|
||||
|
||||
// Get health status for all jobs
|
||||
$health_status = [];
|
||||
foreach ($defined_jobs as $job_name => $job_config) {
|
||||
$health_status[$job_name] = igny8_get_job_health_status($job_name);
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="wrap igny8-admin-page">
|
||||
|
||||
<!-- Smart Automation Jobs Table -->
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Smart Automation Jobs</h3>
|
||||
<p class="igny8-card-subtitle">Configure and manage all automation jobs</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-tools igny8-dashboard-icon-lg igny8-dashboard-icon-purple"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('igny8_cron_settings', 'igny8_cron_nonce'); ?>
|
||||
|
||||
<table class="igny8-table" data-cron-key="<?php echo esc_attr(get_option('igny8_secure_cron_key')); ?>">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Job Name</th>
|
||||
<th>Module</th>
|
||||
<th>Enable</th>
|
||||
<th>Max Items</th>
|
||||
<th>Last Run</th>
|
||||
<th>Execution Time</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($defined_jobs as $job_name => $job_config):
|
||||
// Skip crons if their respective modules are disabled
|
||||
$analytics_crons = ['igny8_process_ai_queue_cron', 'igny8_auto_recalc_cron', 'igny8_health_check_cron'];
|
||||
$writer_crons = ['igny8_auto_generate_content_cron', 'igny8_auto_generate_images_cron', 'igny8_auto_publish_drafts_cron'];
|
||||
$optimizer_crons = ['igny8_auto_optimizer_cron'];
|
||||
|
||||
if (in_array($job_name, $analytics_crons) && !igny8_is_module_enabled('analytics')) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($job_name, $writer_crons) && !igny8_is_module_enabled('writer')) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($job_name, $optimizer_crons) && !igny8_is_module_enabled('optimizer')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$job_settings = $cron_settings[$job_name] ?? [];
|
||||
$job_status = igny8_get_cron_job_status($job_name);
|
||||
$job_health = $health_status[$job_name];
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<strong><?php echo esc_html($job_config['description']); ?></strong>
|
||||
</td>
|
||||
<td>
|
||||
<span class="igny8-module-badge igny8-module-<?php echo esc_attr($job_config['module']); ?>">
|
||||
<?php echo esc_html(ucfirst($job_config['module'])); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<label class="igny8-toggle">
|
||||
<input type="checkbox" name="cron_jobs[<?php echo esc_attr($job_name); ?>][enabled]"
|
||||
<?php checked($job_settings['enabled'] ?? false); ?>>
|
||||
<span class="igny8-toggle-slider"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" name="cron_jobs[<?php echo esc_attr($job_name); ?>][limit]"
|
||||
value="<?php echo esc_attr($cron_limits[$job_name] ?? 10); ?>"
|
||||
min="1" max="100" style="width: 60px;">
|
||||
<?php
|
||||
// Add descriptive text based on job type
|
||||
$item_text = '';
|
||||
switch($job_name) {
|
||||
case 'igny8_auto_cluster_cron':
|
||||
$item_text = 'keywords';
|
||||
break;
|
||||
case 'igny8_auto_generate_ideas_cron':
|
||||
$item_text = 'clusters';
|
||||
break;
|
||||
case 'igny8_auto_queue_cron':
|
||||
$item_text = 'ideas';
|
||||
break;
|
||||
case 'igny8_auto_generate_content_cron':
|
||||
$item_text = 'tasks';
|
||||
break;
|
||||
case 'igny8_auto_generate_images_cron':
|
||||
$item_text = 'posts';
|
||||
break;
|
||||
case 'igny8_auto_publish_drafts_cron':
|
||||
$item_text = 'drafts';
|
||||
break;
|
||||
case 'igny8_process_ai_queue_cron':
|
||||
$item_text = 'tasks';
|
||||
break;
|
||||
case 'igny8_auto_recalc_cron':
|
||||
$item_text = 'items';
|
||||
break;
|
||||
default:
|
||||
$item_text = 'items';
|
||||
}
|
||||
echo ' <small style="color: #666; font-size: 12px;">' . $item_text . '</small>';
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo esc_html($job_health['last_run']); ?>
|
||||
<?php if (!empty($job_health['result_details'])): ?>
|
||||
<br><small style="color: <?php echo ($job_health['last_success'] === true) ? '#28a745' : '#dc3545'; ?>;">
|
||||
<?php echo esc_html($job_health['result_details']); ?>
|
||||
<?php if ($job_health['last_success'] === true): ?>
|
||||
✓
|
||||
<?php else: ?>
|
||||
✗
|
||||
<?php endif; ?>
|
||||
</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$execution_time = $job_health['execution_time'] ?? 0;
|
||||
echo $execution_time > 0 ? number_format($execution_time, 2) . 's' : 'N/A';
|
||||
?>
|
||||
<?php if (!empty($job_health['execution_method'])): ?>
|
||||
<br><small style="color: #666;">
|
||||
via <?php echo esc_html($job_health['execution_method']); ?>
|
||||
</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="igny8-align-center igny8-actions">
|
||||
<button class="igny8-icon-only igny8-icon-external" data-action="openInNewWindow" data-hook="<?php echo esc_attr($job_name); ?>" title="Open in New Window">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
|
||||
<polyline points="15,3 21,3 21,9"></polyline>
|
||||
<line x1="10" y1="14" x2="21" y2="3"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="submit">
|
||||
<input type="submit" name="igny8_save_cron_settings" class="button-primary" value="Save All Settings">
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Master Scheduler Status -->
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Master Scheduler Configuration</h3>
|
||||
<p class="igny8-card-subtitle">Single cron job manages all automation</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-clock igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<p><strong>Single cPanel Configuration Required:</strong></p>
|
||||
<code>*/5 * * * * curl -s "https://<?php echo $_SERVER['HTTP_HOST']; ?>/wp-load.php?import_key=<?php echo get_option('igny8_secure_cron_key'); ?>&import_id=igny8_cron&action=master_scheduler" > /dev/null 2>&1</code>
|
||||
<p><em>This single cron job will intelligently manage all automation based on your settings below.</em></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- System Overview -->
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>System Overview</h3>
|
||||
<p class="igny8-card-subtitle">Current automation system status</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-dashboard igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<?php
|
||||
$total_jobs = count($defined_jobs);
|
||||
$enabled_jobs = count(array_filter($cron_settings, function($settings) { return $settings['enabled'] ?? false; }));
|
||||
$scheduled_jobs = count(array_filter($health_status, function($status) { return $status['enabled']; }));
|
||||
$failed_jobs = count(array_filter($health_status, function($status) { return $status['last_success'] === false; }));
|
||||
?>
|
||||
<div class="igny8-stats-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 20px; margin: 20px 0;">
|
||||
<div class="igny8-metric-item" style="background: var(--panel); border: 1px solid var(--stroke); border-radius: var(--radius); padding: 15px; text-align: center;">
|
||||
<h4 style="margin: 0 0 10px 0; color: var(--blue-dark);">Total Jobs</h4>
|
||||
<p style="margin: 0; font-size: 24px; font-weight: 700; color: var(--text);"><?php echo esc_html($total_jobs); ?></p>
|
||||
</div>
|
||||
<div class="igny8-metric-item" style="background: var(--panel); border: 1px solid var(--stroke); border-radius: var(--radius); padding: 15px; text-align: center;">
|
||||
<h4 style="margin: 0 0 10px 0; color: var(--green-dark);">Enabled Jobs</h4>
|
||||
<p style="margin: 0; font-size: 24px; font-weight: 700; color: var(--text);"><?php echo esc_html($enabled_jobs); ?></p>
|
||||
</div>
|
||||
<div class="igny8-metric-item" style="background: var(--panel); border: 1px solid var(--stroke); border-radius: var(--radius); padding: 15px; text-align: center;">
|
||||
<h4 style="margin: 0 0 10px 0; color: var(--amber-dark);">Scheduled Jobs</h4>
|
||||
<p style="margin: 0; font-size: 24px; font-weight: 700; color: var(--text);"><?php echo esc_html($scheduled_jobs); ?></p>
|
||||
</div>
|
||||
<div class="igny8-metric-item" style="background: var(--panel); border: 1px solid var(--stroke); border-radius: var(--radius); padding: 15px; text-align: center;">
|
||||
<h4 style="margin: 0 0 10px 0; color: var(--red-dark);">Failed Jobs</h4>
|
||||
<p style="margin: 0; font-size: 24px; font-weight: 700; color: var(--text);"><?php echo esc_html($failed_jobs); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
// Capture page content
|
||||
$igny8_page_content = ob_get_clean();
|
||||
|
||||
// Include global layout
|
||||
include plugin_dir_path(__FILE__) . '../../core/global-layout.php';
|
||||
?>
|
||||
353
igny8-ai-seo-wp-plugin/modules/settings/status.php
Normal file
353
igny8-ai-seo-wp-plugin/modules/settings/status.php
Normal file
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
/**
|
||||
* ==========================
|
||||
* 🔐 IGNY8 FILE RULE HEADER
|
||||
* ==========================
|
||||
* @file : status.php
|
||||
* @location : /modules/settings/status.php
|
||||
* @type : Admin Page
|
||||
* @scope : Module Only
|
||||
* @allowed : System status monitoring, health checks, diagnostics
|
||||
* @reusability : Single Use
|
||||
* @notes : System status monitoring page for settings module
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
?>
|
||||
<!-- System Status Section -->
|
||||
<div class="igny8-dashboard-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>System Status</h3>
|
||||
<p class="igny8-card-subtitle">Monitor system health and component status</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-site igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Debug Monitoring & System Layers Section -->
|
||||
<div class="igny8-grid-2 igny8-dashboard-section" style="
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
">
|
||||
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Debug Monitoring</h3>
|
||||
<p class="igny8-card-subtitle">Real-time debug monitoring controls and status</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-tools igny8-dashboard-icon-lg igny8-dashboard-icon-orange"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<p style="color: var(--text-dim); margin-bottom: 16px;">Enable or disable submodule debug monitoring for Planner, Writer, Linker, Optimizer and Personalize</p>
|
||||
|
||||
<!-- Real-time Monitoring Controls -->
|
||||
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 20px;">
|
||||
<div style="font-size: 13px; color: var(--text-dim); text-align: right;">
|
||||
Real-time Monitoring
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 8px;">
|
||||
<div style="display: flex; align-items: center; gap: 4px;">
|
||||
<input type="radio" id="debug-enabled" name="debug_monitoring" value="1" <?php echo get_option('igny8_debug_enabled', false) ? 'checked' : ''; ?>>
|
||||
<label for="debug-enabled" style="font-size: 12px; color: var(--text-dim);">On</label>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 4px;">
|
||||
<input type="radio" id="debug-disabled" name="debug_monitoring" value="0" <?php echo !get_option('igny8_debug_enabled', false) ? 'checked' : ''; ?>>
|
||||
<label for="debug-disabled" style="font-size: 12px; color: var(--text-dim);">Off</label>
|
||||
</div>
|
||||
<button type="button" id="save-debug-setting" class="igny8-btn igny8-btn-primary">
|
||||
<span class="dashicons dashicons-yes-alt" style="font-size: 14px;"></span>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Current Status Display -->
|
||||
<?php
|
||||
$debug_enabled = get_option('igny8_debug_enabled', false);
|
||||
$status_text = $debug_enabled ? 'Enabled' : 'Disabled';
|
||||
$status_color = $debug_enabled ? 'var(--green-dark)' : 'var(--red-dark)';
|
||||
$status_icon = $debug_enabled ? '✅' : '❌';
|
||||
|
||||
// Set background and border colors based on status
|
||||
if ($debug_enabled) {
|
||||
$status_bg = 'rgba(16,185,129,0.1)';
|
||||
$status_border = 'var(--green)';
|
||||
} else {
|
||||
$status_bg = 'rgba(239,68,68,0.1)';
|
||||
$status_border = 'var(--red)';
|
||||
}
|
||||
?>
|
||||
<div style="background: <?php echo $status_bg; ?>; border: 1px solid <?php echo $status_border; ?>; border-radius: var(--radius); padding: 16px; margin-top: 16px;">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<span style="font-size: 24px;"><?php echo $status_icon; ?></span>
|
||||
<div>
|
||||
<strong style="color: <?php echo $status_color; ?>;">Debug Monitoring: <?php echo $status_text; ?></strong><br>
|
||||
<span style="color: var(--text-dim); font-size: 14px;">
|
||||
<?php if ($debug_enabled): ?>
|
||||
Real-time debug monitoring is active for all submodules. Debug cards and status indicators are visible on submodule pages.
|
||||
<?php else: ?>
|
||||
Debug monitoring is disabled. Debug cards and status indicators are hidden on submodule pages.
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>System Layers</h3>
|
||||
<p class="igny8-card-subtitle">System layer health and operational metrics</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-chart-bar igny8-dashboard-icon-lg igny8-dashboard-icon-teal"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<!-- Metrics Row -->
|
||||
<div class="igny8-metrics-row">
|
||||
<div class="igny8-metric">
|
||||
<div class="igny8-metric-value">100%</div>
|
||||
<div class="igny8-metric-label">Layer Health</div>
|
||||
</div>
|
||||
<div class="igny8-metric">
|
||||
<div class="igny8-metric-value" style="color: var(--green);">6</div>
|
||||
<div class="igny8-metric-label">Operational</div>
|
||||
</div>
|
||||
<div class="igny8-metric">
|
||||
<div class="igny8-metric-value" style="color: var(--red-dark);">0</div>
|
||||
<div class="igny8-metric-label">Failed</div>
|
||||
</div>
|
||||
<div class="igny8-metric">
|
||||
<div class="igny8-metric-value">6</div>
|
||||
<div class="igny8-metric-label">Total Layers</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Layer Status Circles -->
|
||||
<div class="igny8-flex" style="justify-content: center; gap: 16px; margin: 20px 0;">
|
||||
<?php
|
||||
$layer_labels = [
|
||||
'database_system' => 'DB',
|
||||
'configuration_system' => 'CFG',
|
||||
'rendering_system' => 'RND',
|
||||
'javascript_ajax' => 'JS',
|
||||
'component_functionality' => 'CMP',
|
||||
'data_flow' => 'FLW'
|
||||
];
|
||||
|
||||
foreach ($layer_labels as $layer_key => $label):
|
||||
$layer_status = true; // Simplified - always true for basic layer summary
|
||||
$status_class = $layer_status ? 'bg-success' : 'bg-error';
|
||||
?>
|
||||
<div class="bg-circle <?php echo $status_class; ?>" title="<?php echo ucfirst(str_replace('_', ' ', $layer_key)); ?>: <?php echo $layer_status ? 'Operational' : 'Failed'; ?>">
|
||||
<?php echo $label; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div style="background: rgba(16,185,129,0.1); border: 1px solid var(--green); border-radius: var(--radius); padding: 16px; margin-top: 16px;">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<span style="font-size: 24px;">✅</span>
|
||||
<div>
|
||||
<strong style="color: var(--green-dark);">All Layers Operational</strong><br>
|
||||
<span style="color: var(--text-dim); font-size: 14px;">
|
||||
All 6 layers are functioning correctly.
|
||||
The Igny8 plugin is operating at full capacity.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- System Information & Database Status Section -->
|
||||
<div class="igny8-dashboard-section">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>System Information & Database Status</h3>
|
||||
<p class="igny8-card-subtitle">System details, database tables, and module status</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-site igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4 Cards Grid -->
|
||||
<div class="igny8-grid igny8-grid-4">
|
||||
|
||||
<!-- Card 1: System Information & API Status -->
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>System & API Info</h3>
|
||||
<p class="igny8-card-subtitle">System information and API configuration status</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-site igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<div style="margin-bottom: 15px;">
|
||||
<div style="font-weight: bold; margin-bottom: 8px; color: #333;">System Information</div>
|
||||
<div style="font-size: 12px; margin-bottom: 4px;"><strong>Plugin:</strong> <?php echo get_option('igny8_version', 'Unknown'); ?></div>
|
||||
<div style="font-size: 12px; margin-bottom: 4px;"><strong>WordPress:</strong> <?php echo get_bloginfo('version'); ?></div>
|
||||
<div style="font-size: 12px; margin-bottom: 4px;"><strong>PHP:</strong> <?php echo PHP_VERSION; ?></div>
|
||||
<div style="font-size: 12px; margin-bottom: 4px;"><strong>MySQL:</strong> <?php global $wpdb; echo $wpdb->db_version(); ?></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div style="font-weight: bold; margin-bottom: 8px; color: #333;">API Status</div>
|
||||
<?php
|
||||
$api_key = get_option('igny8_api_key');
|
||||
$api_configured = !empty($api_key);
|
||||
$api_status_color = $api_configured ? 'green' : 'red';
|
||||
$api_status_icon = $api_configured ? '✓' : '✗';
|
||||
?>
|
||||
<div style="font-size: 12px; margin-bottom: 4px; color: <?php echo $api_status_color; ?>;">
|
||||
<strong>OpenAI API:</strong> <?php echo $api_status_icon; ?> <?php echo $api_configured ? 'Configured' : 'Not Configured'; ?>
|
||||
</div>
|
||||
<div style="font-size: 12px; margin-bottom: 4px;"><strong>Model:</strong> <?php echo get_option('igny8_model', 'gpt-4.1'); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card 2: Database Tables Part 1 -->
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Database Tables 1</h3>
|
||||
<p class="igny8-card-subtitle">Core database tables status and health</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-database igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<?php
|
||||
global $wpdb;
|
||||
$tables_part1 = [
|
||||
'igny8_keywords' => 'Keywords',
|
||||
'igny8_tasks' => 'Tasks',
|
||||
'igny8_data' => 'Data',
|
||||
'igny8_variations' => 'Variations',
|
||||
'igny8_rankings' => 'Rankings',
|
||||
'igny8_suggestions' => 'Suggestions',
|
||||
'igny8_campaigns' => 'Campaigns'
|
||||
];
|
||||
|
||||
foreach ($tables_part1 as $table => $name) {
|
||||
$table_name = $wpdb->prefix . $table;
|
||||
$exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name;
|
||||
$status_color = $exists ? 'green' : 'red';
|
||||
$status_icon = $exists ? '✓' : '✗';
|
||||
echo "<div style='font-size: 12px; margin-bottom: 3px; color: $status_color;'>$status_icon $name</div>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card 3: Database Tables Part 2 -->
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Database Tables 2</h3>
|
||||
<p class="igny8-card-subtitle">Extended database tables status and health</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-database igny8-dashboard-icon-lg igny8-dashboard-icon-purple"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<?php
|
||||
$tables_part2 = [
|
||||
'igny8_content_ideas' => 'Content Ideas',
|
||||
'igny8_clusters' => 'Clusters',
|
||||
'igny8_sites' => 'Sites',
|
||||
'igny8_backlinks' => 'Backlinks',
|
||||
'igny8_mapping' => 'Mapping',
|
||||
'igny8_prompts' => 'Prompts',
|
||||
'igny8_logs' => 'Logs'
|
||||
];
|
||||
|
||||
foreach ($tables_part2 as $table => $name) {
|
||||
$table_name = $wpdb->prefix . $table;
|
||||
$exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name;
|
||||
$status_color = $exists ? 'green' : 'red';
|
||||
$status_icon = $exists ? '✓' : '✗';
|
||||
echo "<div style='font-size: 12px; margin-bottom: 3px; color: $status_color;'>$status_icon $name</div>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card 4: Module Status -->
|
||||
<div class="igny8-card">
|
||||
<div class="igny8-standard-header">
|
||||
<div class="igny8-card-header-content">
|
||||
<div class="igny8-card-title-text">
|
||||
<h3>Module Status</h3>
|
||||
<p class="igny8-card-subtitle">Plugin modules activation and status</p>
|
||||
</div>
|
||||
<div class="igny8-card-icon">
|
||||
<span class="dashicons dashicons-admin-tools igny8-dashboard-icon-lg igny8-dashboard-icon-amber"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-card-body">
|
||||
<?php
|
||||
$modules = [
|
||||
'planner' => 'Planner',
|
||||
'writer' => 'Writer',
|
||||
'personalize' => 'Personalize',
|
||||
'optimizer' => 'Optimizer',
|
||||
'linker' => 'Linker'
|
||||
];
|
||||
|
||||
foreach ($modules as $module => $name) {
|
||||
$enabled = get_option("igny8_{$module}_enabled", true);
|
||||
$status_color = $enabled ? 'green' : 'red';
|
||||
$status_icon = $enabled ? '✓' : '✗';
|
||||
echo "<div style='font-size: 12px; margin-bottom: 3px; color: $status_color;'>$status_icon $name</div>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
if (typeof window.initializeDebugToggle === 'function') {
|
||||
window.initializeDebugToggle();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user