reference plugin and image gen analysis

This commit is contained in:
Desktop
2025-11-11 21:16:37 +05:00
parent fedf415646
commit f4d62448cf
111 changed files with 49595 additions and 3988 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,135 @@
<?php
/**
* ==========================
* 🔐 IGNY8 FILE RULE HEADER
* ==========================
* @file : init.php
* @location : /core/admin/init.php
* @type : Function Library
* @scope : Global
* @allowed : Admin initialization, settings registration, asset enqueuing
* @reusability : Globally Reusable
* @notes : WordPress admin initialization and settings management
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
/**
* ------------------------------------------------------------------------
* ADMIN INITIALIZATION BOOTSTRAP
* ------------------------------------------------------------------------
*/
add_action('admin_init', 'igny8_register_settings');
/**
* ------------------------------------------------------------------------
* SETTINGS REGISTRATION
* ------------------------------------------------------------------------
*/
function igny8_register_settings() {
$groups = igny8_get_settings_config();
foreach ($groups as $group => $settings) {
foreach ($settings as $name => $config) {
register_setting($group, $name, $config);
}
}
}
/**
* Settings Configuration (grouped)
*/
function igny8_get_settings_config() {
return [
'igny8_table_settings' => [
'igny8_records_per_page' => [
'type' => 'integer',
'default' => 20,
'sanitize_callback' => 'absint'
]
],
'igny8_ai_integration_settings' => [
'igny8_ai_cluster_building' => ['type' => 'string', 'default' => 'enabled', 'sanitize_callback' => 'sanitize_text_field'],
'igny8_ai_content_ideas' => ['type' => 'string', 'default' => 'enabled', 'sanitize_callback' => 'sanitize_text_field'],
'igny8_ai_auto_mapping' => ['type' => 'string', 'default' => 'enabled', 'sanitize_callback' => 'sanitize_text_field']
],
'igny8_api_settings' => [
'igny8_api_key' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_text_field'],
'igny8_runware_api_key' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_text_field'],
'igny8_model' => ['type' => 'string', 'default' => 'gpt-4.1', 'sanitize_callback' => 'sanitize_text_field'],
'igny8_image_service' => ['type' => 'string', 'default' => 'openai', 'sanitize_callback' => 'sanitize_text_field'],
'igny8_image_model' => ['type' => 'string', 'default' => 'dall-e-3', 'sanitize_callback' => 'sanitize_text_field'],
'igny8_runware_model' => ['type' => 'string', 'default' => 'runware:97@1', 'sanitize_callback' => 'sanitize_text_field']
],
'igny8_personalize_settings_group' => [
'igny8_content_engine_global_status' => ['sanitize_callback' => 'igny8_sanitize_checkbox_setting'],
'igny8_content_engine_enabled_post_types' => ['sanitize_callback' => 'igny8_sanitize_array_setting'],
'igny8_content_engine_insertion_position' => ['sanitize_callback' => 'sanitize_text_field'],
'igny8_content_engine_display_mode' => ['sanitize_callback' => 'sanitize_text_field'],
'igny8_content_engine_teaser_text' => ['sanitize_callback' => 'sanitize_textarea_field'],
'igny8_content_engine_save_variations' => ['sanitize_callback' => 'intval'],
'igny8_content_engine_field_mode' => ['sanitize_callback' => 'sanitize_text_field'],
'igny8_content_engine_detection_prompt' => ['sanitize_callback' => 'sanitize_textarea_field'],
'igny8_content_engine_context_source' => ['sanitize_callback' => 'sanitize_textarea_field'],
'igny8_content_engine_include_page_context' => ['sanitize_callback' => 'intval'],
'igny8_content_engine_content_length' => ['sanitize_callback' => 'sanitize_text_field'],
'igny8_content_engine_rewrite_prompt' => ['sanitize_callback' => 'sanitize_textarea_field'],
'igny8_content_engine_fixed_fields_config' => ['sanitize_callback' => 'igny8_sanitize_fields_config']
]
];
}
/**
* ------------------------------------------------------------------------
* SANITIZATION HELPERS
* ------------------------------------------------------------------------
*/
function igny8_sanitize_checkbox_setting($raw) {
return isset($_POST['igny8_content_engine_global_status']) ? 'enabled' : 'disabled';
}
function igny8_sanitize_array_setting($raw) {
return is_array($raw) ? array_map('sanitize_text_field', $raw) : [];
}
function igny8_sanitize_fields_config($raw) {
if (!is_array($raw)) return [];
$sanitized = [];
foreach ($raw as $index => $field) {
$sanitized[$index] = [
'label' => sanitize_text_field($field['label'] ?? ''),
'type' => sanitize_text_field($field['type'] ?? 'text'),
'options' => sanitize_text_field($field['options'] ?? '')
];
}
return $sanitized;
}
// MOVED TO: igny8.php - Admin assets enqueuing moved to main plugin file
// ---------------------------------------------------------------------
// WORDPRESS FEATURE REGISTRATION
// ---------------------------------------------------------------------
function igny8_init_wordpress_features() {
// Initialize module manager
add_action('init', 'igny8_module_manager');
// Register taxonomies
add_action('init', 'igny8_register_taxonomies');
// Register post meta once
add_action('init', function() {
if (!get_option('igny8_post_meta_registered')) {
igny8_register_post_meta();
update_option('igny8_post_meta_registered', true);
}
});
}
//Initialize WordPress features
igny8_init_wordpress_features();

View File

@@ -0,0 +1,356 @@
<?php
/**
* ==========================
* 🔐 IGNY8 FILE RULE HEADER
* ==========================
* @file : menu.php
* @location : /core/admin/menu.php
* @type : Admin Menu Handler
* @scope : Global
* @allowed : WordPress admin menu registration, navigation helpers, layout functions
* @reusability : Globally Reusable
* @notes : Registers admin menus and provides breadcrumb/submenu rendering functions
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
/**
* Render breadcrumb navigation
*/
function igny8_render_breadcrumb() {
$current_page = $_GET['page'] ?? '';
$sm = $_GET['sm'] ?? '';
$breadcrumb = '<nav class="igny8-breadcrumb-nav">';
$breadcrumb .= '<span class="igny8-breadcrumb-item"><a href="' . admin_url('admin.php?page=igny8-home') . '">Igny8 Home</a></span>';
if ($current_page === 'igny8-planner') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item"><a href="' . admin_url('admin.php?page=igny8-planner') . '">Planner</a></span>';
if ($sm === 'keywords') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Keywords</span>';
} elseif ($sm === 'clusters') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Clusters</span>';
} elseif ($sm === 'ideas') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Ideas</span>';
} elseif ($sm === 'mapping') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Mapping</span>';
}
} elseif ($current_page === 'igny8-writer') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item"><a href="' . admin_url('admin.php?page=igny8-writer') . '">Writer</a></span>';
if ($sm === 'drafts') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Drafts</span>';
} elseif ($sm === 'templates') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Templates</span>';
}
} elseif ($current_page === 'igny8-optimizer') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item"><a href="' . admin_url('admin.php?page=igny8-optimizer') . '">Optimizer</a></span>';
if ($sm === 'audits') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Audits</span>';
} elseif ($sm === 'suggestions') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Suggestions</span>';
}
} elseif ($current_page === 'igny8-linker') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item"><a href="' . admin_url('admin.php?page=igny8-linker') . '">Linker</a></span>';
if ($sm === 'backlinks') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Backlinks</span>';
} elseif ($sm === 'campaigns') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Campaigns</span>';
}
} elseif ($current_page === 'igny8-personalize') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item"><a href="' . admin_url('admin.php?page=igny8-personalize') . '">Personalize</a></span>';
if ($sm === 'settings') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Settings</span>';
} elseif ($sm === 'content-generation') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Content Generation</span>';
} elseif ($sm === 'rewrites') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Rewrites</span>';
} elseif ($sm === 'front-end') {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Front-end</span>';
}
} elseif (strpos($current_page, 'igny8-analytics') !== false) {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Analytics</span>';
} elseif (strpos($current_page, 'igny8-schedules') !== false) {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Schedules</span>';
} elseif (strpos($current_page, 'igny8-settings') !== false) {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Settings</span>';
} elseif (strpos($current_page, 'igny8-help') !== false) {
$breadcrumb .= '<span class="igny8-breadcrumb-separator"></span>';
$breadcrumb .= '<span class="igny8-breadcrumb-item active">Help</span>';
}
$breadcrumb .= '</nav>';
return $breadcrumb;
}
/**
* Render submenu navigation
*/
function igny8_render_submenu() {
$current_page = $_GET['page'] ?? '';
$sm = $_GET['sm'] ?? '';
$submenu = '';
if ($current_page === 'igny8-planner') {
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-planner&sm=home') . '" class="igny8-btn igny8-btn-sm igny8-btn-success igny8-btn-submenu' . ($sm === 'home' || $sm === '' ? ' active' : '') . '">Dashboard</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-planner&sm=keywords') . '" class="igny8-btn igny8-btn-sm igny8-btn-success igny8-btn-submenu' . ($sm === 'keywords' ? ' active' : '') . '">Keywords</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-planner&sm=clusters') . '" class="igny8-btn igny8-btn-sm igny8-btn-success igny8-btn-submenu' . ($sm === 'clusters' ? ' active' : '') . '">Clusters</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-planner&sm=ideas') . '" class="igny8-btn igny8-btn-sm igny8-btn-success igny8-btn-submenu' . ($sm === 'ideas' ? ' active' : '') . '">Ideas</a>';
} elseif ($current_page === 'igny8-writer') {
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-writer&sm=home') . '" class="igny8-btn igny8-btn-sm igny8-btn-primary igny8-btn-submenu' . ($sm === 'home' || $sm === '' ? ' active' : '') . '">Dashboard</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-writer&sm=tasks') . '" class="igny8-btn igny8-btn-sm igny8-btn-primary igny8-btn-submenu' . ($sm === 'tasks' ? ' active' : '') . '">Tasks</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-writer&sm=drafts') . '" class="igny8-btn igny8-btn-sm igny8-btn-primary igny8-btn-submenu' . ($sm === 'drafts' ? ' active' : '') . '">Drafts</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-writer&sm=published') . '" class="igny8-btn igny8-btn-sm igny8-btn-primary igny8-btn-submenu' . ($sm === 'published' ? ' active' : '') . '">Published</a>';
} elseif ($current_page === 'igny8-thinker') {
$sp = $_GET['sp'] ?? 'main';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-thinker&sp=main') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'main' ? ' active' : '') . '">Dashboard</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-thinker&sp=prompts') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'prompts' ? ' active' : '') . '">Prompts</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-thinker&sp=profile') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'profile' ? ' active' : '') . '">Profile</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-thinker&sp=strategies') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'strategies' ? ' active' : '') . '">Strategies</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-thinker&sp=image-testing') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'image-testing' ? ' active' : '') . '">Image Testing</a>';
} elseif ($current_page === 'igny8-optimizer') {
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-optimizer') . '" class="igny8-btn igny8-btn-sm igny8-btn-warning igny8-btn-submenu' . ($sm === '' ? ' active' : '') . '">Dashboard</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-optimizer&sm=audits') . '" class="igny8-btn igny8-btn-sm igny8-btn-warning igny8-btn-submenu' . ($sm === 'audits' ? ' active' : '') . '">Audits</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-optimizer&sm=suggestions') . '" class="igny8-btn igny8-btn-sm igny8-btn-warning igny8-btn-submenu' . ($sm === 'suggestions' ? ' active' : '') . '">Suggestions</a>';
} elseif ($current_page === 'igny8-linker') {
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-linker') . '" class="igny8-btn igny8-btn-sm igny8-btn-info igny8-btn-submenu' . ($sm === '' ? ' active' : '') . '">Dashboard</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-linker&sm=backlinks') . '" class="igny8-btn igny8-btn-sm igny8-btn-info igny8-btn-submenu' . ($sm === 'backlinks' ? ' active' : '') . '">Backlinks</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-linker&sm=campaigns') . '" class="igny8-btn igny8-btn-sm igny8-btn-info igny8-btn-submenu' . ($sm === 'campaigns' ? ' active' : '') . '">Campaigns</a>';
} elseif ($current_page === 'igny8-personalize') {
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-personalize') . '" class="igny8-btn igny8-btn-sm igny8-btn-secondary igny8-btn-submenu' . ($sm === '' ? ' active' : '') . '">Dashboard</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-personalize&sm=settings') . '" class="igny8-btn igny8-btn-sm igny8-btn-secondary igny8-btn-submenu' . ($sm === 'settings' ? ' active' : '') . '">Settings</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-personalize&sm=content-generation') . '" class="igny8-btn igny8-btn-sm igny8-btn-secondary igny8-btn-submenu' . ($sm === 'content-generation' ? ' active' : '') . '">Content Generation</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-personalize&sm=rewrites') . '" class="igny8-btn igny8-btn-sm igny8-btn-secondary igny8-btn-submenu' . ($sm === 'rewrites' ? ' active' : '') . '">Rewrites</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-personalize&sm=front-end') . '" class="igny8-btn igny8-btn-sm igny8-btn-secondary igny8-btn-submenu' . ($sm === 'front-end' ? ' active' : '') . '">Front-end</a>';
} elseif ($current_page === 'igny8-settings') {
$sp = $_GET['sp'] ?? 'general';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-settings&sp=general') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'general' ? ' active' : '') . '">Settings</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-settings&sp=status') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'status' ? ' active' : '') . '">Status</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-settings&sp=integration') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'integration' ? ' active' : '') . '">Integration</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-settings&sp=import-export') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'import-export' ? ' active' : '') . '">Import/Export</a>';
} elseif ($current_page === 'igny8-help') {
$sp = $_GET['sp'] ?? 'help';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-help&sp=help') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'help' ? ' active' : '') . '">Help & Support</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-help&sp=docs') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'docs' ? ' active' : '') . '">Documentation</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-help&sp=system-testing') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'system-testing' ? ' active' : '') . '">System Testing</a>';
$submenu .= '<a href="' . admin_url('admin.php?page=igny8-help&sp=function-testing') . '" class="igny8-btn igny8-btn-sm igny8-btn-outline igny8-btn-submenu' . ($sp === 'function-testing' ? ' active' : '') . '">Function Testing</a>';
}
return $submenu;
}
/**
* Register admin menu pages
*/
function igny8_register_admin_menu() {
// Ensure module manager is available
if (!function_exists('igny8_is_module_enabled')) {
return;
}
// Main menu page
add_menu_page(
'Igny8 AI SEO', // Page title
'Igny8 AI SEO', // Menu title
'manage_options', // Capability
'igny8-home', // Menu slug
'igny8_home_page', // Callback function
'dashicons-chart-line', // Icon
30 // Position
);
// Home page
add_submenu_page(
'igny8-home', // Parent slug
'Dashboard', // Page title
'Dashboard', // Menu title
'manage_options', // Capability
'igny8-home', // Menu slug
'igny8_home_page' // Callback function
);
// Module submenus (only if enabled)
if (igny8_is_module_enabled('planner')) {
add_submenu_page(
'igny8-home',
'Content Planner',
'Planner',
'manage_options',
'igny8-planner',
'igny8_planner_page'
);
}
if (igny8_is_module_enabled('writer')) {
add_submenu_page(
'igny8-home',
'Content Writer',
'Writer',
'manage_options',
'igny8-writer',
'igny8_writer_page'
);
}
if (igny8_is_module_enabled('thinker')) {
add_submenu_page(
'igny8-home',
'AI Thinker',
'Thinker',
'manage_options',
'igny8-thinker',
'igny8_thinker_page'
);
// Prompts subpage under Thinker
add_submenu_page(
'igny8-thinker',
'AI Prompts',
'Prompts',
'manage_options',
'igny8-thinker&sp=prompts',
'igny8_thinker_page'
);
}
if (igny8_is_module_enabled('schedules')) {
add_submenu_page(
'igny8-home',
'Smart Automation Schedules',
'Schedules',
'manage_options',
'igny8-schedules',
'igny8_schedules_page'
);
}
// Analytics before Settings (only if enabled)
if (igny8_is_module_enabled('analytics')) {
add_submenu_page(
'igny8-home',
'Analytics',
'Analytics',
'manage_options',
'igny8-analytics',
'igny8_analytics_page'
);
}
// Cron Health page
// Settings page
add_submenu_page(
'igny8-home',
'Settings',
'Settings',
'manage_options',
'igny8-settings',
'igny8_settings_page'
);
// Help page
add_submenu_page(
'igny8-home',
'Help',
'Help',
'manage_options',
'igny8-help',
'igny8_help_page'
);
// Documentation subpage under Help
add_submenu_page(
'igny8-help',
'Documentation',
'Documentation',
'manage_options',
'igny8-help&sp=docs',
'igny8_help_page'
);
// System Testing subpage under Help
add_submenu_page(
'igny8-help',
'System Testing',
'System Testing',
'manage_options',
'igny8-help&sp=system-testing',
'igny8_help_page'
);
// Function Testing subpage under Help
add_submenu_page(
'igny8-help',
'Function Testing',
'Function Testing',
'manage_options',
'igny8-help&sp=function-testing',
'igny8_help_page'
);
}
// Static page wrapper functions - each page handles its own layout
function igny8_home_page() {
include_once plugin_dir_path(__FILE__) . '../../modules/home.php';
}
function igny8_planner_page() {
include_once plugin_dir_path(__FILE__) . '../../modules/planner/planner.php';
}
function igny8_writer_page() {
include_once plugin_dir_path(__FILE__) . '../../modules/writer/writer.php';
}
function igny8_thinker_page() {
include_once plugin_dir_path(__FILE__) . '../../modules/thinker/thinker.php';
}
function igny8_settings_page() {
include_once plugin_dir_path(__FILE__) . '../../modules/settings/general-settings.php';
}
function igny8_analytics_page() {
include_once plugin_dir_path(__FILE__) . '../../modules/analytics/analytics.php';
}
function igny8_schedules_page() {
include_once plugin_dir_path(__FILE__) . '../../modules/settings/schedules.php';
}
function igny8_help_page() {
include_once plugin_dir_path(__FILE__) . '../../modules/help/help.php';
}
// Hook into admin_menu
add_action('admin_menu', 'igny8_register_admin_menu');

View File

@@ -0,0 +1,387 @@
<?php
/**
* ==========================
* 🔐 IGNY8 FILE RULE HEADER
* ==========================
* @file : meta-boxes.php
* @location : /core/admin/meta-boxes.php
* @type : Function Library
* @scope : Global
* @allowed : Meta box registration, SEO field management
* @reusability : Globally Reusable
* @notes : SEO meta boxes for post editor
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// === SEO Meta Box ===
add_action('add_meta_boxes', function() {
// SEO fields
add_meta_box('igny8_seo_meta', 'Igny8 SEO Fields', function($post) {
$meta_title = get_post_meta($post->ID, '_igny8_meta_title', true);
$meta_desc = get_post_meta($post->ID, '_igny8_meta_description', true);
$primary_kw = get_post_meta($post->ID, '_igny8_primary_keywords', true);
$secondary_kw = get_post_meta($post->ID, '_igny8_secondary_keywords', true);
?>
<div style="padding:8px 4px;">
<label><strong>Meta Title:</strong></label><br>
<input type="text" name="_igny8_meta_title" value="<?php echo esc_attr($meta_title); ?>" style="width:100%;"><br><br>
<label><strong>Meta Description:</strong></label><br>
<textarea name="_igny8_meta_description" rows="3" style="width:100%;"><?php echo esc_textarea($meta_desc); ?></textarea><br><br>
<label><strong>Primary Keyword:</strong></label><br>
<input type="text" name="_igny8_primary_keywords" value="<?php echo esc_attr($primary_kw); ?>" style="width:100%;"><br><br>
<label><strong>Secondary Keywords (comma-separated):</strong></label><br>
<input type="text" name="_igny8_secondary_keywords" value="<?php echo esc_attr($secondary_kw); ?>" style="width:100%;">
</div>
<?php
}, ['post','page','product'], 'normal', 'high');
});
// === Save Meta Box Data ===
add_action('save_post', function($post_id) {
// Security checks
if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) {
return;
}
// Save SEO fields
$fields = [
'_igny8_meta_title',
'_igny8_meta_description',
'_igny8_primary_keywords',
'_igny8_secondary_keywords',
];
foreach ($fields as $field) {
if (isset($_POST[$field])) {
update_post_meta($post_id, $field, sanitize_text_field($_POST[$field]));
}
}
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log("Igny8 Metabox: SEO fields saved for post $post_id");
}
});
// === In-Article Image Gallery Meta Box ===
add_action('add_meta_boxes', function() {
$enabled_post_types = get_option('igny8_enable_image_metabox', []);
foreach ((array) $enabled_post_types as $pt) {
add_meta_box(
'igny8_image_gallery',
'Igny8 In-Article Images',
'igny8_render_image_gallery_metabox',
$pt,
'side',
'high'
);
}
});
function igny8_render_image_gallery_metabox($post) {
wp_nonce_field('igny8_save_image_gallery', 'igny8_image_gallery_nonce');
$images = get_post_meta($post->ID, '_igny8_inarticle_images', true);
if (!is_array($images)) $images = [];
// Add CSS for grid layout and remove button
?>
<style>
.igny8-image-list {
display: flex;
flex-wrap: wrap;
list-style: none;
margin: 0;
padding: 0;
gap: 5px;
}
.igny8-image-list li {
width: 200px;
margin: 0 5px 5px 0;
box-sizing: border-box;
text-align: center;
position: relative;
border: 1px solid #eee;
padding: 5px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 180px;
}
.igny8-image-list li img {
display: block;
margin: 0 auto 5px auto;
}
.igny8-image-actions {
position: absolute;
bottom: 5px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 5px;
opacity: 0;
transition: opacity 0.2s ease;
z-index: 10;
}
.igny8-image-list li:hover .igny8-image-actions {
opacity: 1;
}
.igny8-remove-btn, .igny8-replace-btn {
background: #f0f0f0;
border: 1px solid #ccc;
color: #333;
font-size: 10px;
padding: 2px 6px;
cursor: pointer;
border-radius: 2px;
text-decoration: none;
white-space: nowrap;
}
.igny8-remove-btn:hover {
background: #dc3232;
color: #fff;
border-color: #dc3232;
}
.igny8-replace-btn:hover {
background: #0073aa;
color: #fff;
border-color: #0073aa;
}
.igny8-image-list li strong {
font-size: 0.8em;
word-break: break-all;
}
</style>
<?php
echo '<div id="igny8-image-gallery">';
echo '<p><label><input type="radio" name="igny8_image_type" value="desktop" checked> Desktop</label>
<label><input type="radio" name="igny8_image_type" value="mobile"> Mobile</label></p>';
echo '<button type="button" class="button button-primary" id="igny8-add-image">Add Image</button>';
echo '<ul class="igny8-image-list">';
// Sort images by device type and ID
$sorted_images = [];
foreach ($images as $label => $data) {
$sorted_images[$label] = $data;
}
// Custom sort function to order by device type (desktop first) then by ID
uksort($sorted_images, function($a, $b) {
$a_parts = explode('-', $a);
$b_parts = explode('-', $b);
$a_device = $a_parts[0];
$b_device = $b_parts[0];
// Desktop comes before mobile
if ($a_device === 'desktop' && $b_device === 'mobile') return -1;
if ($a_device === 'mobile' && $b_device === 'desktop') return 1;
// If same device, sort by ID number
if ($a_device === $b_device) {
$a_id = intval($a_parts[1]);
$b_id = intval($b_parts[1]);
return $a_id - $b_id;
}
return 0;
});
foreach ($sorted_images as $label => $data) {
echo '<li data-label="' . esc_attr($label) . '">';
echo '<strong>' . esc_html($label) . '</strong><br>';
echo wp_get_attachment_image($data['attachment_id'], 'thumbnail', false, ['style' => 'width: 150px; height: 150px; object-fit: cover;']);
echo '<div class="igny8-image-actions">';
echo '<button type="button" class="igny8-replace-btn">Replace</button>';
echo '<button type="button" class="igny8-remove-btn">Remove</button>';
echo '</div>';
echo '<input type="hidden" name="igny8_image_data[' . esc_attr($label) . '][attachment_id]" value="' . esc_attr($data['attachment_id']) . '">';
echo '<input type="hidden" name="igny8_image_data[' . esc_attr($label) . '][device]" value="' . esc_attr($data['device']) . '">';
echo '</li>';
}
echo '</ul>';
// Inline JS
?>
<script>
jQuery(document).ready(function($) {
// Function to get first available ID for a device type
function getFirstAvailableId(deviceType) {
let existingIds = [];
$('.igny8-image-list li').each(function() {
let label = $(this).data('label');
if (label && label.startsWith(deviceType + '-')) {
let id = parseInt(label.split('-')[1]);
if (!isNaN(id)) {
existingIds.push(id);
}
}
});
// Sort existing IDs and find first gap
existingIds.sort((a, b) => a - b);
for (let i = 1; i <= existingIds.length + 1; i++) {
if (!existingIds.includes(i)) {
return i;
}
}
return 1; // Fallback
}
$('#igny8-add-image').on('click', function(e) {
e.preventDefault();
let type = $('input[name="igny8_image_type"]:checked').val() || 'desktop';
let availableId = getFirstAvailableId(type);
let label = type + '-' + availableId;
const frame = wp.media({
title: 'Select Image',
button: { text: 'Use this image' },
multiple: false
});
frame.on('select', function() {
let attachment = frame.state().get('selection').first().toJSON();
let html = '<li data-label="' + label + '">' +
'<strong>' + label + '</strong><br>' +
'<img src="' + attachment.sizes.thumbnail.url + '" style="width: 150px; height: 150px; object-fit: cover;" /><br>' +
'<div class="igny8-image-actions">' +
'<button type="button" class="igny8-replace-btn">Replace</button>' +
'<button type="button" class="igny8-remove-btn">Remove</button>' +
'</div>' +
'<input type="hidden" name="igny8_image_data[' + label + '][attachment_id]" value="' + attachment.id + '">' +
'<input type="hidden" name="igny8_image_data[' + label + '][device]" value="' + type + '">' +
'</li>';
$('.igny8-image-list').append(html);
});
frame.open();
});
// Handle image removal (event delegation for dynamically added elements)
$(document).on('click', '.igny8-remove-btn', function() {
$(this).closest('li').remove();
});
// Handle image replacement (event delegation for dynamically added elements)
$(document).on('click', '.igny8-replace-btn', function() {
let $li = $(this).closest('li');
let label = $li.data('label');
let type = label.split('-')[0];
const frame = wp.media({
title: 'Replace Image',
button: { text: 'Replace this image' },
multiple: false
});
frame.on('select', function() {
let attachment = frame.state().get('selection').first().toJSON();
// Replace the entire img element to force reload
let $img = $li.find('img');
let newImg = $('<img>').attr({
'src': attachment.sizes.thumbnail.url,
'style': 'width: 150px; height: 150px; object-fit: cover;'
});
$img.replaceWith(newImg);
// Update the hidden input
$li.find('input[name*="[attachment_id]"]').val(attachment.id);
});
frame.open();
});
// Handle Convert Content to Blocks
$('#igny8-convert-to-blocks').on('click', function(e) {
e.preventDefault();
if (!confirm('This will convert the post content from HTML to WordPress blocks. Continue?')) {
return;
}
let $button = $(this);
let originalText = $button.text();
$button.prop('disabled', true).text('Converting...');
// Get post ID from the current post
let postId = $('#post_ID').val();
// Make AJAX request to convert content to blocks
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'igny8_convert_content_to_blocks',
post_id: postId,
nonce: '<?php echo wp_create_nonce('igny8_convert_to_blocks'); ?>'
},
success: function(response) {
console.log('Convert to Blocks Response:', response);
if (response.success) {
console.log('Success data:', response.data);
alert('Content converted successfully! ' + response.data.message);
location.reload();
} else {
console.error('Error data:', response.data);
alert('Error: ' + (response.data || 'Unknown error'));
}
},
error: function(xhr, status, error) {
console.error('Convert to Blocks Error:', {status, error, responseText: xhr.responseText});
alert('Error converting content. Check console for details.');
},
complete: function() {
$button.prop('disabled', false).text(originalText);
}
});
});
});
</script>
<?php
}
// SAVE HANDLER for Image Gallery
add_action('save_post', function($post_id) {
if (!isset($_POST['igny8_image_gallery_nonce']) || !wp_verify_nonce($_POST['igny8_image_gallery_nonce'], 'igny8_save_image_gallery')) return;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!current_user_can('edit_post', $post_id)) return;
$images = $_POST['igny8_image_data'] ?? [];
$filtered = [];
foreach ($images as $label => $data) {
if (!empty($data['attachment_id'])) {
$filtered[$label] = [
'label' => sanitize_text_field($label),
'attachment_id' => intval($data['attachment_id']),
'url' => wp_get_attachment_url(intval($data['attachment_id'])),
'device' => sanitize_text_field($data['device'])
];
}
}
update_post_meta($post_id, '_igny8_inarticle_images', $filtered);
if (WP_DEBUG === true) {
error_log("[IGNY8 DEBUG] Saving In-Article Images for Post ID: $post_id");
error_log(print_r($filtered, true));
}
});

View File

@@ -0,0 +1,181 @@
<?php
/**
* ==========================
* 🔐 IGNY8 FILE RULE HEADER
* ==========================
* @file : module-manager-class.php
* @location : /core/admin/module-manager-class.php
* @type : Function Library
* @scope : Global
* @allowed : Module management, class definitions, core functionality
* @reusability : Globally Reusable
* @notes : Module manager class for core functionality
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
/**
* Igny8 Module Manager - Controls which modules are active
*/
class Igny8_Module_Manager {
private static $instance = null;
private $modules = [];
public static function get_instance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init_modules();
add_action('admin_init', [$this, 'register_module_settings']);
}
/**
* Initialize module definitions - main modules only
*/
private function init_modules() {
$this->modules = [
'planner' => [
'name' => 'Planner',
'description' => 'Keyword research and content planning with clusters, ideas, and mapping tools.',
'default' => true,
'icon' => 'dashicons-search',
'category' => 'main',
'cron_jobs' => [
'igny8_auto_cluster_cron',
'igny8_auto_generate_ideas_cron',
'igny8_auto_queue_cron'
]
],
'writer' => [
'name' => 'Writer',
'description' => 'AI-powered content generation with drafts and templates management.',
'default' => false,
'icon' => 'dashicons-edit',
'category' => 'main',
'cron_jobs' => [
'igny8_auto_generate_content_cron',
'igny8_auto_generate_images_cron',
'igny8_auto_publish_drafts_cron'
]
],
'analytics' => [
'name' => 'Analytics',
'description' => 'Performance tracking and data analysis with comprehensive reporting.',
'default' => false,
'icon' => 'dashicons-chart-bar',
'category' => 'admin',
'cron_jobs' => [
'igny8_process_ai_queue_cron',
'igny8_auto_recalc_cron',
'igny8_health_check_cron'
]
],
'schedules' => [
'name' => 'Schedules',
'description' => 'Content scheduling and automation with calendar management.',
'default' => false,
'icon' => 'dashicons-calendar-alt',
'category' => 'admin'
],
'thinker' => [
'name' => 'AI Thinker',
'description' => 'AI-powered content strategy, prompts, and intelligent content planning tools.',
'default' => true,
'icon' => 'dashicons-lightbulb',
'category' => 'admin'
]
];
}
/**
* Check if a module is enabled
*/
public function is_module_enabled($module) {
$settings = get_option('igny8_module_settings', []);
return isset($settings[$module]) ? (bool) $settings[$module] : (isset($this->modules[$module]) ? $this->modules[$module]['default'] : false);
}
/**
* Get all enabled modules
*/
public function get_enabled_modules() {
$enabled = [];
foreach ($this->modules as $key => $module) {
if ($this->is_module_enabled($key)) {
$enabled[$key] = $module;
}
}
return $enabled;
}
/**
* Get all modules
*/
public function get_modules() {
return $this->modules;
}
/**
* Register module settings
*/
public function register_module_settings() {
register_setting('igny8_module_settings', 'igny8_module_settings');
}
/**
* Save module settings
*/
public function save_module_settings() {
if (!isset($_POST['igny8_module_nonce']) || !wp_verify_nonce($_POST['igny8_module_nonce'], 'igny8_module_settings')) {
wp_die('Security check failed');
}
$settings = $_POST['igny8_module_settings'] ?? [];
// Initialize all modules as disabled first
$all_modules = $this->get_modules();
$final_settings = [];
foreach ($all_modules as $module_key => $module) {
$final_settings[$module_key] = false; // Default to disabled
}
// Set enabled modules to true
foreach ($settings as $key => $value) {
if (isset($final_settings[$key])) {
$final_settings[$key] = (bool) $value;
}
}
update_option('igny8_module_settings', $final_settings);
// Force page reload using JavaScript
echo '<script>window.location.reload();</script>';
exit;
}
}
// Initialize the module manager
function igny8_module_manager() {
return Igny8_Module_Manager::get_instance();
}
// Helper functions for easy access
function igny8_is_module_enabled($module) {
return igny8_module_manager()->is_module_enabled($module);
}
function igny8_get_enabled_modules() {
return igny8_module_manager()->get_enabled_modules();
}
function igny8_get_modules() {
return igny8_module_manager()->get_modules();
}