$current_module,
'submodule' => $current_submodule,
'table_id' => $table_id,
'page' => $_GET['page'] ?? ''
];
}
/**
* Track AI Logs State
*/
function igny8_track_ai_logs_state($module_info) {
// Check if AI functions are available
if (!function_exists('igny8_get_ai_setting')) {
return [
'status' => 'error',
'message' => 'AI system not available',
'details' => 'igny8_get_ai_setting function missing'
];
}
// Check AI mode
$ai_mode = igny8_get_ai_setting('planner_mode', 'manual');
$ai_enabled = $ai_mode === 'ai';
// Get recent AI logs (last 10 events)
$ai_logs = get_option('igny8_ai_logs', []);
$recent_logs = array_slice($ai_logs, 0, 10);
$log_count = count($recent_logs);
$error_count = 0;
$success_count = 0;
foreach ($recent_logs as $log) {
if ($log['status'] === 'error') {
$error_count++;
} elseif ($log['status'] === 'success') {
$success_count++;
}
}
$details = [
'AI Mode: ' . ($ai_enabled ? '✅ Enabled' : '❌ Disabled'),
'Recent Events: ' . $log_count,
'Success: ' . $success_count . ' | Errors: ' . $error_count,
'Module: ' . $module_info['module'],
'Submodule: ' . ($module_info['submodule'] ?: 'NONE')
];
if ($ai_enabled && $log_count > 0) {
$status = $error_count === 0 ? 'success' : ($error_count < $success_count ? 'warning' : 'error');
$message = "AI Logs: {$log_count} events ({$success_count} success, {$error_count} errors)";
} elseif ($ai_enabled) {
$status = 'success';
$message = 'AI Logs: Ready (no events yet)';
} else {
$status = 'warning';
$message = 'AI Logs: AI mode disabled';
}
return [
'status' => $status,
'message' => $message,
'details' => implode('
', $details)
];
}
/**
* Track Database Validation State
*/
function igny8_track_database_validation_state() {
$module_info = igny8_get_current_module_info();
$table_id = $module_info['table_id'];
// Get actual database table name and fields
global $wpdb;
$table_name = igny8_get_table_name($table_id);
if (!$table_name) {
return [
'status' => 'error',
'message' => 'Table not found',
'details' => 'Table ID: ' . $table_id . ' - No table name mapping found'
];
}
// Get actual database fields
$db_fields = [];
$table_exists = $wpdb->get_var("SHOW TABLES LIKE '{$table_name}'") !== null;
if ($table_exists) {
$columns = $wpdb->get_results("DESCRIBE {$table_name}");
foreach ($columns as $column) {
$db_fields[] = $column->Field;
}
} else {
return [
'status' => 'error',
'message' => 'Database table missing',
'details' => 'Table: ' . $table_name . ' does not exist in database'
];
}
// Validate table config fields
$table_errors = igny8_validate_table_config_fields($table_id, $db_fields);
$filter_errors = igny8_validate_filter_config_fields($table_id, $db_fields);
$form_errors = igny8_validate_form_config_fields($table_id, $db_fields);
$total_errors = count($table_errors) + count($filter_errors) + count($form_errors);
if ($total_errors === 0) {
return [
'status' => 'success',
'message' => 'Database validation passed',
'details' => 'Table: ✅
Filters: ✅
Forms: ✅
Automation: ✅'
];
} else {
$error_details = [];
// Format table errors
if (!empty($table_errors)) {
// Filter out config errors and show only field names
$field_errors = array_filter($table_errors, function($error) {
return !strpos($error, 'config') && !strpos($error, 'missing');
});
if (!empty($field_errors)) {
$error_details[] = 'Table:
' . implode(', ', $field_errors) . ' mismatch with db, doesn\'t exist';
}
}
// Format filter errors
if (!empty($filter_errors)) {
// Filter out config errors and show only field names
$field_errors = array_filter($filter_errors, function($error) {
return !strpos($error, 'config') && !strpos($error, 'missing');
});
if (!empty($field_errors)) {
$error_details[] = 'Filters:
' . implode(', ', $field_errors) . ' mismatch with db, doesn\'t exist';
}
}
// Format form errors
if (!empty($form_errors)) {
// Filter out config errors and show only field names
$field_errors = array_filter($form_errors, function($error) {
return !strpos($error, 'config') && !strpos($error, 'missing');
});
if (!empty($field_errors)) {
$error_details[] = 'Forms:
' . implode(', ', $field_errors) . ' mismatch with db, doesn\'t exist';
}
}
// If no field errors, show config errors
if (empty($error_details)) {
if (!empty($table_errors)) {
$error_details[] = 'Table:
' . implode(', ', $table_errors);
}
if (!empty($filter_errors)) {
$error_details[] = 'Filters:
' . implode(', ', $filter_errors);
}
if (!empty($form_errors)) {
$error_details[] = 'Forms:
' . implode(', ', $form_errors);
}
}
return [
'status' => 'error',
'message' => 'Database validation failed',
'details' => implode('
', $error_details)
];
}
}
/**
* Validate table config fields against database schema
*/
function igny8_validate_table_config_fields($table_id, $db_fields) {
$errors = [];
try {
// Load config file directly
$config_path = plugin_dir_path(__FILE__) . '../modules/config/tables-config.php';
if (!file_exists($config_path)) {
return ['tables_config_file_missing'];
}
// Define constant to bypass access control
if (!defined('IGNY8_INCLUDE_CONFIG')) {
define('IGNY8_INCLUDE_CONFIG', true);
}
$tables_config = require $config_path;
if (!isset($tables_config[$table_id])) {
return ['table_config_not_found'];
}
$table_config = $tables_config[$table_id];
// Check columns
if (isset($table_config['columns'])) {
foreach ($table_config['columns'] as $column_name => $column_config) {
// For display columns, check the source_field instead of the column name
$field_to_check = $column_name;
if (isset($column_config['source_field'])) {
$field_to_check = $column_config['source_field'];
}
if (!in_array($field_to_check, $db_fields)) {
$errors[] = $column_name;
}
}
}
// Check humanize_columns
if (isset($table_config['humanize_columns'])) {
foreach ($table_config['humanize_columns'] as $column_name) {
if (!in_array($column_name, $db_fields)) {
$errors[] = $column_name;
}
}
}
} catch (Exception $e) {
$errors[] = 'config_load_error: ' . $e->getMessage();
}
return $errors;
}
/**
* Validate filter config fields against database schema
*/
function igny8_validate_filter_config_fields($table_id, $db_fields) {
$errors = [];
try {
// Load config file directly
$config_path = plugin_dir_path(__FILE__) . '../modules/config/filters-config.php';
if (!file_exists($config_path)) {
return ['filters_config_file_missing'];
}
// Define constant to bypass access control
if (!defined('IGNY8_INCLUDE_CONFIG')) {
define('IGNY8_INCLUDE_CONFIG', true);
}
$filters_config = require $config_path;
if (!isset($filters_config[$table_id])) {
return []; // No filters config is OK
}
$filter_config = $filters_config[$table_id];
foreach ($filter_config as $filter_name => $filter_data) {
if (isset($filter_data['field']) && !in_array($filter_data['field'], $db_fields)) {
$errors[] = $filter_data['field'];
}
}
} catch (Exception $e) {
$errors[] = 'config_load_error: ' . $e->getMessage();
}
return $errors;
}
/**
* Validate form config fields against database schema
*/
function igny8_validate_form_config_fields($table_id, $db_fields) {
$errors = [];
try {
// Load config file directly
$config_path = plugin_dir_path(__FILE__) . '../modules/config/forms-config.php';
if (!file_exists($config_path)) {
return ['forms_config_file_missing'];
}
// Define constant to bypass access control
if (!defined('IGNY8_INCLUDE_CONFIG')) {
define('IGNY8_INCLUDE_CONFIG', true);
}
$forms_config = require $config_path;
if (!isset($forms_config[$table_id])) {
return []; // No form config is OK
}
$form_config = $forms_config[$table_id];
if (!$form_config || !isset($form_config['fields'])) {
return []; // No form config is OK
}
foreach ($form_config['fields'] as $field) {
if (isset($field['name']) && !in_array($field['name'], $db_fields)) {
$errors[] = $field['name'];
}
}
} catch (Exception $e) {
$errors[] = 'config_load_error: ' . $e->getMessage();
}
return $errors;
}
function igny8_test_column_type_validation($config_data, $table_id) {
if (!isset($config_data[$table_id]['columns'])) {
return ['passed' => false, 'error' => 'no columns'];
}
$columns = $config_data[$table_id]['columns'];
foreach ($columns as $key => $column) {
if (!isset($column['type']) || !in_array($column['type'], ['text', 'number', 'date', 'select', 'textarea', 'enum'])) {
return ['passed' => false, 'error' => 'invalid type: ' . $key];
}
}
return ['passed' => true, 'error' => ''];
}
function igny8_test_filter_field_validation($config_data, $table_id) {
if (!isset($config_data[$table_id])) {
return ['passed' => false, 'error' => 'no filters'];
}
$filters = $config_data[$table_id];
foreach ($filters as $key => $filter) {
if (!isset($filter['field']) || empty($filter['field'])) {
return ['passed' => false, 'error' => 'missing field: ' . $key];
}
}
return ['passed' => true, 'error' => ''];
}
function igny8_test_field_validation_check($config_data, $table_id) {
if (!function_exists('igny8_get_form_config')) {
return ['passed' => false, 'error' => 'function missing'];
}
$form_config = igny8_get_form_config($table_id);
if (!$form_config || !isset($form_config['fields'])) {
return ['passed' => false, 'error' => 'no form fields'];
}
foreach ($form_config['fields'] as $field) {
if (!isset($field['name']) || !isset($field['type'])) {
return ['passed' => false, 'error' => 'invalid field structure'];
}
// Test foreign key relationships
if (isset($field['type']) && $field['type'] === 'select' && (isset($field['options']) || isset($field['source']))) {
$fk_result = igny8_test_foreign_key_relationship($field, $table_id);
if (!$fk_result['passed']) {
return ['passed' => false, 'error' => 'FK issue: ' . $field['name'] . ' - ' . $fk_result['error']];
}
}
}
return ['passed' => true, 'error' => ''];
}
function igny8_test_foreign_key_relationship($field, $table_id) {
// Check if this is a foreign key field (like cluster_id, category_id, etc.)
$field_name = $field['name'];
// Common foreign key patterns
$fk_patterns = ['cluster_id', 'category_id', 'parent_id', 'user_id', 'group_id'];
$is_foreign_key = false;
foreach ($fk_patterns as $pattern) {
if (strpos($field_name, $pattern) !== false) {
$is_foreign_key = true;
break;
}
}
if (!$is_foreign_key) {
return ['passed' => true, 'error' => '']; // Not a foreign key, skip test
}
// CRITICAL ISSUE: Check if field uses 'source' with custom select rendering
if (isset($field['source']) && $field['type'] === 'select') {
// This is the cluster_id issue - custom select button vs form submission mismatch
return ['passed' => false, 'error' => 'custom select rendering - form submission mismatch'];
}
return ['passed' => true, 'error' => ''];
}
function igny8_test_query_syntax_validation($config_data, $table_id) {
if (!isset($config_data[$table_id])) {
return ['passed' => false, 'error' => 'no kpi config'];
}
$kpis = $config_data[$table_id];
foreach ($kpis as $key => $kpi) {
if (!isset($kpi['query']) || empty($kpi['query'])) {
return ['passed' => false, 'error' => 'missing query: ' . $key];
}
// Check for basic SQL syntax
if (!preg_match('/SELECT.*FROM.*\{table_name\}/i', $kpi['query'])) {
return ['passed' => false, 'error' => 'invalid query syntax: ' . $key];
}
}
return ['passed' => true, 'error' => ''];
}
/**
* Track Routing State
*/
function igny8_track_routing_state() {
$module_info = igny8_get_current_module_info();
$current_page = $_GET['page'] ?? '';
$current_submodule = $_GET['sm'] ?? '';
$routing_ok = !empty($current_page) && strpos($current_page, 'igny8-') === 0;
$submodule_ok = !empty($current_submodule);
return [
'status' => $routing_ok ? 'success' : 'error',
'message' => "Routing: {$current_page}" . ($submodule_ok ? " → {$current_submodule}" : ""),
'details' => "Table ID: {$module_info['table_id']}"
];
}
/**
* Track Initial Render State
*/
function igny8_track_initial_render_state() {
$module_info = igny8_get_current_module_info();
$table_id = $module_info['table_id'];
$render_functions = [
'igny8_render_filters' => 'Filters',
'igny8_render_table_actions' => 'Actions',
'igny8_render_pagination' => 'Pagination'
];
$working_functions = 0;
$total_functions = count($render_functions);
$details = [];
foreach ($render_functions as $function => $name) {
if (function_exists($function)) {
$working_functions++;
$details[] = "{$name}: ✅";
} else {
$details[] = "{$name}: ❌";
}
}
// Test form rendering system
$form_tests = igny8_test_form_rendering_system($table_id);
$details[] = "Form Rendering: " . ($form_tests['passed'] ? '✅' : '❌ ' . $form_tests['error']);
if ($form_tests['passed']) {
$working_functions++;
}
$total_functions++;
return [
'status' => $working_functions === $total_functions ? 'success' : 'warning',
'message' => "Render functions: {$working_functions}/{$total_functions}",
'details' => implode('
', $details)
];
}
/**
* Test form rendering system
*/
function igny8_test_form_rendering_system($table_id) {
// Test 1: Form config function exists
if (!function_exists('igny8_get_form_config')) {
return ['passed' => false, 'error' => 'igny8_get_form_config missing'];
}
// Test 2: Form rendering function exists
if (!function_exists('igny8_render_inline_form_row')) {
return ['passed' => false, 'error' => 'igny8_render_inline_form_row missing'];
}
// Test 3: Form field rendering functions exist
$field_functions = [
'igny8_render_form_field',
'igny8_render_text_field',
'igny8_render_number_field',
'igny8_render_select_field',
'igny8_render_textarea_field'
];
foreach ($field_functions as $func) {
if (!function_exists($func)) {
return ['passed' => false, 'error' => "{$func} missing"];
}
}
// Test 4: Form config loads for current table
try {
$form_config = igny8_get_form_config($table_id);
if (!$form_config) {
return ['passed' => false, 'error' => 'No form config for table'];
}
if (empty($form_config['fields'])) {
return ['passed' => false, 'error' => 'Empty form fields'];
}
// Test 5: Form can render without errors
$test_output = igny8_render_inline_form_row($table_id, 'add', []);
if (empty($test_output) || strpos($test_output, 'Form not configured') !== false) {
return ['passed' => false, 'error' => 'Form render failed'];
}
} catch (Exception $e) {
return ['passed' => false, 'error' => 'Form config error: ' . $e->getMessage()];
}
return ['passed' => true, 'error' => ''];
}
/**
* Track Table Rendering State
*/
function igny8_track_table_rendering_state() {
$module_info = igny8_get_current_module_info();
$table_id = $module_info['table_id'];
// Test 1: Table render function exists
if (!function_exists('igny8_render_table')) {
return [
'status' => 'error',
'message' => 'Table render function missing',
'details' => 'igny8_render_table function not found'
];
}
// Test 2: AJAX table loading functions exist
$ajax_functions = [
'igny8_get_table_data' => 'Main table data loader',
'igny8_ajax_load_table_data' => 'Submodule table loader'
];
$working_ajax = 0;
$total_ajax = count($ajax_functions);
$ajax_details = [];
foreach ($ajax_functions as $func => $name) {
if (function_exists($func)) {
$working_ajax++;
$ajax_details[] = "{$name}: ✅";
} else {
$ajax_details[] = "{$name}: ❌";
}
}
// Test 3: Check if table has actually loaded data
$table_data_status = igny8_check_table_data_loaded($table_id);
// Test 4: AJAX states tracking (only meaningful after AJAX has run)
$ajax_states = igny8_track_ajax_table_states();
$total_tests = 4;
$passed_tests = ($working_ajax === $total_ajax ? 1 : 0) +
($table_data_status['passed'] ? 1 : 0) +
($ajax_states['passed'] ? 1 : 0) + 1; // +1 for function existence
$details = [
'Function exists: ✅',
'AJAX functions: ' . $working_ajax . '/' . $total_ajax,
implode('
', $ajax_details),
'Table data loaded: ' . ($table_data_status['passed'] ? '✅' : '⏳ ' . $table_data_status['message']),
'AJAX states: ' . ($ajax_states['passed'] ? '✅' : '⏳ ' . $ajax_states['error']),
$ajax_states['details']
];
return [
'status' => $passed_tests === $total_tests ? 'success' : ($passed_tests > 2 ? 'warning' : 'error'),
'message' => "Table rendering: {$passed_tests}/{$total_tests} tests passed",
'details' => implode('
', $details)
];
}
/**
* Check if table has actually loaded data
*/
function igny8_check_table_data_loaded($table_id) {
// Check if there's recent AJAX response data
if (isset($GLOBALS['igny8_last_ajax_response'])) {
$response = $GLOBALS['igny8_last_ajax_response'];
$time_diff = time() - $response['timestamp'];
// If response is recent (within 30 seconds) and has data
if ($time_diff < 30 && !empty($response['data']['items'])) {
return [
'passed' => true,
'message' => 'Data loaded (' . count($response['data']['items']) . ' rows)'
];
}
}
// Check if AJAX states indicate successful loading
if (isset($GLOBALS['igny8_debug_states']['TABLE_AJAX_RESPONSE_OK'])) {
$state = $GLOBALS['igny8_debug_states']['TABLE_AJAX_RESPONSE_OK'];
if ($state['status'] === true) {
return [
'passed' => true,
'message' => 'AJAX response successful'
];
}
}
// If no data loaded yet
return [
'passed' => false,
'message' => 'Waiting for AJAX data load'
];
}
/**
* Debug state helper function - stores debug states in globals
*/
function igny8_debug_state($stage, $ok, $msg) {
if (!isset($GLOBALS['igny8_debug_states'])) {
$GLOBALS['igny8_debug_states'] = [];
}
$GLOBALS['igny8_debug_states'][$stage] = [
'status' => $ok,
'message' => $msg,
'timestamp' => time()
];
}
/**
* Track AJAX table states
*/
function igny8_track_ajax_table_states() {
// The 4 AJAX states that indicate successful table loading
$ajax_states = [
'AJAX_NONCE_VALIDATED' => false,
'USER_CAPABILITY_OK' => false,
'TABLE_AJAX_RESPONSE_OK' => false,
'TABLE_AJAX_REQUEST_SENT' => false
];
$details = [];
$passed_states = 0;
// Check each AJAX state
foreach ($ajax_states as $state_name => $state_value) {
// Check if this state has been set by AJAX functions
if (isset($GLOBALS['igny8_debug_states'][$state_name])) {
$state_data = $GLOBALS['igny8_debug_states'][$state_name];
if ($state_data['status'] === true) {
$passed_states++;
$details[] = "{$state_name}: ✅";
} else {
$details[] = "{$state_name}: ❌ " . $state_data['message'];
}
} else {
$details[] = "{$state_name}: ⏳ Not triggered yet";
}
}
// Check if AJAX tracking system is available
if (!function_exists('igny8_debug_state')) {
return [
'passed' => false,
'error' => 'AJAX tracking system not available',
'details' => implode('
', $details)
];
}
// If no states have been triggered yet (page just loaded)
if ($passed_states === 0 && !isset($GLOBALS['igny8_debug_states'])) {
return [
'passed' => true,
'error' => 'AJAX tracking ready (no requests yet)',
'details' => implode('
', $details)
];
}
return [
'passed' => $passed_states === 4,
'error' => $passed_states === 4 ? '' : "Only {$passed_states}/4 states passed",
'details' => implode('
', $details)
];
}
/**
* Track Filters State
*/
function igny8_track_filters_state() {
$module_info = igny8_get_current_module_info();
$table_id = $module_info['table_id'];
// Test 1: Filter render function exists
if (!function_exists('igny8_render_filters')) {
return [
'status' => 'error',
'message' => 'Filter render function missing',
'details' => 'igny8_render_filters function not found'
];
}
// Test 2: Filter config loads for current table (direct method)
try {
// Load filters config directly like igny8_render_filters() does
$filters_config_path = plugin_dir_path(__FILE__) . '../modules/config/filters-config.php';
if (!file_exists($filters_config_path)) {
return [
'status' => 'error',
'message' => 'Filter config file missing',
'details' => 'filters-config.php not found at: ' . $filters_config_path
];
}
$filters_config = require $filters_config_path;
$filter_config = $filters_config[$table_id] ?? [];
if (empty($filter_config)) {
return [
'status' => 'warning',
'message' => 'No filter config for table',
'details' => 'Filter config not found for: ' . $table_id
];
}
$filter_count = count($filter_config);
} catch (Exception $e) {
return [
'status' => 'error',
'message' => 'Filter config error',
'details' => 'Error loading filter config: ' . $e->getMessage()
];
}
// Test 4: Filter can render without errors
try {
$test_output = igny8_render_filters($table_id);
if (empty($test_output) || strpos($test_output, 'Filter not configured') !== false) {
$render_test = '❌ Filter render failed';
} else {
$render_test = '✅ Filter renders OK';
}
} catch (Exception $e) {
$render_test = '❌ Render error: ' . $e->getMessage();
}
$details = [
'Render function: ✅',
'Config file: ✅',
'Filter config: ✅ (' . $filter_count . ' filters)',
'Render test: ' . $render_test
];
return [
'status' => 'success',
'message' => "Filters: {$filter_count} filters configured",
'details' => implode('
', $details)
];
}
/**
* Track Forms State
*/
function igny8_track_forms_state() {
$module_info = igny8_get_current_module_info();
$table_id = $module_info['table_id'];
// Test 1: Form render function exists
if (!function_exists('igny8_render_inline_form_row')) {
return [
'status' => 'error',
'message' => 'Form render function missing',
'details' => 'igny8_render_inline_form_row function not found'
];
}
// Test 2: Form config function exists
if (!function_exists('igny8_get_form_config')) {
return [
'status' => 'error',
'message' => 'Form config function missing',
'details' => 'igny8_get_form_config function not found'
];
}
// Test 3: Form config loads for current table
try {
$form_config = igny8_get_form_config($table_id);
if (!$form_config) {
return [
'status' => 'warning',
'message' => 'No form config for table',
'details' => 'Form config not found for: ' . $table_id
];
}
if (empty($form_config['fields'])) {
return [
'status' => 'warning',
'message' => 'Empty form fields',
'details' => 'Form config exists but has no fields'
];
}
$field_count = count($form_config['fields']);
} catch (Exception $e) {
return [
'status' => 'error',
'message' => 'Form config error',
'details' => 'Error loading form config: ' . $e->getMessage()
];
}
// Test 4: Form can render without errors
try {
$test_output = igny8_render_inline_form_row($table_id, 'add', []);
if (empty($test_output) || strpos($test_output, 'Form not configured') !== false) {
$render_test = '❌ Form render failed';
} else {
$render_test = '✅ Form renders OK';
}
} catch (Exception $e) {
$render_test = '❌ Render error: ' . $e->getMessage();
}
$details = [
'Function exists: ✅',
'Config function: ✅',
'Form config: ✅ (' . $field_count . ' fields)',
'Render test: ' . $render_test
];
return [
'status' => 'success',
'message' => "Forms: {$field_count} fields configured",
'details' => implode('
', $details)
];
}
/**
* Track Automation Validation State - Submodule Specific
*/
function igny8_track_automation_validation_state() {
$module_info = igny8_get_current_module_info();
$current_submodule = $module_info['submodule'];
$automation_errors = [];
$automation_functions = [];
$working_functions = 0;
try {
// Define submodule-specific automation functions
switch ($current_submodule) {
case 'keywords':
$automation_functions = [
'igny8_update_cluster_metrics' => 'Cluster metrics update',
'igny8_handle_keyword_cluster_update' => 'Keyword cluster updates',
'igny8_bulk_delete_keywords' => 'Bulk keyword deletion',
'igny8_bulk_map_keywords' => 'Bulk keyword mapping',
'igny8_bulk_unmap_keywords' => 'Bulk keyword unmapping',
'igny8_ajax_ai_cluster_keywords' => 'AI cluster creation',
'igny8_workflow_triggers' => 'Workflow triggers',
'igny8_ajax_import_keywords' => 'Keyword import automation'
];
break;
case 'clusters':
$automation_functions = [
'igny8_update_cluster_metrics' => 'Cluster metrics update',
'igny8_auto_create_cluster_term' => 'Cluster taxonomy creation',
'igny8_auto_update_cluster_term' => 'Cluster taxonomy updates',
'igny8_handle_content_cluster_association' => 'Content cluster associations',
'igny8_ajax_ai_generate_ideas' => 'AI idea generation',
'igny8_workflow_triggers' => 'Workflow triggers'
];
break;
case 'ideas':
$automation_functions = [
'igny8_update_idea_metrics' => 'Idea metrics update',
'igny8_create_task_from_idea' => 'Task creation from ideas',
'igny8_workflow_triggers' => 'Workflow triggers',
'igny8_write_log' => 'Automation logging',
'igny8_ajax_ai_generate_ideas' => 'AI idea generation',
'igny8_ajax_ai_generate_content' => 'AI content generation'
];
break;
default:
// Fallback to basic automation functions
$automation_functions = [
'igny8_update_cluster_metrics' => 'Cluster metrics update',
'igny8_handle_keyword_cluster_update' => 'Keyword cluster updates',
'igny8_workflow_triggers' => 'Workflow triggers'
];
}
// Check if each automation function exists
$function_details = [];
foreach ($automation_functions as $function => $description) {
if (function_exists($function)) {
$working_functions++;
$function_details[] = "{$description}: ✅";
} else {
// Check if this is a known missing function
if (strpos($description, 'MISSING') !== false) {
$automation_errors[] = "{$description}: ❌ (Function never implemented - referenced in docs but missing from code)";
$function_details[] = "{$description}: ❌ (NOT IMPLEMENTED)";
} else {
$automation_errors[] = "{$description}: ❌ ({$function} missing)";
$function_details[] = "{$description}: ❌";
}
}
}
$total_functions = count($automation_functions);
} catch (Exception $e) {
$automation_errors[] = 'Automation check error: ' . $e->getMessage();
}
if (empty($automation_errors)) {
return [
'status' => 'success',
'message' => "Automation: {$working_functions}/{$total_functions} functions active",
'details' => implode('
', $function_details)
];
} else {
return [
'status' => $working_functions > ($total_functions / 2) ? 'warning' : 'error',
'message' => "Automation: {$working_functions}/{$total_functions} functions active",
'details' => implode('
', $function_details) . '
Issues:
' . implode('
', $automation_errors)
];
}
}
/**
* Track Database Pre-Fetch State
*/
function igny8_track_db_prefetch_state() {
global $wpdb;
$module_info = igny8_get_current_module_info();
// Get table name
if (function_exists('igny8_get_table_name')) {
$table_name = igny8_get_table_name($module_info['table_id']);
} else {
$table_name = $wpdb->prefix . 'igny8_' . str_replace('_', '', $module_info['table_id']);
}
// Check if table exists
$table_exists = $wpdb->get_var("SHOW TABLES LIKE '{$table_name}'") !== null;
if ($table_exists) {
$row_count = $wpdb->get_var("SELECT COUNT(*) FROM {$table_name}");
return [
'status' => 'success',
'message' => "Table: {$table_name} ({$row_count} rows)",
'details' => "Database connection: ✅
Table exists: ✅"
];
} else {
return [
'status' => 'error',
'message' => "Table not found: {$table_name}",
'details' => "Database connection: " . (!empty($wpdb->dbh) ? '✅' : '❌') . "
Table exists: ❌"
];
}
}
/**
* Track Frontend Initialization State
*/
function igny8_track_frontend_init_state() {
// Check if core.js is enqueued
$core_js_enqueued = wp_script_is('igny8-admin-js', 'enqueued');
// Check if required DOM elements exist (this will be checked by JavaScript)
return [
'status' => $core_js_enqueued ? 'success' : 'warning',
'message' => "Frontend JS: " . ($core_js_enqueued ? 'Enqueued' : 'Not enqueued'),
'details' => "Core.js loaded: " . ($core_js_enqueued ? '✅' : '❌') . "
DOM elements: Checked by JS"
];
}
// Get module debug content using consolidated evidence system
function igny8_get_module_debug_content() {
// Get current module information
$module_info = igny8_get_current_module_info();
$module_name = ucfirst($module_info['module']);
$current_submodule = $module_info['submodule'];
// Track debug states - split into component states and automation states
$component_states = [
'database' => igny8_track_database_validation_state(),
'table' => igny8_track_initial_render_state(),
'filters' => igny8_track_filters_state(),
'forms' => igny8_track_forms_state()
];
$automation_states = [
'automation' => igny8_track_automation_validation_state(),
'ai_logs' => igny8_track_ai_logs_state($module_info)
];
ob_start();
?>