Initial commit: igny8 project

This commit is contained in:
igny8
2025-11-09 10:27:02 +00:00
commit 60b8188111
27265 changed files with 4360521 additions and 0 deletions

View File

@@ -0,0 +1,917 @@
<?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')
]);
?>

View File

@@ -0,0 +1,344 @@
<?php
/**
* ==========================
* 🔐 IGNY8 FILE RULE HEADER
* ==========================
* @file : profile.php
* @location : /modules/thinker/profile.php
* @type : Admin Page
* @scope : Module Only
* @allowed : AI profile configuration, behavior settings, personality management
* @reusability : Single Use
* @notes : AI behavior configuration interface for thinker module
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
?>
<div class="igny8-module-page">
<div class="igny8-container">
<!-- Page title removed - titles should not appear inside page content -->
<!-- Writing Style Section -->
<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>Writing Style Preferences</h3>
<p class="igny8-card-subtitle">Configure AI writing tone, style, and behavior</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-edit-page igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<form id="igny8-ai-profile-form">
<!-- Tone Selection -->
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="ai_tone" class="igny8-field-label">Default Tone</label>
<select name="ai_tone" id="ai_tone" class="igny8-select" style="width: 100%;">
<option value="professional" <?php selected(igny8_get_ai_setting('ai_tone', 'professional'), 'professional'); ?>>Professional</option>
<option value="casual" <?php selected(igny8_get_ai_setting('ai_tone', 'professional'), 'casual'); ?>>Casual</option>
<option value="authoritative" <?php selected(igny8_get_ai_setting('ai_tone', 'professional'), 'authoritative'); ?>>Authoritative</option>
<option value="friendly" <?php selected(igny8_get_ai_setting('ai_tone', 'professional'), 'friendly'); ?>>Friendly</option>
<option value="technical" <?php selected(igny8_get_ai_setting('ai_tone', 'professional'), 'technical'); ?>>Technical</option>
</select>
<small class="igny8-field-description">Choose the default tone for AI-generated content</small>
</div>
<!-- Writing Level -->
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="writing_level" class="igny8-field-label">Writing Level</label>
<select name="writing_level" id="writing_level" class="igny8-select" style="width: 100%;">
<option value="beginner" <?php selected(igny8_get_ai_setting('writing_level', 'intermediate'), 'beginner'); ?>>Beginner (Simple, clear language)</option>
<option value="intermediate" <?php selected(igny8_get_ai_setting('writing_level', 'intermediate'), 'intermediate'); ?>>Intermediate (Balanced complexity)</option>
<option value="advanced" <?php selected(igny8_get_ai_setting('writing_level', 'intermediate'), 'advanced'); ?>>Advanced (Complex, detailed)</option>
</select>
<small class="igny8-field-description">Select the complexity level for AI-generated content</small>
</div>
<!-- Content Length Preference -->
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="content_length" class="igny8-field-label">Preferred Content Length</label>
<select name="content_length" id="content_length" class="igny8-select" style="width: 100%;">
<option value="short" <?php selected(igny8_get_ai_setting('content_length', 'medium'), 'short'); ?>>Short (300-500 words)</option>
<option value="medium" <?php selected(igny8_get_ai_setting('content_length', 'medium'), 'medium'); ?>>Medium (500-1000 words)</option>
<option value="long" <?php selected(igny8_get_ai_setting('content_length', 'medium'), 'long'); ?>>Long (1000+ words)</option>
</select>
<small class="igny8-field-description">Choose the preferred length for AI-generated content</small>
</div>
<!-- Custom Instructions -->
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="custom_instructions" class="igny8-field-label">Custom AI Instructions</label>
<textarea name="custom_instructions" id="custom_instructions" rows="6" class="igny8-textarea igny8-textarea-blue" style="width: 100%;" placeholder="Enter specific instructions for how the AI should behave, write, or respond..."><?php echo esc_textarea(wp_unslash(igny8_get_ai_setting('custom_instructions', ''))); ?></textarea>
<small class="igny8-field-description">These instructions will be added to all AI prompts to customize behavior.</small>
</div>
</form>
</div>
</div>
</div>
<!-- SEO Preferences Section -->
<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>SEO Preferences</h3>
<p class="igny8-card-subtitle">Configure SEO optimization settings and preferences</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-search igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<form id="igny8-seo-profile-form">
<!-- Keyword Density -->
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="keyword_density" class="igny8-field-label">Keyword Density Preference</label>
<select name="keyword_density" id="keyword_density" class="igny8-select" style="width: 100%;">
<option value="low" <?php selected(igny8_get_ai_setting('keyword_density', 'medium'), 'low'); ?>>Low (1-2%)</option>
<option value="medium" <?php selected(igny8_get_ai_setting('keyword_density', 'medium'), 'medium'); ?>>Medium (2-3%)</option>
<option value="high" <?php selected(igny8_get_ai_setting('keyword_density', 'medium'), 'high'); ?>>High (3-4%)</option>
</select>
<small class="igny8-field-description">Choose the keyword density for SEO optimization</small>
</div>
<!-- Meta Description Length -->
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="meta_description_length" class="igny8-field-label">Meta Description Length</label>
<select name="meta_description_length" id="meta_description_length" class="igny8-select" style="width: 100%;">
<option value="short" <?php selected(igny8_get_ai_setting('meta_description_length', 'medium'), 'short'); ?>>Short (120-140 chars)</option>
<option value="medium" <?php selected(igny8_get_ai_setting('meta_description_length', 'medium'), 'medium'); ?>>Medium (140-160 chars)</option>
<option value="long" <?php selected(igny8_get_ai_setting('meta_description_length', 'medium'), 'long'); ?>>Long (160+ chars)</option>
</select>
<small class="igny8-field-description">Choose the preferred length for meta descriptions</small>
</div>
<!-- Include Schema Markup -->
<div class="igny8-form-group" style="margin-bottom: 15px;">
<label class="igny8-checkbox-label" style="display: flex; align-items: center; gap: 10px;">
<input type="checkbox" name="include_schema" id="include_schema" <?php checked(igny8_get_ai_setting('include_schema', false)); ?>>
<span class="igny8-checkbox-text">Include Schema.org markup suggestions</span>
</label>
<small class="igny8-field-description">Enable structured data recommendations for better SEO</small>
</div>
<!-- Include Internal Linking -->
<div class="igny8-form-group" style="margin-bottom: 15px;">
<label class="igny8-checkbox-label" style="display: flex; align-items: center; gap: 10px;">
<input type="checkbox" name="include_internal_links" id="include_internal_links" <?php checked(igny8_get_ai_setting('include_internal_links', true)); ?>>
<span class="igny8-checkbox-text">Suggest internal linking opportunities</span>
</label>
<small class="igny8-field-description">Enable internal linking suggestions for better site structure</small>
</div>
</form>
</div>
</div>
</div>
<!-- Content Structure Preferences -->
<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>Content Structure Preferences</h3>
<p class="igny8-card-subtitle">Configure content structure and formatting preferences</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-list-view igny8-dashboard-icon-lg igny8-dashboard-icon-purple"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<form id="igny8-structure-profile-form">
<!-- Heading Structure -->
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="heading_style" class="igny8-field-label">Heading Style Preference</label>
<select name="heading_style" id="heading_style" class="igny8-select" style="width: 100%;">
<option value="hierarchical" <?php selected(igny8_get_ai_setting('heading_style', 'hierarchical'), 'hierarchical'); ?>>Hierarchical (H1 > H2 > H3)</option>
<option value="flat" <?php selected(igny8_get_ai_setting('heading_style', 'hierarchical'), 'flat'); ?>>Flat (H1 > H2 only)</option>
<option value="minimal" <?php selected(igny8_get_ai_setting('heading_style', 'hierarchical'), 'minimal'); ?>>Minimal (H1 only)</option>
</select>
<small class="igny8-field-description">Choose the heading structure for content organization</small>
</div>
<!-- Include Table of Contents -->
<div class="igny8-form-group" style="margin-bottom: 15px;">
<label class="igny8-checkbox-label" style="display: flex; align-items: center; gap: 10px;">
<input type="checkbox" name="include_toc" id="include_toc" <?php checked(igny8_get_ai_setting('include_toc', false)); ?>>
<span class="igny8-checkbox-text">Include Table of Contents for long articles</span>
</label>
<small class="igny8-field-description">Automatically generate table of contents for lengthy content</small>
</div>
<!-- Include Call-to-Action -->
<div class="igny8-form-group" style="margin-bottom: 15px;">
<label class="igny8-checkbox-label" style="display: flex; align-items: center; gap: 10px;">
<input type="checkbox" name="include_cta" id="include_cta" <?php checked(igny8_get_ai_setting('include_cta', true)); ?>>
<span class="igny8-checkbox-text">Include Call-to-Action sections</span>
</label>
<small class="igny8-field-description">Add call-to-action sections to engage readers</small>
</div>
<!-- Bullet Points Preference -->
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="bullet_style" class="igny8-field-label">Bullet Points Style</label>
<select name="bullet_style" id="bullet_style" class="igny8-select" style="width: 100%;">
<option value="numbered" <?php selected(igny8_get_ai_setting('bullet_style', 'bulleted'), 'numbered'); ?>>Numbered Lists</option>
<option value="bulleted" <?php selected(igny8_get_ai_setting('bullet_style', 'bulleted'), 'bulleted'); ?>>Bulleted Lists</option>
<option value="mixed" <?php selected(igny8_get_ai_setting('bullet_style', 'bulleted'), 'mixed'); ?>>Mixed (as appropriate)</option>
</select>
<small class="igny8-field-description">Choose the preferred list style for content</small>
</div>
</form>
</div>
</div>
</div>
<!-- Save Actions -->
<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>Profile Actions</h3>
<p class="igny8-card-subtitle">Save, reset, or test your AI profile settings</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-form-actions">
<button type="button" id="igny8-save-profile" class="igny8-btn igny8-btn-success">
<span class="dashicons dashicons-yes"></span>
Save AI Profile
</button>
<button type="button" id="igny8-reset-profile" class="igny8-btn igny8-btn-outline">
<span class="dashicons dashicons-update"></span>
Reset to Defaults
</button>
<button type="button" id="igny8-test-profile" class="igny8-btn igny8-btn-primary">
<span class="dashicons dashicons-admin-network"></span>
Test Profile Settings
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
// Save AI Profile
$('#igny8-save-profile').on('click', function() {
var formData = {
action: 'igny8_save_ai_profile',
nonce: '<?php echo wp_create_nonce('igny8_thinker_profile'); ?>',
ai_tone: $('#ai_tone').val(),
writing_level: $('#writing_level').val(),
content_length: $('#content_length').val(),
custom_instructions: $('#custom_instructions').val(),
keyword_density: $('#keyword_density').val(),
meta_description_length: $('#meta_description_length').val(),
include_schema: $('#include_schema').is(':checked'),
include_internal_links: $('#include_internal_links').is(':checked'),
heading_style: $('#heading_style').val(),
include_toc: $('#include_toc').is(':checked'),
include_cta: $('#include_cta').is(':checked'),
bullet_style: $('#bullet_style').val()
};
$.ajax({
url: ajaxurl,
type: 'POST',
data: formData,
success: function(response) {
if (response.success) {
igny8ShowNotification('AI Profile saved successfully!', 'success', 'thinker');
} else {
igny8ShowNotification('Error saving profile: ' + response.data, 'error', 'thinker');
}
},
error: function() {
igny8ShowNotification('Error saving profile', 'error', 'thinker');
}
});
});
// Reset Profile
$('#igny8-reset-profile').on('click', function() {
if (confirm('Are you sure you want to reset the AI profile to default settings?')) {
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'igny8_reset_ai_profile',
nonce: '<?php echo wp_create_nonce('igny8_thinker_profile'); ?>'
},
success: function(response) {
if (response.success) {
igny8ShowNotification('AI Profile reset to defaults!', 'success', 'thinker');
// Update form fields with reset values from response
if (response.data) {
if (response.data.ai_tone) $('#ai_tone').val(response.data.ai_tone);
if (response.data.writing_level) $('#writing_level').val(response.data.writing_level);
if (response.data.content_length) $('#content_length').val(response.data.content_length);
if (response.data.custom_instructions) $('#custom_instructions').val(response.data.custom_instructions);
if (response.data.keyword_density) $('#keyword_density').val(response.data.keyword_density);
if (response.data.meta_description_length) $('#meta_description_length').val(response.data.meta_description_length);
if (response.data.include_schema !== undefined) $('#include_schema').prop('checked', response.data.include_schema);
if (response.data.include_internal_links !== undefined) $('#include_internal_links').prop('checked', response.data.include_internal_links);
if (response.data.heading_style) $('#heading_style').val(response.data.heading_style);
if (response.data.include_toc !== undefined) $('#include_toc').prop('checked', response.data.include_toc);
if (response.data.include_cta !== undefined) $('#include_cta').prop('checked', response.data.include_cta);
if (response.data.bullet_style) $('#bullet_style').val(response.data.bullet_style);
}
} else {
igny8ShowNotification('Error resetting profile: ' + response.data, 'error', 'thinker');
}
},
error: function() {
igny8ShowNotification('Error resetting profile', 'error', 'thinker');
}
});
}
});
// Test Profile
$('#igny8-test-profile').on('click', function() {
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'igny8_test_ai_profile',
nonce: '<?php echo wp_create_nonce('igny8_thinker_profile'); ?>'
},
success: function(response) {
if (response.success) {
igny8ShowNotification('AI Profile test successful!', 'success', 'thinker');
} else {
igny8ShowNotification('AI Profile test failed: ' + response.data, 'error', 'thinker');
}
},
error: function() {
igny8ShowNotification('Error testing profile', 'error', 'thinker');
}
});
});
});
</script>
<!-- Global notification system is handled by core.js -->
<?php

View File

@@ -0,0 +1,461 @@
<?php
/**
* ==========================
* 🔐 IGNY8 FILE RULE HEADER
* ==========================
* @file : prompts.php
* @location : /modules/thinker/prompts.php
* @type : Admin Page
* @scope : Module Only
* @allowed : AI prompt management, prompt editing, AI configuration
* @reusability : Single Use
* @notes : AI prompt management interface for thinker module
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Prompts subpage - show AI prompts management
?>
<div class="igny8-module-page">
<div class="igny8-container">
<!-- Page title removed - titles should not appear inside page content -->
<!-- Planner Prompts Section -->
<div class="igny8-dashboard-section">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Planner Prompts</h3>
<p class="igny8-card-subtitle">Configure AI prompt templates for clustering and idea generation</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-edit igny8-dashboard-icon-lg igny8-dashboard-icon-amber"></span>
</div>
</div>
</div>
<?php if (igny8_get_ai_setting('planner_mode', 'manual') === 'ai'): ?>
<!-- Clustering Prompt Card -->
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h4>Clustering Prompt</h4>
<p class="igny8-card-subtitle">Group keywords into topic clusters</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-networking igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
</div>
</div>
</div>
<div class="igny8-card-body" style="text-align: center;">
<p class="description">This prompt is used to group keywords into topic clusters. Use [IGNY8_KEYWORDS] to inject keyword data.</p>
<textarea name="igny8_clustering_prompt" rows="8" class="igny8-textarea-green" style="width: 90%; margin: 0 auto; font-family: monospace; font-size: 14px; min-height: 300px; display: block;"><?php echo esc_textarea(wp_unslash(igny8_get_ai_setting('clustering_prompt', igny8_get_default_clustering_prompt()))); ?></textarea>
<div class="igny8-form-actions" style="margin-top: 15px;">
<button type="button" id="igny8-save-clustering-prompt" class="igny8-btn igny8-btn-success">Save Clustering Prompt</button>
<button type="button" id="igny8-reset-clustering-prompt" class="igny8-btn igny8-btn-outline">Reset to Default</button>
</div>
</div>
</div>
<!-- Ideas Generation Prompt Card -->
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h4>Ideas Generation Prompt</h4>
<p class="igny8-card-subtitle">Generate content ideas from clusters</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-lightbulb igny8-dashboard-icon-lg igny8-dashboard-icon-orange"></span>
</div>
</div>
</div>
<div class="igny8-card-body" style="text-align: center;">
<p class="description">This prompt generates content ideas from clusters. Use [IGNY8_CLUSTERS] to inject cluster data.</p>
<textarea name="igny8_ideas_prompt" rows="8" class="igny8-textarea-orange" style="width: 90%; margin: 0 auto; font-family: monospace; font-size: 14px; min-height: 300px; display: block;"><?php echo esc_textarea(wp_unslash(igny8_get_ai_setting('ideas_prompt', igny8_get_default_ideas_prompt()))); ?></textarea>
<div class="igny8-form-actions" style="margin-top: 15px;">
<button type="button" id="igny8-save-ideas-prompt" class="igny8-btn igny8-btn-success">Save Ideas Prompt</button>
<button type="button" id="igny8-reset-ideas-prompt" class="igny8-btn igny8-btn-outline">Reset to Default</button>
</div>
</div>
</div>
<?php else: ?>
<div class="igny8-card">
<div class="igny8-card-body">
<div class="igny8-info-box">
<p><strong>Note:</strong> Planner prompts are only available when AI-Powered SEO Mode is enabled in the Planner module.</p>
<a href="<?php echo admin_url('admin.php?page=igny8-planner'); ?>" class="igny8-btn igny8-btn-primary">Go to Planner Settings</a>
</div>
</div>
</div>
<?php endif; ?>
</div>
<!-- Writer Prompts Section -->
<div class="igny8-dashboard-section">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Writer Prompts</h3>
<p class="igny8-card-subtitle">Configure AI prompt templates for content writing</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-edit-page igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
</div>
</div>
</div>
<?php if (igny8_get_ai_setting('writer_mode', 'manual') === 'ai'): ?>
<!-- Content Generation Prompt Card -->
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h4>Content Generation Prompt</h4>
<p class="igny8-card-subtitle">Generate content from ideas</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-edit-page igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
</div>
</div>
</div>
<div class="igny8-card-body" style="text-align: center;">
<!-- Content Generation Prompt -->
<p class="description">This prompt is used to generate content from ideas. Use [IGNY8_IDEA] to inject idea data, [IGNY8_CLUSTER] for cluster data, and [IGNY8_KEYWORDS] for keywords.</p>
<textarea name="igny8_content_generation_prompt" rows="8" class="igny8-textarea-blue" style="width: 90%; margin: 0 auto; font-family: monospace; font-size: 14px; min-height: 300px; display: block;"><?php echo esc_textarea(wp_unslash(igny8_get_ai_setting('content_generation_prompt', igny8_content_generation_prompt()))); ?></textarea>
<div class="igny8-form-actions" style="margin-top: 15px;">
<button type="button" id="igny8-save-content-generation-prompt" class="igny8-btn igny8-btn-success">Save Content Generation Prompt</button>
<button type="button" id="igny8-reset-content-generation-prompt" class="igny8-btn igny8-btn-outline">Reset to Default</button>
</div>
</div>
</div>
<?php else: ?>
<div class="igny8-card">
<div class="igny8-card-body">
<div class="igny8-info-box">
<p><strong>Note:</strong> Writer prompts are only available when AI-Powered Mode is enabled in the Writer module.</p>
<a href="<?php echo admin_url('admin.php?page=igny8-writer'); ?>" class="igny8-btn igny8-btn-primary">Go to Writer Settings</a>
</div>
</div>
</div>
<?php endif; ?>
</div>
<!-- Image Generation Section -->
<div class="igny8-dashboard-section">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Image Generation</h3>
<p class="igny8-card-subtitle">Test and configure AI image generation with DALL·E 3 and Runware</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="">
<div class="igny8-card igny8-prompt-section"> <!-- Image Generation Form -->
<div class="igny8-dashboard-section">
<!-- Prompt Settings -->
<div class="igny8-card-body">
<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="8" class="igny8-form-control" placeholder="Enter your custom prompt template..."><?php echo esc_textarea(wp_unslash(get_option('igny8_image_prompt_template', 'Create a high-quality {image_type} image to use as a featured photo for a blog post titled "{post_title}". The image should visually represent the theme, mood, and subject implied by the image prompt: {image_prompt}. Focus on a realistic, well-composed scene that naturally communicates the topic without text or logos. Use balanced lighting, pleasing composition, and photographic detail suitable for lifestyle or editorial web content. Avoid adding any visible or readable text, brand names, or illustrative effects. **And make sure image is not blurry.**'))); ?></textarea>
<small class="form-help">
<strong>Available placeholders:</strong><br>
<code>{post_title}</code> - Post title<br>
<code>{image_prompt}</code> - Image prompt (featured or in-article based on request)<br>
<code>{image_type}</code> - Selected image type (from settings)
</small>
<div class="igny8-form-actions" style="margin-top: 10px;">
<button type="button" id="igny8-save-image-prompt-template" class="igny8-btn igny8-btn-success">Save Prompt Template</button>
<button type="button" id="igny8-reset-image-prompt-template" class="igny8-btn igny8-btn-outline">Reset to Default</button>
</div>
</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 esc_textarea(wp_unslash(get_option('igny8_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 class="igny8-form-actions" style="margin-top: 10px;">
<button type="button" id="igny8-save-negative-prompt" class="igny8-btn igny8-btn-success">Save Negative Prompt</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<?php
// Localize script for prompts page
wp_localize_script('igny8-admin-js', 'IGNY8_PAGE', [
'module' => 'thinker',
'subpage' => 'prompts',
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('igny8_thinker_settings')
]);
// Add JavaScript for prompt management
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
// Save prompts
$('#igny8-save-clustering-prompt').on('click', function() {
savePrompt('clustering_prompt', $('textarea[name="igny8_clustering_prompt"]').val());
});
$('#igny8-save-ideas-prompt').on('click', function() {
savePrompt('ideas_prompt', $('textarea[name="igny8_ideas_prompt"]').val());
});
$('#igny8-save-content-generation-prompt').on('click', function() {
// Save content generation prompt
savePrompt('content_generation_prompt', $('textarea[name="igny8_content_generation_prompt"]').val());
});
// Reset prompts
$('#igny8-reset-clustering-prompt').on('click', function() {
resetPrompt('clustering_prompt');
});
$('#igny8-reset-ideas-prompt').on('click', function() {
resetPrompt('ideas_prompt');
});
$('#igny8-reset-content-generation-prompt').on('click', function() {
// Reset content generation prompt to default
if (confirm('Are you sure you want to reset the content generation prompt to default? This will overwrite any custom changes.')) {
$.ajax({
url: IGNY8_PAGE.ajaxUrl,
type: 'POST',
data: {
action: 'igny8_reset_multiple_prompts',
prompt_types: ['content_generation_prompt'],
nonce: IGNY8_PAGE.nonce
},
success: function(response) {
if (response.success) {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Content generation prompt reset to default successfully!', 'success', 'thinker');
}
// Update textarea with reset value
if (response.data && response.data.content_generation_prompt) {
$('textarea[name="igny8_content_generation_prompt"]').val(response.data.content_generation_prompt);
}
} else {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error resetting prompts: ' + (response.data || 'Unknown error'), 'error', 'thinker');
}
}
},
error: function() {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error resetting prompts. Please try again.', 'error', 'thinker');
}
}
});
}
});
// Reset image prompt template
$('#igny8-reset-image-prompt-template').on('click', function() {
resetImagePromptTemplate();
});
// Save image prompt template
$('#igny8-save-image-prompt-template').on('click', function() {
saveImagePromptTemplate();
});
// Save negative prompt
$('#igny8-save-negative-prompt').on('click', function() {
saveNegativePrompt();
});
function savePrompt(promptType, promptValue) {
$.ajax({
url: IGNY8_PAGE.ajaxUrl,
type: 'POST',
data: {
action: 'igny8_save_prompt',
prompt_type: promptType,
prompt_value: promptValue,
nonce: IGNY8_PAGE.nonce
},
success: function(response) {
if (response.success) {
// Show specific prompt name in notification
var promptName = promptType.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase());
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification(promptName + ' saved successfully!', 'success', 'thinker');
}
} else {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error saving prompt: ' + response.data, 'error', 'thinker');
}
}
},
error: function() {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error saving prompt', 'error', 'thinker');
}
}
});
}
function resetPrompt(promptType) {
if (confirm('Are you sure you want to reset this prompt to default? This will overwrite any custom changes.')) {
$.ajax({
url: IGNY8_PAGE.ajaxUrl,
type: 'POST',
data: {
action: 'igny8_reset_prompt',
prompt_type: promptType,
nonce: IGNY8_PAGE.nonce
},
success: function(response) {
if (response.success) {
// Show specific prompt name in notification
var promptName = promptType.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase());
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification(promptName + ' reset to default successfully!', 'success', 'thinker');
}
// Update the textarea with the reset value from response
if (response.data && response.data.prompt_value) {
$('textarea[name="igny8_' + promptType + '"]').val(response.data.prompt_value);
}
} else {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error resetting prompt: ' + response.data, 'error', 'thinker');
}
}
},
error: function() {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error resetting prompt', 'error', 'thinker');
}
}
});
}
}
function saveImagePromptTemplate() {
const promptTemplate = $('#prompt_template').val();
$.ajax({
url: IGNY8_PAGE.ajaxUrl,
type: 'POST',
data: {
action: 'igny8_save_prompt',
prompt_type: 'image_prompt_template',
prompt_value: promptTemplate,
nonce: IGNY8_PAGE.nonce
},
success: function(response) {
if (response.success) {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Image prompt template saved successfully!', 'success', 'thinker');
}
} else {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error saving image prompt template: ' + response.data, 'error', 'thinker');
}
}
},
error: function() {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error saving image prompt template', 'error', 'thinker');
}
}
});
}
function saveNegativePrompt() {
const negativePrompt = $('#negative_prompt').val();
$.ajax({
url: IGNY8_PAGE.ajaxUrl,
type: 'POST',
data: {
action: 'igny8_save_prompt',
prompt_type: 'negative_prompt',
prompt_value: negativePrompt,
nonce: IGNY8_PAGE.nonce
},
success: function(response) {
if (response.success) {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Negative prompt saved successfully!', 'success', 'thinker');
}
} else {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error saving negative prompt: ' + response.data, 'error', 'thinker');
}
}
},
error: function() {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error saving negative prompt', 'error', 'thinker');
}
}
});
}
function resetImagePromptTemplate() {
if (confirm('Are you sure you want to reset the image prompt template to default? This will overwrite any custom changes.')) {
$.ajax({
url: IGNY8_PAGE.ajaxUrl,
type: 'POST',
data: {
action: 'igny8_reset_image_prompt_template',
nonce: IGNY8_PAGE.nonce
},
success: function(response) {
if (response.success) {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Image Prompt Template reset to default successfully!', 'success', 'thinker');
}
// Update the textarea with the reset value from response
if (response.data && response.data.prompt_value) {
$('#prompt_template').val(response.data.prompt_value);
}
} else {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error resetting image prompt template: ' + response.data, 'error', 'thinker');
}
}
},
error: function() {
if (typeof igny8ShowNotification === 'function') {
igny8ShowNotification('Error resetting image prompt template', 'error', 'thinker');
}
}
});
}
}
});
</script>
// Global notification system is handled by core.js

View File

@@ -0,0 +1,408 @@
<?php
/**
* ==========================
* 🔐 IGNY8 FILE RULE HEADER
* ==========================
* @file : strategies.php
* @location : /modules/thinker/strategies.php
* @type : Admin Page
* @scope : Module Only
* @allowed : Content strategy management, AI generation patterns, strategic approaches
* @reusability : Single Use
* @notes : Content strategy management interface for thinker module
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
?>
<div class="igny8-module-page">
<div class="igny8-container">
<!-- Page title removed - titles should not appear inside page content -->
<!-- Strategy Templates Section -->
<div class="igny8-dashboard-section">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Strategy Templates</h3>
<p class="igny8-card-subtitle">Pre-built content strategies for different use cases</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-admin-page igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
</div>
</div>
</div>
<div class="igny8-grid-4">
<!-- Blog Post Strategy -->
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h4>Blog Post Strategy</h4>
<p class="igny8-card-subtitle">Comprehensive blog post creation with SEO optimization</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-edit-page igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<p>Comprehensive blog post creation with SEO optimization, internal linking, and engagement elements.</p>
<div class="igny8-strategy-features">
<span class="igny8-badge igny8-badge-info">SEO Optimized</span>
<span class="igny8-badge igny8-badge-info">Internal Links</span>
<span class="igny8-badge igny8-badge-info">CTA Included</span>
</div>
<div class="igny8-form-actions">
<button type="button" class="igny8-btn igny8-btn-sm igny8-btn-primary" onclick="igny8EditStrategy('blog_post')">
<span class="dashicons dashicons-edit"></span>
Edit
</button>
<button type="button" class="igny8-btn igny8-btn-sm igny8-btn-outline" onclick="igny8TestStrategy('blog_post')">
<span class="dashicons dashicons-admin-network"></span>
Test
</button>
</div>
</div>
</div>
<!-- Product Description Strategy -->
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h4>Product Description Strategy</h4>
<p class="igny8-card-subtitle">E-commerce focused product descriptions with conversion optimization</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-cart igny8-dashboard-icon-lg igny8-dashboard-icon-orange"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<p>E-commerce focused product descriptions with conversion optimization and feature highlighting.</p>
<div class="igny8-strategy-features">
<span class="igny8-badge igny8-badge-warning">Conversion Focused</span>
<span class="igny8-badge igny8-badge-warning">Feature Rich</span>
<span class="igny8-badge igny8-badge-warning">Benefit Driven</span>
</div>
<div class="igny8-form-actions">
<button type="button" class="igny8-btn igny8-btn-sm igny8-btn-primary" onclick="igny8EditStrategy('product_description')">
<span class="dashicons dashicons-edit"></span>
Edit
</button>
<button type="button" class="igny8-btn igny8-btn-sm igny8-btn-outline" onclick="igny8TestStrategy('product_description')">
<span class="dashicons dashicons-admin-network"></span>
Test
</button>
</div>
</div>
</div>
<!-- Landing Page Strategy -->
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h4>Landing Page Strategy</h4>
<p class="igny8-card-subtitle">High-converting landing pages with persuasive copy and social proof</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-admin-home igny8-dashboard-icon-lg igny8-dashboard-icon-purple"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<p>High-converting landing pages with persuasive copy, social proof, and clear value propositions.</p>
<div class="igny8-strategy-features">
<span class="igny8-badge igny8-badge-success">Persuasive Copy</span>
<span class="igny8-badge igny8-badge-success">Social Proof</span>
<span class="igny8-badge igny8-badge-success">Clear CTA</span>
</div>
<div class="igny8-form-actions">
<button type="button" class="igny8-btn igny8-btn-sm igny8-btn-primary" onclick="igny8EditStrategy('landing_page')">
<span class="dashicons dashicons-edit"></span>
Edit
</button>
<button type="button" class="igny8-btn igny8-btn-sm igny8-btn-outline" onclick="igny8TestStrategy('landing_page')">
<span class="dashicons dashicons-admin-network"></span>
Test
</button>
</div>
</div>
</div>
<!-- Email Campaign Strategy -->
<div class="igny8-card">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h4>Email Campaign Strategy</h4>
<p class="igny8-card-subtitle">Engaging email sequences with personalization and automation</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-email igny8-dashboard-icon-lg igny8-dashboard-icon-teal"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<p>Engaging email sequences with personalization, segmentation, and automated follow-ups.</p>
<div class="igny8-strategy-features">
<span class="igny8-badge igny8-badge-info">Personalized</span>
<span class="igny8-badge igny8-badge-info">Segmented</span>
<span class="igny8-badge igny8-badge-info">Automated</span>
</div>
<div class="igny8-form-actions">
<button type="button" class="igny8-btn igny8-btn-sm igny8-btn-primary" onclick="igny8EditStrategy('email_campaign')">
<span class="dashicons dashicons-edit"></span>
Edit
</button>
<button type="button" class="igny8-btn igny8-btn-sm igny8-btn-outline" onclick="igny8TestStrategy('email_campaign')">
<span class="dashicons dashicons-admin-network"></span>
Test
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Custom Strategy Builder -->
<div class="igny8-dashboard-section">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Custom Strategy Builder</h3>
<p class="igny8-card-subtitle">Create custom content strategies tailored to your needs</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-plus-alt igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
</div>
</div>
</div>
<div class="igny8-card">
<div class="igny8-card-body">
<form id="igny8-custom-strategy-form">
<div class="igny8-form-row" style="display: flex; gap: 20px; margin-bottom: 20px;">
<div class="igny8-form-group" style="flex: 1;">
<label for="strategy_name" class="igny8-field-label">Strategy Name</label>
<input type="text" name="strategy_name" id="strategy_name" class="igny8-input" style="width: 100%;" placeholder="Enter strategy name...">
<small class="igny8-field-description">Choose a descriptive name for your strategy</small>
</div>
<div class="igny8-form-group" style="flex: 1;">
<label for="strategy_type" class="igny8-field-label">Strategy Type</label>
<select name="strategy_type" id="strategy_type" class="igny8-select" style="width: 100%;">
<option value="content">Content Creation</option>
<option value="marketing">Marketing Campaign</option>
<option value="seo">SEO Strategy</option>
<option value="social">Social Media</option>
<option value="email">Email Marketing</option>
</select>
<small class="igny8-field-description">Select the category for your strategy</small>
</div>
</div>
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="strategy_description" class="igny8-field-label">Strategy Description</label>
<textarea name="strategy_description" id="strategy_description" rows="4" class="igny8-textarea igny8-textarea-blue" style="width: 100%;" placeholder="Describe the purpose and goals of this strategy..."></textarea>
<small class="igny8-field-description">Provide a clear description of what this strategy aims to achieve</small>
</div>
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="strategy_goals" class="igny8-field-label">Goals & Objectives</label>
<textarea name="strategy_goals" id="strategy_goals" rows="3" class="igny8-textarea igny8-textarea-green" style="width: 100%;" placeholder="List the specific goals and objectives for this strategy..."></textarea>
<small class="igny8-field-description">Define the specific goals and measurable objectives</small>
</div>
<div class="igny8-form-group" style="margin-bottom: 20px;">
<label for="strategy_instructions" class="igny8-field-label">AI Instructions</label>
<textarea name="strategy_instructions" id="strategy_instructions" rows="6" class="igny8-textarea igny8-textarea-purple" style="width: 100%;" placeholder="Provide specific instructions for how the AI should approach this strategy..."></textarea>
<small class="igny8-field-description">Detailed instructions for AI behavior and approach</small>
</div>
<div class="igny8-form-actions">
<button type="button" id="igny8-save-strategy" class="igny8-btn igny8-btn-success">
<span class="dashicons dashicons-yes"></span>
Save Strategy
</button>
<button type="button" id="igny8-test-strategy" class="igny8-btn igny8-btn-primary">
<span class="dashicons dashicons-admin-network"></span>
Test Strategy
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Strategy Performance -->
<div class="igny8-dashboard-section">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Strategy Performance</h3>
<p class="igny8-card-subtitle">Track the performance and success of your strategies</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-chart-bar igny8-dashboard-icon-lg igny8-dashboard-icon-purple"></span>
</div>
</div>
</div>
<div class="igny8-card">
<div class="igny8-card-body">
<div class="igny8-performance-grid">
<div class="igny8-performance-item">
<div class="igny8-performance-value"><?php echo esc_html(igny8_get_ai_setting('strategies_created', 0)); ?></div>
<div class="igny8-performance-label">Strategies Created</div>
</div>
<div class="igny8-performance-item">
<div class="igny8-performance-value"><?php echo esc_html(igny8_get_ai_setting('strategy_success_rate', '0%')); ?></div>
<div class="igny8-performance-label">Success Rate</div>
</div>
<div class="igny8-performance-item">
<div class="igny8-performance-value"><?php echo esc_html(igny8_get_ai_setting('content_generated', 0)); ?></div>
<div class="igny8-performance-label">Content Generated</div>
</div>
<div class="igny8-performance-item">
<div class="igny8-performance-value"><?php echo esc_html(igny8_get_ai_setting('avg_engagement', '0%')); ?></div>
<div class="igny8-performance-label">Avg Engagement</div>
</div>
</div>
</div>
</div>
</div>
<!-- Recent Strategy Activity -->
<div class="igny8-dashboard-section">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Recent Strategy Activity</h3>
<p class="igny8-card-subtitle">Monitor recent strategy usage and activity</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-clock igny8-dashboard-icon-lg igny8-dashboard-icon-orange"></span>
</div>
</div>
</div>
<div class="igny8-card">
<div class="igny8-card-body">
<div class="igny8-activity-list">
<div class="igny8-empty-state">
<p>No recent strategy activity. Create and use strategies to see activity here.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
// Edit Strategy
window.igny8EditStrategy = function(strategyType) {
// Open strategy editor modal or redirect to edit page
igny8ShowNotification('Opening strategy editor for ' + strategyType, 'info', 'thinker');
};
// Test Strategy
window.igny8TestStrategy = function(strategyType) {
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'igny8_test_strategy',
strategy_type: strategyType,
nonce: '<?php echo wp_create_nonce('igny8_thinker_strategies'); ?>'
},
success: function(response) {
if (response.success) {
igny8ShowNotification('Strategy test successful for ' + strategyType, 'success', 'thinker');
} else {
igny8ShowNotification('Strategy test failed: ' + response.data, 'error', 'thinker');
}
},
error: function() {
igny8ShowNotification('Error testing strategy', 'error', 'thinker');
}
});
};
// Save Custom Strategy
$('#igny8-save-strategy').on('click', function() {
var formData = {
action: 'igny8_save_custom_strategy',
nonce: '<?php echo wp_create_nonce('igny8_thinker_strategies'); ?>',
strategy_name: $('#strategy_name').val(),
strategy_type: $('#strategy_type').val(),
strategy_description: $('#strategy_description').val(),
strategy_goals: $('#strategy_goals').val(),
strategy_instructions: $('#strategy_instructions').val()
};
if (!formData.strategy_name || !formData.strategy_description) {
igny8ShowNotification('Please fill in required fields', 'warning', 'thinker');
return;
}
$.ajax({
url: ajaxurl,
type: 'POST',
data: formData,
success: function(response) {
if (response.success) {
igny8ShowNotification('Custom strategy saved successfully!', 'success', 'thinker');
$('#igny8-custom-strategy-form')[0].reset();
} else {
igny8ShowNotification('Error saving strategy: ' + response.data, 'error', 'thinker');
}
},
error: function() {
igny8ShowNotification('Error saving strategy', 'error', 'thinker');
}
});
});
// Test Custom Strategy
$('#igny8-test-strategy').on('click', function() {
var formData = {
action: 'igny8_test_custom_strategy',
nonce: '<?php echo wp_create_nonce('igny8_thinker_strategies'); ?>',
strategy_name: $('#strategy_name').val(),
strategy_type: $('#strategy_type').val(),
strategy_description: $('#strategy_description').val(),
strategy_goals: $('#strategy_goals').val(),
strategy_instructions: $('#strategy_instructions').val()
};
if (!formData.strategy_name || !formData.strategy_description) {
igny8ShowNotification('Please fill in required fields before testing', 'warning', 'thinker');
return;
}
$.ajax({
url: ajaxurl,
type: 'POST',
data: formData,
success: function(response) {
if (response.success) {
igny8ShowNotification('Custom strategy test successful!', 'success', 'thinker');
} else {
igny8ShowNotification('Custom strategy test failed: ' + response.data, 'error', 'thinker');
}
},
error: function() {
igny8ShowNotification('Error testing strategy', 'error', 'thinker');
}
});
});
});
</script>
<!-- Notification Area -->
<!-- Global notification system is handled by core.js -->
<?php

View File

@@ -0,0 +1,224 @@
<?php
/**
* ==========================
* 🔐 IGNY8 FILE RULE HEADER
* ==========================
* @file : thinker.php
* @location : /modules/thinker/thinker.php
* @type : Admin Page
* @scope : Module Only
* @allowed : Thinker module logic, subpage routing, AI interface
* @reusability : Single Use
* @notes : Main thinker page with subpage routing for AI features
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Handle URL parameters for subpages
$subpage = $_GET['sp'] ?? 'main';
$GLOBALS['igny8_current_subpage'] = $subpage;
// Start output buffering
ob_start();
switch ($subpage) {
case 'prompts':
include plugin_dir_path(__FILE__) . 'prompts.php';
break;
case 'profile':
include plugin_dir_path(__FILE__) . 'profile.php';
break;
case 'strategies':
include plugin_dir_path(__FILE__) . 'strategies.php';
break;
case 'image-testing':
include plugin_dir_path(__FILE__) . 'image-testing.php';
break;
case 'main':
default:
// Main dashboard content
?>
<div class="igny8-module-page">
<div class="igny8-container">
<!-- Thinker Workflow Steps -->
<div class="igny8-dashboard-section">
<div class="igny8-standard-header">
<div class="igny8-card-header-content">
<div class="igny8-card-title-text">
<h3>Thinker Workflow Steps</h3>
<p class="igny8-card-subtitle">Track your AI configuration progress</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-admin-tools igny8-dashboard-icon-lg igny8-dashboard-icon-green"></span>
</div>
</div>
</div>
<div class="igny8-grid igny8-grid-4">
<!-- AI Prompts Step -->
<div class="igny8-card igny8-step-card completed">
<div class="igny8-card-body">
<div class="igny8-step-header">
<div class="igny8-step-number">1</div>
<div class="igny8-step-title">AI Prompts</div>
</div>
<div class="igny8-step-status">
<span class="igny8-step-status-icon">✅</span>
<span class="igny8-step-status-text">Configured</span>
</div>
<div class="igny8-step-data">
Manage AI prompt templates
</div>
<div class="igny8-step-action">
<a href="?page=igny8-thinker&sp=prompts" class="igny8-btn igny8-btn-primary igny8-btn-sm">Configure</a>
</div>
</div>
</div>
<!-- AI Profile Step -->
<div class="igny8-card igny8-step-card current">
<div class="igny8-card-body">
<div class="igny8-step-header">
<div class="igny8-step-number">2</div>
<div class="igny8-step-title">AI Profile</div>
</div>
<div class="igny8-step-status">
<span class="igny8-step-status-icon">⏳</span>
<span class="igny8-step-status-text">Ready</span>
</div>
<div class="igny8-step-data">
Set AI behavior and tone
</div>
<div class="igny8-step-action">
<a href="?page=igny8-thinker&sp=profile" class="igny8-btn igny8-btn-primary igny8-btn-sm">Configure</a>
</div>
</div>
</div>
<!-- Content Strategies Step -->
<div class="igny8-card igny8-step-card pending">
<div class="igny8-card-body">
<div class="igny8-step-header">
<div class="igny8-step-number">3</div>
<div class="igny8-step-title">Content Strategies</div>
</div>
<div class="igny8-step-status">
<span class="igny8-step-status-icon">⏳</span>
<span class="igny8-step-status-text">Pending</span>
</div>
<div class="igny8-step-data">
Define content strategies
</div>
<div class="igny8-step-action">
<a href="?page=igny8-thinker&sp=strategies" class="igny8-btn igny8-btn-primary igny8-btn-sm">Configure</a>
</div>
</div>
</div>
<!-- Image Testing Step -->
<div class="igny8-card igny8-step-card pending">
<div class="igny8-card-body">
<div class="igny8-step-header">
<div class="igny8-step-number">4</div>
<div class="igny8-step-title">Image Testing</div>
</div>
<div class="igny8-step-status">
<span class="igny8-step-status-icon">⏳</span>
<span class="igny8-step-status-text">Pending</span>
</div>
<div class="igny8-step-data">
Test DALL·E 3 integration
</div>
<div class="igny8-step-action">
<a href="?page=igny8-thinker&sp=image-testing" class="igny8-btn igny8-btn-primary igny8-btn-sm">Test</a>
</div>
</div>
</div>
</div>
</div>
<!-- AI Settings & Quick Actions -->
<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 Settings & Quick Actions</h3>
<p class="igny8-card-subtitle">Manage AI configuration and test connections</p>
</div>
<div class="igny8-card-icon">
<span class="dashicons dashicons-admin-settings igny8-dashboard-icon-lg igny8-dashboard-icon-blue"></span>
</div>
</div>
</div>
<div class="igny8-card-body">
<div class="igny8-flex-row">
<button onclick="igny8TestAIConnection()" class="igny8-btn igny8-btn-primary">Test AI Connection</button>
<button onclick="igny8ResetAISettings()" class="igny8-btn igny8-btn-outline">Reset AI Settings</button>
<button onclick="igny8ViewAILogs()" class="igny8-btn igny8-btn-outline">View AI Logs</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
// Test AI Connection
window.igny8TestAIConnection = function() {
// Check if API key is configured
const apiKey = '<?php echo get_option('igny8_api_key', ''); ?>';
if (!apiKey) {
igny8ShowNotification('Please configure your OpenAI API key in Settings first.', 'warning', 'thinker');
return;
}
// Show testing notification
igny8ShowNotification('Testing AI connection...', 'info', 'thinker');
// Simulate connection test (replace with actual API test)
setTimeout(() => {
igny8ShowNotification('AI connection test completed successfully!', 'success', 'thinker');
}, 2000);
};
// Execute Action based on selection
window.igny8ExecuteAction = function() {
const selectedAction = $('input[name="ai_action"]:checked').val();
if (selectedAction === 'reset') {
if (confirm('Are you sure you want to reset all AI settings to default? This will affect all modules.')) {
// Simulate reset action
igny8ShowNotification('AI settings have been reset to default values.', 'success', 'thinker');
}
} else if (selectedAction === 'logs') {
window.open('<?php echo admin_url('admin.php?page=igny8-analytics&sp=status'); ?>', '_blank');
}
};
// Reset AI Settings (legacy function)
window.igny8ResetAISettings = function() {
if (confirm('Are you sure you want to reset all AI settings to default? This will affect all modules.')) {
igny8ShowNotification('AI settings reset feature coming soon!', 'info', 'thinker');
}
};
// View AI Logs (legacy function)
window.igny8ViewAILogs = function() {
window.open('<?php echo admin_url('admin.php?page=igny8-analytics&sp=status'); ?>', '_blank');
};
});
</script>
</div>
</div>
<?php
break;
}
// Capture page content
$igny8_page_content = ob_get_clean();
// Include global layout
include_once plugin_dir_path(__FILE__) . '../../core/global-layout.php';