Files
igny8/igny8-ai-seo-wp-plugin/modules/thinker/image-testing.php
2025-11-11 21:16:37 +05:00

917 lines
50 KiB
PHP

<?php
/**
* ==========================
* 🔐 IGNY8 FILE RULE HEADER
* ==========================
* @file : image-testing.php
* @location : /modules/thinker/image-testing.php
* @type : Admin Page
* @scope : Module Only
* @allowed : AI image generation testing, DALL·E 3 integration, image creation
* @reusability : Single Use
* @notes : AI image generation testing interface for thinker module
*/
if (!defined('ABSPATH')) exit;
// Component render functions are loaded centrally via global-layout.php
// Helper function to read last N lines of a file
function tail_file($filepath, $lines = 10) {
if (!file_exists($filepath)) {
return [];
}
$handle = fopen($filepath, "r");
if (!$handle) {
return [];
}
$linecounter = $lines;
$pos = -2;
$beginning = false;
$text = [];
while ($linecounter > 0) {
$t = " ";
while ($t != "\n") {
if (fseek($handle, $pos, SEEK_END) == -1) {
$beginning = true;
break;
}
$t = fgetc($handle);
$pos--;
}
$linecounter--;
if ($beginning) {
rewind($handle);
}
$text[$lines - $linecounter - 1] = fgets($handle);
if ($beginning) break;
}
fclose($handle);
return array_reverse($text);
}
// Image Testing content
ob_start();
// Handle Form Submit
$image_url = '';
$response_error = '';
$save_path = '';
$generated_image_data = null;
// Handle saving prompt settings
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_prompt_nonce']) && wp_verify_nonce($_POST['save_prompt_nonce'], 'save_prompt')) {
$prompt_template = sanitize_textarea_field(wp_unslash($_POST['prompt_template']));
update_option('igny8_image_prompt_template', $prompt_template);
$settings_saved = true;
}
// Handle image generation
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['generate_image_nonce']) && wp_verify_nonce($_POST['generate_image_nonce'], 'generate_image')) {
$title = sanitize_text_field(wp_unslash($_POST['title']));
$desc = sanitize_textarea_field(wp_unslash($_POST['desc']));
$image_type = sanitize_text_field(wp_unslash($_POST['image_type']));
$image_provider = sanitize_text_field(wp_unslash($_POST['image_provider'] ?? 'openai'));
$negative_prompt = sanitize_textarea_field(wp_unslash($_POST['negative_prompt'] ?? 'text, watermark, logo, overlay, title, caption, writing on walls, writing on objects, UI, infographic elements, post title'));
$image_width = intval($_POST['image_width'] ?? 1024);
$image_height = intval($_POST['image_height'] ?? 1024);
$image_format = sanitize_text_field(wp_unslash($_POST['image_format'] ?? 'jpg'));
// Get custom prompt template or use default
$prompt_template = wp_unslash(get_option('igny8_image_prompt_template', 'Generate a {image_type} image for a blog post titled "{title}". Description: {description}'));
// Replace placeholders in prompt template
$prompt = str_replace(
['{image_type}', '{title}', '{description}'],
[$image_type, $title, $desc],
$prompt_template
);
// Get API keys
$openai_key = get_option('igny8_api_key', '');
$runware_key = get_option('igny8_runware_api_key', '');
// Check if the required API key is configured
$required_key = ($image_provider === 'runware') ? $runware_key : $openai_key;
$service_name = ($image_provider === 'runware') ? 'Runware' : 'OpenAI';
if (empty($required_key)) {
$response_error = $service_name . ' API key not configured. Please set your API key in the settings.';
} else {
// Debug: Log the request details
error_log('Igny8 Image Generation - Starting request');
error_log('Igny8 Image Generation - Prompt: ' . $prompt);
error_log('Igny8 Image Generation - Provider: ' . $image_provider);
error_log('Igny8 Image Generation - API Key: ' . substr($required_key, 0, 10) . '...');
try {
if ($image_provider === 'runware') {
// Runware API Call
error_log('Igny8 Image Generation - Using Runware service');
// Prepare Runware API payload
$payload = [
[
'taskType' => 'authentication',
'apiKey' => $runware_key
],
[
'taskType' => 'imageInference',
'taskUUID' => wp_generate_uuid4(),
'positivePrompt' => $prompt,
'negativePrompt' => $negative_prompt,
'model' => 'runware:97@1',
'width' => $image_width,
'height' => $image_height,
'steps' => 30,
'CFGScale' => 7.5,
'numberResults' => 1,
'outputFormat' => $image_format
]
];
// Make API request
$response = wp_remote_post('https://api.runware.ai/v1', [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode($payload),
'timeout' => 60
]);
if (is_wp_error($response)) {
error_log('Igny8 Image Generation - Runware Error: ' . $response->get_error_message());
$response_error = 'Runware API Error: ' . $response->get_error_message();
} else {
$response_body = wp_remote_retrieve_body($response);
$response_data = json_decode($response_body, true);
if (isset($response_data['data'][0]['imageURL'])) {
// Download and save the image
$image_url = $response_data['data'][0]['imageURL'];
$filename = sanitize_file_name($title) . '_' . time() . '.' . $image_format;
// Create uploads directory
$upload_dir = wp_upload_dir();
$igny8_dir = $upload_dir['basedir'] . '/igny8-ai-images/';
if (!file_exists($igny8_dir)) {
wp_mkdir_p($igny8_dir);
}
// Download image
$image_response = wp_remote_get($image_url);
if (is_wp_error($image_response)) {
$response_error = 'Failed to download Runware image: ' . $image_response->get_error_message();
} else {
$image_data = wp_remote_retrieve_body($image_response);
$file_path = $igny8_dir . $filename;
$saved = file_put_contents($file_path, $image_data);
if ($saved === false) {
$response_error = 'Failed to save Runware image file';
} else {
$response_success = true;
$response_image_url = str_replace(ABSPATH, home_url('/'), $file_path);
$response_message = 'Image generated successfully using Runware!';
// Set generated image data for consistent display
$generated_image_data = [
'model' => 'runware:97@1',
'provider' => 'runware',
'negative_prompt' => $negative_prompt
];
error_log('Igny8 Image Generation - Runware image saved to: ' . $file_path);
}
}
} elseif (isset($response_data['errors'][0]['message'])) {
$response_error = 'Runware API Error: ' . $response_data['errors'][0]['message'];
} else {
$response_error = 'Unknown response from Runware API';
}
}
} else {
// OpenAI DALL-E 3 API Call
error_log('Igny8 Image Generation - Using OpenAI DALL-E 3 service');
$data = [
'model' => 'dall-e-3',
'prompt' => $prompt,
'n' => 1,
'size' => $image_width . 'x' . $image_height
];
// Add negative prompt if supported (DALL-E 3 doesn't support negative prompts, but we'll log it)
if (!empty($negative_prompt)) {
error_log('Igny8 Image Generation - Negative prompt provided but DALL-E 3 does not support negative prompts: ' . $negative_prompt);
}
$args = [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $openai_key,
'OpenAI-Beta' => 'assistants=v2'
],
'body' => json_encode($data),
'timeout' => 60,
'sslverify' => true
];
error_log('Igny8 Image Generation - Making API request to OpenAI');
$api_response = wp_remote_post('https://api.openai.com/v1/images/generations', $args);
// Debug: Log response details
if (is_wp_error($api_response)) {
error_log('Igny8 Image Generation - WP Error: ' . $api_response->get_error_message());
error_log('Igny8 Image Generation - Error Code: ' . $api_response->get_error_code());
$response_error = 'WordPress HTTP Error: ' . $api_response->get_error_message();
} else {
$response_code = wp_remote_retrieve_response_code($api_response);
$response_body = wp_remote_retrieve_body($api_response);
error_log('Igny8 Image Generation - Response Code: ' . $response_code);
error_log('Igny8 Image Generation - Response Body: ' . substr($response_body, 0, 500));
if ($response_code === 200) {
$body = json_decode($response_body, true);
if (isset($body['data'][0]['url'])) {
$image_url = $body['data'][0]['url'];
$generated_image_data = $body['data'][0];
error_log('Igny8 Image Generation - Image URL received: ' . $image_url);
// Log successful image generation
global $wpdb;
$wpdb->insert($wpdb->prefix . 'igny8_logs', [
'level' => 'info',
'message' => 'Image generation successful',
'context' => wp_json_encode([
'model' => 'dall-e-3',
'prompt_length' => strlen($prompt),
'image_size' => '1024x1024',
'total_cost' => 0.040, // DALL-E 3 standard cost
'title' => $title,
'image_type' => $image_type
]),
'source' => 'openai_image',
'status' => 'success',
'api_id' => $body['data'][0]['id'] ?? null,
'user_id' => get_current_user_id(),
'created_at' => current_time('mysql')
], ['%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s']);
// Try to save to plugin directory first, fallback to WordPress uploads
$plugin_upload_dir = plugin_dir_path(__FILE__) . '../../assets/ai-images/';
$wp_upload_dir = wp_upload_dir();
$wp_upload_path = $wp_upload_dir['basedir'] . '/igny8-ai-images/';
$slug = sanitize_title($title);
$upload_dir = $plugin_upload_dir;
$folder = $upload_dir . $slug . '/';
$save_location = 'plugin';
// Check if plugin directory is writable
if (!file_exists($plugin_upload_dir)) {
if (wp_mkdir_p($plugin_upload_dir)) {
error_log('Igny8 Image Generation - Created plugin directory: ' . $plugin_upload_dir);
} else {
error_log('Igny8 Image Generation - Failed to create plugin directory: ' . $plugin_upload_dir);
// Fallback to WordPress uploads directory
$upload_dir = $wp_upload_path;
$folder = $upload_dir . $slug . '/';
$save_location = 'wordpress';
error_log('Igny8 Image Generation - Using WordPress uploads as fallback: ' . $wp_upload_path);
}
}
if (file_exists($plugin_upload_dir) && !is_writable($plugin_upload_dir)) {
// Try to fix permissions
chmod($plugin_upload_dir, 0755);
error_log('Igny8 Image Generation - Attempted to fix plugin directory permissions: ' . $plugin_upload_dir);
if (!is_writable($plugin_upload_dir)) {
// Fallback to WordPress uploads directory
$upload_dir = $wp_upload_path;
$folder = $upload_dir . $slug . '/';
$save_location = 'wordpress';
error_log('Igny8 Image Generation - Plugin directory not writable, using WordPress uploads: ' . $wp_upload_path);
}
}
// Ensure target directory exists
if (!file_exists($folder)) {
wp_mkdir_p($folder);
error_log('Igny8 Image Generation - Created directory: ' . $folder);
}
// Final check if directory is writable
if (file_exists($folder) && !is_writable($folder)) {
// Try to fix permissions one more time
chmod($folder, 0755);
error_log('Igny8 Image Generation - Attempted to fix final permissions for: ' . $folder);
if (!is_writable($folder)) {
$response_error = 'Directory is not writable. Please check file permissions for: ' . $folder;
error_log('Igny8 Image Generation - Directory still not writable: ' . $folder);
error_log('Igny8 Image Generation - Directory permissions: ' . substr(sprintf('%o', fileperms($folder)), -4));
}
} elseif (!file_exists($folder)) {
$response_error = 'Directory does not exist and could not be created: ' . $folder;
error_log('Igny8 Image Generation - Directory does not exist: ' . $folder);
}
if (empty($response_error)) {
// Download image data
$image_data = file_get_contents($image_url);
if ($image_data === false) {
$response_error = 'Failed to download image from URL: ' . $image_url;
error_log('Igny8 Image Generation - Failed to download image from: ' . $image_url);
} else {
$filename = $folder . 'image.png';
// Try to write the file
$bytes_written = file_put_contents($filename, $image_data);
if ($bytes_written === false) {
$response_error = 'Failed to save image file. Check file permissions.';
error_log('Igny8 Image Generation - Failed to write file: ' . $filename);
error_log('Igny8 Image Generation - Directory permissions: ' . substr(sprintf('%o', fileperms($folder)), -4));
error_log('Igny8 Image Generation - Directory writable: ' . (is_writable($folder) ? 'yes' : 'no'));
} else {
// Determine the correct path for display
if ($save_location === 'wordpress') {
$display_path = '/wp-content/uploads/igny8-ai-images/' . $slug . '/image.png';
$log_path = $display_path;
} else {
$display_path = '/assets/ai-images/' . $slug . '/image.png';
$log_path = $display_path;
}
$save_path = 'Saved to: ' . $display_path . ' (' . $bytes_written . ' bytes)';
error_log('Igny8 Image Generation - Image saved successfully: ' . $filename . ' (' . $bytes_written . ' bytes)');
error_log('Igny8 Image Generation - Save location: ' . $save_location);
// Update log with file path
$wpdb->update(
$wpdb->prefix . 'igny8_logs',
[
'context' => wp_json_encode([
'model' => 'dall-e-3',
'prompt_length' => strlen($prompt),
'image_size' => '1024x1024',
'total_cost' => 0.040,
'title' => $title,
'image_type' => $image_type,
'file_path' => $log_path,
'file_size' => $bytes_written,
'save_location' => $save_location
])
],
['api_id' => $body['data'][0]['id'] ?? null],
['%s'],
['%s']
);
}
}
}
} else {
$response_error = 'Image URL not returned from API. Response: ' . substr($response_body, 0, 200);
if (isset($body['error']['message'])) {
$response_error .= ' Error: ' . $body['error']['message'];
}
// Log failed image generation
global $wpdb;
$wpdb->insert($wpdb->prefix . 'igny8_logs', [
'level' => 'error',
'message' => 'Image generation failed - no URL returned',
'context' => wp_json_encode([
'model' => 'dall-e-3',
'prompt_length' => strlen($prompt),
'image_size' => '1024x1024',
'error_response' => substr($response_body, 0, 500),
'title' => $title,
'image_type' => $image_type
]),
'source' => 'openai_image',
'status' => 'error',
'user_id' => get_current_user_id(),
'created_at' => current_time('mysql')
], ['%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s']);
}
} else {
$response_error = 'API returned error code ' . $response_code . '. Response: ' . substr($response_body, 0, 200);
// Log failed image generation
global $wpdb;
$wpdb->insert($wpdb->prefix . 'igny8_logs', [
'level' => 'error',
'message' => 'Image generation failed - HTTP error',
'context' => wp_json_encode([
'model' => 'dall-e-3',
'prompt_length' => strlen($prompt),
'image_size' => '1024x1024',
'http_code' => $response_code,
'error_response' => substr($response_body, 0, 500),
'title' => $title,
'image_type' => $image_type
]),
'source' => 'openai_image',
'status' => 'error',
'user_id' => get_current_user_id(),
'created_at' => current_time('mysql')
], ['%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s']);
}
}
} // End of OpenAI else block
} catch (Exception $e) {
error_log('Igny8 Image Generation - Exception: ' . $e->getMessage());
$response_error = 'Exception occurred: ' . $e->getMessage();
// Log exception
global $wpdb;
$wpdb->insert($wpdb->prefix . 'igny8_logs', [
'level' => 'error',
'message' => 'Image generation failed - exception',
'context' => wp_json_encode([
'model' => 'dall-e-3',
'prompt_length' => strlen($prompt),
'image_size' => '1024x1024',
'exception_message' => $e->getMessage(),
'title' => $title,
'image_type' => $image_type
]),
'source' => 'openai_image',
'status' => 'error',
'user_id' => get_current_user_id(),
'created_at' => current_time('mysql')
], ['%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s']);
}
}
}
?>
<div class="igny8-module-home">
<!-- Page Header -->
<div class="igny8-dashboard-section">
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>AI Image Generation Test</h3>
<p class="igny8-card-subtitle">Test OpenAI DALL·E 3 image generation with your content data</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-format-image igny8-dashboard-icon-lg igny8-dashboard-icon-purple"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<p>Generate AI-powered images for your content using OpenAI's DALL·E 3. Enter your post details below to create custom images based on your title, description, keywords, and cluster information.</p>
</div>
</div>
</div>
<div class="igny8-grid-3">
<!-- Image Generation Form -->
<div class="igny8-dashboard-section">
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Generate Image</h3>
<p class="igny8-card-subtitle">Configure image generation parameters</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-admin-generic igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<form method="POST" id="igny8-image-generation-form">
<?php wp_nonce_field('generate_image', 'generate_image_nonce'); ?>
<div class="igny8-form-group">
<label for="title">Post Title *</label>
<input type="text" id="title" name="title" class="igny8-form-control" value="<?php echo isset($_POST['title']) ? esc_attr(wp_unslash($_POST['title'])) : ''; ?>" required>
</div>
<div class="igny8-form-group">
<label for="desc">Prompt Description *</label>
<textarea id="desc" name="desc" rows="4" class="igny8-form-control" placeholder="Describe the image you want to generate..." required><?php echo isset($_POST['desc']) ? esc_textarea(wp_unslash($_POST['desc'])) : ''; ?></textarea>
<small class="form-help">Describe the visual elements, style, mood, and composition you want in the image.</small>
</div>
<div class="igny8-form-group">
<label for="negative_prompt">Negative Prompt</label>
<textarea id="negative_prompt" name="negative_prompt" rows="2" class="igny8-form-control" placeholder="Describe what you DON'T want in the image..."><?php echo isset($_POST['negative_prompt']) ? esc_textarea(wp_unslash($_POST['negative_prompt'])) : 'text, watermark, logo, overlay, title, caption, writing on walls, writing on objects, UI, infographic elements, post title'; ?></textarea>
<small class="form-help">Specify elements to avoid in the generated image (text, watermarks, logos, etc.).</small>
</div>
<div class="igny8-form-group">
<label for="image_type">Image Type</label>
<select id="image_type" name="image_type" class="igny8-form-control">
<option value="realistic" <?php selected(isset($_POST['image_type']) ? $_POST['image_type'] : 'realistic', 'realistic'); ?>>Realistic</option>
<option value="illustration" <?php selected(isset($_POST['image_type']) ? $_POST['image_type'] : '', 'illustration'); ?>>Illustration</option>
<option value="3D render" <?php selected(isset($_POST['image_type']) ? $_POST['image_type'] : '', '3D render'); ?>>3D Render</option>
<option value="minimalist" <?php selected(isset($_POST['image_type']) ? $_POST['image_type'] : '', 'minimalist'); ?>>Minimalist</option>
<option value="cartoon" <?php selected(isset($_POST['image_type']) ? $_POST['image_type'] : '', 'cartoon'); ?>>Cartoon</option>
</select>
</div>
<div class="igny8-form-group">
<label for="image_provider">Image Provider</label>
<select id="image_provider" name="image_provider" class="igny8-form-control">
<option value="openai" <?php selected(isset($_POST['image_provider']) ? $_POST['image_provider'] : 'openai', 'openai'); ?>>OpenAI DALL·E 3</option>
<option value="runware" <?php selected(isset($_POST['image_provider']) ? $_POST['image_provider'] : '', 'runware'); ?>>Runware HiDream-I1 Full</option>
</select>
<small class="form-help">Choose the AI image generation service to use.</small>
</div>
<div class="igny8-form-group">
<label for="igny8_image_size_selector">Image Size</label>
<select id="igny8_image_size_selector" name="image_size" class="igny8-form-control">
<!-- Options will be populated dynamically by JavaScript -->
</select>
<small class="form-help">Choose the image dimensions for your generated image.</small>
<div id="igny8-selected-dimensions" style="margin-top: 5px; font-weight: bold; color: #0073aa;"></div>
</div>
<div class="igny8-form-group">
<label for="igny8_image_format_selector">Image Format</label>
<select id="igny8_image_format_selector" name="image_format" class="igny8-form-control">
<option value="jpg" <?php selected(isset($_POST['image_format']) ? $_POST['image_format'] : 'jpg', 'jpg'); ?>>JPG</option>
<option value="png" <?php selected(isset($_POST['image_format']) ? $_POST['image_format'] : '', 'png'); ?>>PNG</option>
<option value="webp" <?php selected(isset($_POST['image_format']) ? $_POST['image_format'] : '', 'webp'); ?>>WEBP</option>
</select>
<small class="form-help">Choose the image file format for your generated image.</small>
<div id="igny8-selected-format" style="margin-top: 5px; font-weight: bold; color: #0073aa;"></div>
</div>
<!-- Hidden fields for width and height -->
<input type="hidden" id="image_width" name="image_width" value="1024">
<input type="hidden" id="image_height" name="image_height" value="1024">
<div class="igny8-form-actions">
<button type="submit" class="igny8-btn igny8-btn-primary" id="generate-btn">
<span class="dashicons dashicons-format-image"></span>
<span class="btn-text">Generate Image</span>
<span class="btn-loading" style="display: none;">
<span class="dashicons dashicons-update" style="animation: spin 1s linear infinite;"></span>
Sending Request...
</span>
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Results Panel -->
<div class="igny8-dashboard-section">
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Generated Image</h3>
<p class="igny8-card-subtitle">AI-generated image results</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-format-image igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<?php if ($image_url): ?>
<div class="igny8-image-result">
<div class="igny8-image-preview">
<img src="<?php echo esc_url($image_url); ?>" alt="Generated Image" style="max-width: 100%; height: auto; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);">
</div>
<?php if ($generated_image_data): ?>
<div class="igny8-image-details">
<h4>Image Details</h4>
<ul class="igny8-details-list">
<li><strong>Size:</strong> <?php echo $image_width . 'x' . $image_height; ?> pixels</li>
<li><strong>Format:</strong> <?php echo strtoupper($image_format); ?></li>
<li><strong>Model:</strong> <?php echo ($image_provider === 'runware') ? 'Runware HiDream-I1 Full' : 'DALL·E 3'; ?></li>
<?php if (isset($generated_image_data['revised_prompt'])): ?>
<li><strong>Revised Prompt:</strong> <?php echo esc_html($generated_image_data['revised_prompt']); ?></li>
<?php endif; ?>
<?php if (!empty($negative_prompt)): ?>
<li><strong>Negative Prompt:</strong> <?php echo esc_html($negative_prompt); ?></li>
<?php endif; ?>
</ul>
</div>
<?php endif; ?>
<?php if ($save_path): ?>
<div class="igny8-save-info">
<p class="igny8-success-message">
<span class="dashicons dashicons-yes-alt" style="color: var(--green);"></span>
<?php echo esc_html($save_path); ?>
</p>
</div>
<?php endif; ?>
<div class="igny8-image-actions">
<a href="<?php echo esc_url($image_url); ?>" target="_blank" class="igny8-btn igny8-btn-outline">
<span class="dashicons dashicons-external"></span>
View Original
</a>
<button type="button" class="igny8-btn igny8-btn-success" onclick="navigator.clipboard.writeText('<?php echo esc_js($image_url); ?>')">
<span class="dashicons dashicons-admin-page"></span>
Copy URL
</button>
</div>
</div>
<?php elseif ($response_error): ?>
<div class="igny8-error-message">
<span class="dashicons dashicons-warning" style="color: var(--red); font-size: 24px;"></span>
<h4>Generation Failed</h4>
<p><?php echo esc_html($response_error); ?></p>
</div>
<?php else: ?>
<div class="igny8-empty-state">
<span class="dashicons dashicons-format-image" style="color: var(--text-dim); font-size: 48px;"></span>
<p>No image generated yet. Fill out the form and click "Generate Image" to create your first AI image.</p>
</div>
<?php endif; ?>
</div>
</div>
</div>
<!-- Prompt Settings -->
<div class="igny8-dashboard-section">
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Prompt Settings</h3>
<p class="igny8-card-subtitle">Customize your image generation prompt template</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-edit-page igny8-dashboard-icon-lg igny8-dashboard-icon-amber"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<?php if (isset($settings_saved)): ?>
<div class="igny8-notice igny8-notice-success">
<span class="dashicons dashicons-yes-alt"></span>
Prompt template saved successfully!
</div>
<?php endif; ?>
<form method="POST">
<?php wp_nonce_field('save_prompt', 'save_prompt_nonce'); ?>
<div class="igny8-form-group">
<label for="prompt_template">Prompt Template</label>
<textarea id="prompt_template" name="prompt_template" rows="6" class="igny8-form-control" placeholder="Enter your custom prompt template..."><?php echo esc_textarea(wp_unslash(get_option('igny8_image_prompt_template', 'Generate a {image_type} image for a blog post titled "{title}". Description: {description}'))); ?></textarea>
<small class="form-help">
<strong>Available placeholders:</strong><br>
<code>{title}</code> - Post title<br>
<code>{description}</code> - Prompt description<br>
<code>{image_type}</code> - Selected image type
</small>
</div>
<div class="igny8-form-actions">
<button type="submit" class="igny8-btn igny8-btn-success">
<span class="dashicons dashicons-saved"></span>
Save Prompt Template
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- API Configuration Info -->
<div class="igny8-dashboard-section">
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>API Configuration</h3>
<p class="igny8-card-subtitle">OpenAI API settings and requirements</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-admin-settings igny8-dashboard-icon-lg igny8-dashboard-icon-amber"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<div class="igny8-api-info">
<div class="igny8-info-grid">
<div class="igny8-info-item">
<h4>OpenAI API Key</h4>
<p>Your OpenAI API key is <?php echo !empty(get_option('igny8_api_key', '')) ? '<span class="igny8-status-ok">configured</span>' : '<span class="igny8-status-error">not set</span>'; ?></p>
<a href="<?php echo admin_url('admin.php?page=igny8-settings'); ?>" class="igny8-btn igny8-btn-outline igny8-btn-sm">
<span class="dashicons dashicons-admin-settings"></span>
Configure API Key
</a>
</div>
<div class="igny8-info-item">
<h4>Image Service</h4>
<p><?php
$current_provider = isset($image_provider) ? $image_provider : 'openai';
if ($current_provider === 'runware') {
echo 'Runware HiDream-I1 Full';
} else {
echo 'OpenAI DALL·E 3';
}
?> (1024x1024 resolution)</p>
</div>
<div class="igny8-info-item">
<h4>Image Storage</h4>
<p>Generated images are saved to <code>/assets/ai-images/[slug]/image.png</code></p>
</div>
<div class="igny8-info-item">
<h4>Usage Limits</h4>
<p>Subject to your OpenAI account limits and billing</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Debug Information -->
<div class="igny8-dashboard-section">
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Debug Information</h3>
<p class="igny8-card-subtitle">Technical details and troubleshooting</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">
<div class="igny8-debug-info">
<div class="igny8-debug-grid">
<div class="igny8-debug-item">
<h4>Server Information</h4>
<ul class="igny8-debug-list">
<li><strong>PHP Version:</strong> <?php echo PHP_VERSION; ?></li>
<li><strong>WordPress Version:</strong> <?php echo get_bloginfo('version'); ?></li>
<li><strong>cURL Available:</strong> <?php echo function_exists('curl_init') ? 'Yes' : 'No'; ?></li>
<li><strong>SSL Support:</strong> <?php echo function_exists('openssl_version') ? 'Yes' : 'No'; ?></li>
<li><strong>Image Save Directory:</strong> <?php echo wp_upload_dir()['basedir'] . '/igny8-ai-images/'; ?></li>
<li><strong>Image Dir Writable:</strong>
<?php
$image_dir = wp_upload_dir()['basedir'] . '/igny8-ai-images/';
if (file_exists($image_dir)) {
echo is_writable($image_dir) ? '✅ Yes' : '❌ No (' . substr(sprintf('%o', fileperms($image_dir)), -4) . ')';
} else {
echo '❌ Directory does not exist';
}
?>
</li>
<li><strong>WordPress Uploads:</strong> <?php echo wp_upload_dir()['basedir']; ?></li>
<li><strong>WP Uploads Writable:</strong>
<?php
$wp_uploads = wp_upload_dir()['basedir'];
echo is_writable($wp_uploads) ? '✅ Yes' : '❌ No (' . substr(sprintf('%o', fileperms($wp_uploads)), -4) . ')';
?>
</li>
</ul>
</div>
<div class="igny8-debug-item">
<h4>API Configuration</h4>
<ul class="igny8-debug-list">
<li><strong>API Key Status:</strong> <?php echo !empty(get_option('igny8_api_key', '')) ? 'Configured' : 'Not Set'; ?></li>
<li><strong>API Key Length:</strong> <?php echo strlen(get_option('igny8_api_key', '')); ?> characters</li>
<li><strong>Prompt Template:</strong> <?php echo strlen(get_option('igny8_image_prompt_template', '')); ?> characters</li>
</ul>
</div>
<div class="igny8-debug-item">
<h4>Recent Errors</h4>
<div class="igny8-error-log">
<?php
$error_log = ini_get('error_log');
if ($error_log && file_exists($error_log)) {
$recent_errors = tail_file($error_log, 10);
if ($recent_errors) {
echo '<pre style="font-size: 11px; background: #f8f9fa; padding: 10px; border-radius: 4px; max-height: 200px; overflow-y: auto;">';
foreach ($recent_errors as $error) {
if (strpos($error, 'Igny8 Image Generation') !== false) {
echo esc_html($error) . "\n";
}
}
echo '</pre>';
} else {
echo '<p>No recent Igny8 errors found.</p>';
}
} else {
echo '<p>Error log not accessible.</p>';
}
?>
</div>
</div>
<div class="igny8-debug-item">
<h4>Test Connection</h4>
<button type="button" class="igny8-btn igny8-btn-outline" onclick="testConnection()">
<span class="dashicons dashicons-admin-network"></span>
Test API Connection
</button>
<div id="connection-test-result" style="margin-top: 10px;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('igny8-image-generation-form');
const generateBtn = document.getElementById('generate-btn');
const btnText = generateBtn.querySelector('.btn-text');
const btnLoading = generateBtn.querySelector('.btn-loading');
if (form) {
form.addEventListener('submit', function(e) {
// Show loading state
btnText.style.display = 'none';
btnLoading.style.display = 'inline-flex';
generateBtn.disabled = true;
// Show notification that request is being sent
showNotification('Sending image generation request to DALL·E 3...', 'info');
});
}
// Use unified global notification system
function showNotification(message, type = 'info') {
if (typeof igny8GlobalNotification === 'function') {
igny8GlobalNotification(message, type);
} else {
// Fallback to basic alert if global system not available
alert(message);
}
}
// Show success/error notifications if page was just submitted
<?php if ($image_url): ?>
showNotification('Image generated successfully! 🎉', 'success');
<?php elseif ($response_error): ?>
showNotification('Image generation failed: <?php echo esc_js($response_error); ?>', 'error');
<?php endif; ?>
});
// Global function for testing API connection
function testConnection() {
const resultDiv = document.getElementById('connection-test-result');
resultDiv.innerHTML = '<p>Testing connection...</p>';
// Simple test request to check if server can make HTTP requests
fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'action=igny8_test_connection&nonce=<?php echo wp_create_nonce('igny8_test_connection'); ?>'
})
.then(response => response.json())
.then(data => {
if (data.success) {
resultDiv.innerHTML = '<p style="color: green;">✓ Connection test successful</p>';
} else {
resultDiv.innerHTML = '<p style="color: red;">✗ Connection test failed: ' + (data.data || 'Unknown error') + '</p>';
}
})
.catch(error => {
resultDiv.innerHTML = '<p style="color: red;">✗ Connection test failed: ' + error.message + '</p>';
});
}
</script>
<?php
// Localize script for the image testing page
wp_localize_script('igny8-admin-js', 'IGNY8_PAGE', [
'module' => 'thinker',
'subpage' => 'image-testing',
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('igny8_image_testing_settings')
]);
?>