Make your WordPress site irresistible. Natural SEO attraction with: - robots.txt management - sitemap.xml generation - LLMs.txt support - Google integration (Analytics, Search Console, Tag Manager) - Schema.org structured data - Open Graph / Twitter Card meta tags - AMP support - Visual elements gallery - Built-in backup/restore module Includes build.sh and .distignore for WordPress-installable release ZIPs.
787 lines
37 KiB
PHP
787 lines
37 KiB
PHP
<?php
|
|
/**
|
|
* AI Provider Module for TigerStyle Heat
|
|
* OpenAI-compatible API provider with multi-key management
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
class TigerStyleSEO_AI_Provider {
|
|
private static $instance = null;
|
|
|
|
public static function instance() {
|
|
if (is_null(self::$instance)) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
private function __construct() {
|
|
$this->init();
|
|
}
|
|
|
|
/**
|
|
* Initialize AI provider functionality
|
|
*/
|
|
public function init() {
|
|
// Admin hooks
|
|
if (is_admin()) {
|
|
add_action('admin_post_update_ai_provider_settings', array($this, 'handle_form_submission'));
|
|
add_action('wp_ajax_tigerstyle_test_api_key', array($this, 'ajax_test_api_key'));
|
|
add_action('wp_ajax_tigerstyle_refresh_models', array($this, 'ajax_refresh_models'));
|
|
add_action('wp_ajax_tigerstyle_delete_api_key', array($this, 'ajax_delete_api_key'));
|
|
add_action('wp_ajax_tigerstyle_ai_chat', array($this, 'ajax_ai_chat'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get all configured API providers
|
|
*/
|
|
public function get_api_providers() {
|
|
return get_option('tigerstyle_ai_providers', array());
|
|
}
|
|
|
|
/**
|
|
* Get API provider by name
|
|
*/
|
|
public function get_api_provider($name) {
|
|
$providers = $this->get_api_providers();
|
|
return isset($providers[$name]) ? $providers[$name] : null;
|
|
}
|
|
|
|
/**
|
|
* Add or update API provider
|
|
*/
|
|
public function save_api_provider($name, $config) {
|
|
$providers = $this->get_api_providers();
|
|
|
|
// Encrypt API key
|
|
$config['api_key'] = $this->encrypt_api_key($config['api_key']);
|
|
$config['created_at'] = time();
|
|
$config['last_tested'] = null;
|
|
$config['test_status'] = 'pending';
|
|
$config['models'] = array();
|
|
|
|
$providers[$name] = $config;
|
|
update_option('tigerstyle_ai_providers', $providers);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Delete API provider
|
|
*/
|
|
public function delete_api_provider($name) {
|
|
$providers = $this->get_api_providers();
|
|
if (isset($providers[$name])) {
|
|
unset($providers[$name]);
|
|
update_option('tigerstyle_ai_providers', $providers);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Encrypt API key for secure storage
|
|
*/
|
|
private function encrypt_api_key($api_key) {
|
|
if (!function_exists('openssl_encrypt')) {
|
|
// Fallback to base64 encoding if OpenSSL not available
|
|
return base64_encode($api_key);
|
|
}
|
|
|
|
$encryption_key = $this->get_encryption_key();
|
|
$iv = openssl_random_pseudo_bytes(16);
|
|
$encrypted = openssl_encrypt($api_key, 'AES-256-CBC', $encryption_key, 0, $iv);
|
|
|
|
return base64_encode($iv . $encrypted);
|
|
}
|
|
|
|
/**
|
|
* Mask API key for display (show only first and last 4 characters)
|
|
*/
|
|
private function mask_api_key($api_key) {
|
|
if (strlen($api_key) <= 8) {
|
|
// If key is too short, show first 2 and last 2 characters
|
|
return substr($api_key, 0, 2) . str_repeat('*', max(4, strlen($api_key) - 4)) . substr($api_key, -2);
|
|
}
|
|
|
|
// Show first 4 and last 4 characters with asterisks in between
|
|
return substr($api_key, 0, 4) . str_repeat('*', max(8, strlen($api_key) - 8)) . substr($api_key, -4);
|
|
}
|
|
|
|
/**
|
|
* Get masked API key for display purposes
|
|
*/
|
|
public function get_masked_api_key($name) {
|
|
$provider = $this->get_api_provider($name);
|
|
if (!$provider) {
|
|
return null;
|
|
}
|
|
|
|
$decrypted_key = $this->decrypt_api_key($provider['api_key']);
|
|
return $this->mask_api_key($decrypted_key);
|
|
}
|
|
|
|
/**
|
|
* Decrypt API key
|
|
*/
|
|
private function decrypt_api_key($encrypted_key) {
|
|
if (!function_exists('openssl_decrypt')) {
|
|
// Fallback from base64 encoding
|
|
return base64_decode($encrypted_key);
|
|
}
|
|
|
|
$encryption_key = $this->get_encryption_key();
|
|
$data = base64_decode($encrypted_key);
|
|
$iv = substr($data, 0, 16);
|
|
$encrypted = substr($data, 16);
|
|
|
|
return openssl_decrypt($encrypted, 'AES-256-CBC', $encryption_key, 0, $iv);
|
|
}
|
|
|
|
/**
|
|
* Get encryption key for API keys
|
|
*/
|
|
private function get_encryption_key() {
|
|
$key = get_option('tigerstyle_ai_encryption_key');
|
|
if (!$key) {
|
|
$key = wp_generate_password(32, false);
|
|
update_option('tigerstyle_ai_encryption_key', $key);
|
|
}
|
|
return $key;
|
|
}
|
|
|
|
/**
|
|
* Test API key by listing models
|
|
*/
|
|
public function test_api_key($name) {
|
|
$provider = $this->get_api_provider($name);
|
|
if (!$provider) {
|
|
return array('success' => false, 'error' => 'Provider not found');
|
|
}
|
|
|
|
$api_key = $this->decrypt_api_key($provider['api_key']);
|
|
$base_url = $provider['base_url'];
|
|
|
|
// Test by listing models
|
|
$response = wp_remote_get($base_url . '/models', array(
|
|
'headers' => array(
|
|
'Authorization' => 'Bearer ' . $api_key,
|
|
'Content-Type' => 'application/json',
|
|
'User-Agent' => 'TigerStyle-SEO/' . TIGERSTYLE_HEAT_VERSION
|
|
),
|
|
'timeout' => 30
|
|
));
|
|
|
|
if (is_wp_error($response)) {
|
|
return array(
|
|
'success' => false,
|
|
'error' => $response->get_error_message()
|
|
);
|
|
}
|
|
|
|
$status_code = wp_remote_retrieve_response_code($response);
|
|
$body = wp_remote_retrieve_body($response);
|
|
|
|
if ($status_code !== 200) {
|
|
return array(
|
|
'success' => false,
|
|
'error' => 'HTTP ' . $status_code . ': ' . $body
|
|
);
|
|
}
|
|
|
|
$data = json_decode($body, true);
|
|
if (!$data || !isset($data['data'])) {
|
|
return array(
|
|
'success' => false,
|
|
'error' => 'Invalid response format'
|
|
);
|
|
}
|
|
|
|
// Update provider with test results
|
|
$providers = $this->get_api_providers();
|
|
$providers[$name]['last_tested'] = time();
|
|
$providers[$name]['test_status'] = 'success';
|
|
$providers[$name]['models'] = $this->process_models($data['data']);
|
|
update_option('tigerstyle_ai_providers', $providers);
|
|
|
|
return array(
|
|
'success' => true,
|
|
'models' => $providers[$name]['models'],
|
|
'message' => 'API key tested successfully! Found ' . count($providers[$name]['models']) . ' models.'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Process models from API response
|
|
*/
|
|
private function process_models($models_data) {
|
|
$models = array();
|
|
|
|
foreach ($models_data as $model) {
|
|
if (isset($model['id'])) {
|
|
$models[] = array(
|
|
'id' => $model['id'],
|
|
'object' => $model['object'] ?? 'model',
|
|
'created' => $model['created'] ?? time(),
|
|
'owned_by' => $model['owned_by'] ?? 'unknown',
|
|
'enabled' => true // Default to enabled
|
|
);
|
|
}
|
|
}
|
|
|
|
return $models;
|
|
}
|
|
|
|
/**
|
|
* Get OpenAI-compatible client for a provider
|
|
*/
|
|
public function get_client($provider_name, $model_id = null) {
|
|
$provider = $this->get_api_provider($provider_name);
|
|
if (!$provider) {
|
|
throw new Exception('Provider not found: ' . $provider_name);
|
|
}
|
|
|
|
if ($model_id && !$this->is_model_enabled($provider_name, $model_id)) {
|
|
throw new Exception('Model not enabled: ' . $model_id);
|
|
}
|
|
|
|
$api_key = $this->decrypt_api_key($provider['api_key']);
|
|
|
|
return new TigerStyleSEO_AI_Client($provider['base_url'], $api_key, $model_id);
|
|
}
|
|
|
|
/**
|
|
* Check if model is enabled for provider
|
|
*/
|
|
public function is_model_enabled($provider_name, $model_id) {
|
|
$provider = $this->get_api_provider($provider_name);
|
|
if (!$provider || !isset($provider['models'])) {
|
|
return false;
|
|
}
|
|
|
|
foreach ($provider['models'] as $model) {
|
|
if ($model['id'] === $model_id) {
|
|
return $model['enabled'] ?? true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Toggle model enabled/disabled status
|
|
*/
|
|
public function toggle_model($provider_name, $model_id, $enabled) {
|
|
$providers = $this->get_api_providers();
|
|
if (!isset($providers[$provider_name])) {
|
|
return false;
|
|
}
|
|
|
|
foreach ($providers[$provider_name]['models'] as &$model) {
|
|
if ($model['id'] === $model_id) {
|
|
$model['enabled'] = $enabled;
|
|
break;
|
|
}
|
|
}
|
|
|
|
update_option('tigerstyle_ai_providers', $providers);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Get enabled models for provider
|
|
*/
|
|
public function get_enabled_models($provider_name) {
|
|
$provider = $this->get_api_provider($provider_name);
|
|
if (!$provider || !isset($provider['models'])) {
|
|
return array();
|
|
}
|
|
|
|
return array_filter($provider['models'], function($model) {
|
|
return $model['enabled'] ?? true;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* AJAX handler for testing API key
|
|
*/
|
|
public function ajax_test_api_key() {
|
|
check_ajax_referer('tigerstyle_ai_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_die('Unauthorized access');
|
|
}
|
|
|
|
$provider_name = sanitize_text_field($_POST['provider_name']);
|
|
$result = $this->test_api_key($provider_name);
|
|
|
|
wp_send_json($result);
|
|
}
|
|
|
|
/**
|
|
* AJAX handler for refreshing models
|
|
*/
|
|
public function ajax_refresh_models() {
|
|
check_ajax_referer('tigerstyle_ai_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_die('Unauthorized access');
|
|
}
|
|
|
|
$provider_name = sanitize_text_field($_POST['provider_name']);
|
|
$result = $this->test_api_key($provider_name); // Refresh models by re-testing
|
|
|
|
wp_send_json($result);
|
|
}
|
|
|
|
/**
|
|
* AJAX handler for deleting API key
|
|
*/
|
|
public function ajax_delete_api_key() {
|
|
check_ajax_referer('tigerstyle_ai_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_die('Unauthorized access');
|
|
}
|
|
|
|
$provider_name = sanitize_text_field($_POST['provider_name']);
|
|
$success = $this->delete_api_provider($provider_name);
|
|
|
|
wp_send_json(array(
|
|
'success' => $success,
|
|
'message' => $success ? 'Provider deleted successfully!' : 'Failed to delete provider.'
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Handle form submission
|
|
*/
|
|
public function handle_form_submission() {
|
|
// Verify nonce
|
|
if (!wp_verify_nonce($_POST['ai_provider_nonce'], 'update_ai_provider_settings')) {
|
|
wp_die('Nonce verification failed');
|
|
}
|
|
|
|
// Check user permissions
|
|
if (!current_user_can('manage_options')) {
|
|
wp_die('Insufficient permissions');
|
|
}
|
|
|
|
$action = sanitize_text_field($_POST['ai_action'] ?? '');
|
|
|
|
if ($action === 'add_provider') {
|
|
$name = sanitize_text_field($_POST['provider_name']);
|
|
$api_key = sanitize_text_field($_POST['api_key']);
|
|
$base_url = esc_url_raw($_POST['base_url']);
|
|
$description = sanitize_textarea_field($_POST['description'] ?? '');
|
|
|
|
if (empty($name) || empty($api_key) || empty($base_url)) {
|
|
wp_redirect(add_query_arg(array(
|
|
'page' => 'tigerstyle-heat',
|
|
'tab' => 'ai-provider',
|
|
'message' => 'error'
|
|
), admin_url('admin.php')));
|
|
exit;
|
|
}
|
|
|
|
$config = array(
|
|
'base_url' => rtrim($base_url, '/'),
|
|
'api_key' => $api_key,
|
|
'description' => $description,
|
|
'provider_type' => 'openai' // Default to OpenAI compatible
|
|
);
|
|
|
|
$this->save_api_provider($name, $config);
|
|
|
|
wp_redirect(add_query_arg(array(
|
|
'page' => 'tigerstyle-heat',
|
|
'tab' => 'ai-provider',
|
|
'message' => 'provider_added'
|
|
), admin_url('admin.php')));
|
|
} elseif ($action === 'toggle_model') {
|
|
$provider_name = sanitize_text_field($_POST['provider_name']);
|
|
$model_id = sanitize_text_field($_POST['model_id']);
|
|
$enabled = isset($_POST['enabled']) ? 1 : 0;
|
|
|
|
$this->toggle_model($provider_name, $model_id, $enabled);
|
|
|
|
wp_redirect(add_query_arg(array(
|
|
'page' => 'tigerstyle-heat',
|
|
'tab' => 'ai-provider',
|
|
'message' => 'model_updated'
|
|
), admin_url('admin.php')));
|
|
}
|
|
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Handle AI chat AJAX requests
|
|
*/
|
|
public function ajax_ai_chat() {
|
|
// Verify nonce
|
|
if (!check_ajax_referer('tigerstyle_ai_nonce', 'nonce', false)) {
|
|
wp_send_json_error('Invalid nonce');
|
|
return;
|
|
}
|
|
|
|
$provider_name = sanitize_text_field($_POST['provider_name'] ?? '');
|
|
$model_id = sanitize_text_field($_POST['model_id'] ?? '');
|
|
$message = sanitize_textarea_field($_POST['message'] ?? '');
|
|
|
|
if (empty($provider_name) || empty($model_id) || empty($message)) {
|
|
wp_send_json_error('Missing required parameters');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Get AI client
|
|
$client = $this->get_client($provider_name, $model_id);
|
|
|
|
// Create SEO-focused system prompt
|
|
$system_prompt = "You are an expert SEO consultant and web optimization specialist. " .
|
|
"Provide helpful, accurate advice about search engine optimization, content strategy, " .
|
|
"meta tags, website performance, and digital marketing best practices. " .
|
|
"Keep responses concise but informative. Focus on actionable advice.";
|
|
|
|
// Send chat request
|
|
$response = $client->simple_chat($message, $system_prompt, $model_id);
|
|
$ai_response = $client->extract_text($response);
|
|
|
|
wp_send_json_success(array(
|
|
'response' => wp_kses_post($ai_response)
|
|
));
|
|
|
|
} catch (Exception $e) {
|
|
wp_send_json_error('AI Error: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render admin page
|
|
*/
|
|
public function render_admin_page() {
|
|
$providers = $this->get_api_providers();
|
|
?>
|
|
<!-- AI Chat Interface -->
|
|
<div class="seo-info-box">
|
|
<h3><?php _e('💬 AI Chat Assistant', 'tigerstyle-heat'); ?></h3>
|
|
<p class="description">
|
|
<?php _e('Ask AI questions about SEO, content optimization, or get instant help with your website.', 'tigerstyle-heat'); ?>
|
|
</p>
|
|
|
|
<div id="ai-chat-container" style="margin: 20px 0;">
|
|
<div style="display: flex; gap: 10px; margin-bottom: 15px;">
|
|
<select id="ai-chat-provider" style="min-width: 200px;">
|
|
<option value=""><?php _e('Select AI Provider...', 'tigerstyle-heat'); ?></option>
|
|
<?php if (!empty($providers)): ?>
|
|
<?php foreach ($providers as $provider_name => $provider_data): ?>
|
|
<?php if (!empty($provider_data['models'])): ?>
|
|
<?php foreach ($provider_data['models'] as $model_id => $model_data): ?>
|
|
<?php if ($model_data['enabled']): ?>
|
|
<option value="<?php echo esc_attr($provider_name . '|' . $model_id); ?>">
|
|
<?php echo esc_html($provider_name . ' - ' . $model_id); ?>
|
|
</option>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</select>
|
|
<button type="button" id="ai-chat-clear" class="button"><?php _e('Clear Chat', 'tigerstyle-heat'); ?></button>
|
|
</div>
|
|
|
|
<div id="ai-chat-messages" style="background: #f9f9f9; border: 1px solid #ddd; border-radius: 5px; padding: 15px; min-height: 200px; max-height: 400px; overflow-y: auto; margin-bottom: 15px;">
|
|
<div class="chat-message system-message" style="color: #666; font-style: italic;">
|
|
<?php _e('💡 Ask me anything about SEO, content optimization, meta tags, or website improvement!', 'tigerstyle-heat'); ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: flex; gap: 10px;">
|
|
<textarea id="ai-chat-input" placeholder="<?php _e('Ask me anything about SEO...', 'tigerstyle-heat'); ?>" style="flex: 1; min-height: 60px; padding: 10px; border: 1px solid #ddd; border-radius: 5px;" rows="3"></textarea>
|
|
<button type="button" id="ai-chat-send" class="button button-primary" disabled style="align-self: flex-end;"><?php _e('Send', 'tigerstyle-heat'); ?></button>
|
|
</div>
|
|
|
|
<div id="ai-chat-status" style="margin-top: 10px; font-size: 12px; color: #666;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="seo-info-box">
|
|
<h3><?php _e('🔧 AI Provider Configuration', 'tigerstyle-heat'); ?></h3>
|
|
<p class="description">
|
|
<?php _e('Configure OpenAI-compatible API providers to enable AI-powered SEO features like content optimization, meta tag generation, and automated analysis.', 'tigerstyle-heat'); ?>
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Add New Provider Form -->
|
|
<div class="seo-info-box">
|
|
<h4><?php _e('Add New API Provider', 'tigerstyle-heat'); ?></h4>
|
|
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>">
|
|
<input type="hidden" name="action" value="update_ai_provider_settings">
|
|
<input type="hidden" name="ai_action" value="add_provider">
|
|
<?php wp_nonce_field('update_ai_provider_settings', 'ai_provider_nonce'); ?>
|
|
|
|
<table class="form-table">
|
|
<tr>
|
|
<th scope="row"><?php _e('Provider Name', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="text" name="provider_name" class="regular-text" placeholder="e.g., openai-main, anthropic-claude" required>
|
|
<p class="description"><?php _e('Unique name to identify this API provider.', 'tigerstyle-heat'); ?></p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row"><?php _e('API Key', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="password" name="api_key" class="regular-text" placeholder="sk-..." required>
|
|
<p class="description"><?php _e('API key will be encrypted and stored securely.', 'tigerstyle-heat'); ?></p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row"><?php _e('Base URL', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="url" name="base_url" class="regular-text" value="https://api.openai.com/v1" required>
|
|
<p class="description"><?php _e('API base URL (OpenAI: https://api.openai.com/v1, Azure: https://your-resource.openai.azure.com)', 'tigerstyle-heat'); ?></p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row"><?php _e('Description', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<textarea name="description" class="large-text" rows="3" placeholder="Optional description for this provider..."></textarea>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<?php submit_button(__('Add Provider', 'tigerstyle-heat')); ?>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Existing Providers -->
|
|
<?php if (!empty($providers)): ?>
|
|
<div class="seo-info-box">
|
|
<h4><?php _e('Configured API Providers', 'tigerstyle-heat'); ?></h4>
|
|
|
|
<?php foreach ($providers as $name => $config): ?>
|
|
<div class="provider-card" style="border: 1px solid #ddd; border-radius: 5px; padding: 15px; margin-bottom: 15px;">
|
|
<div style="display: flex; justify-content: between; align-items: center; margin-bottom: 10px;">
|
|
<h5 style="margin: 0; flex-grow: 1;"><?php echo esc_html($name); ?></h5>
|
|
<div class="provider-actions">
|
|
<button type="button" class="button test-api-key" data-provider="<?php echo esc_attr($name); ?>">
|
|
<?php _e('Test API Key', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
<button type="button" class="button refresh-models" data-provider="<?php echo esc_attr($name); ?>">
|
|
<?php _e('Refresh Models', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
<button type="button" class="button button-secondary delete-provider" data-provider="<?php echo esc_attr($name); ?>">
|
|
<?php _e('Delete', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="provider-info" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; margin-bottom: 15px;">
|
|
<div><strong><?php _e('API Key:', 'tigerstyle-heat'); ?></strong><br>
|
|
<code style="background: #f1f1f1; padding: 2px 6px; border-radius: 3px; font-family: monospace; font-size: 12px;">
|
|
<?php echo esc_html($this->get_masked_api_key($name)); ?>
|
|
</code>
|
|
</div>
|
|
<div><strong><?php _e('Base URL:', 'tigerstyle-heat'); ?></strong><br><?php echo esc_html($config['base_url']); ?></div>
|
|
<div><strong><?php _e('Status:', 'tigerstyle-heat'); ?></strong><br>
|
|
<span class="status-<?php echo esc_attr($config['test_status'] ?? 'pending'); ?>">
|
|
<?php echo esc_html(ucfirst($config['test_status'] ?? 'pending')); ?>
|
|
</span>
|
|
</div>
|
|
<div><strong><?php _e('Models:', 'tigerstyle-heat'); ?></strong><br><?php echo count($config['models'] ?? array()); ?> available</div>
|
|
<div><strong><?php _e('Last Tested:', 'tigerstyle-heat'); ?></strong><br>
|
|
<?php
|
|
if ($config['last_tested']) {
|
|
echo esc_html(human_time_diff($config['last_tested']) . ' ago');
|
|
} else {
|
|
echo esc_html__('Never', 'tigerstyle-heat');
|
|
}
|
|
?>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (!empty($config['description'])): ?>
|
|
<p class="description"><?php echo esc_html($config['description']); ?></p>
|
|
<?php endif; ?>
|
|
|
|
<!-- Models List -->
|
|
<?php if (!empty($config['models'])): ?>
|
|
<div class="models-section">
|
|
<h6><?php _e('Available Models', 'tigerstyle-heat'); ?></h6>
|
|
<div class="models-grid" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 10px;">
|
|
<?php foreach ($config['models'] as $model): ?>
|
|
<div class="model-item" style="padding: 10px; background: #f9f9f9; border-radius: 3px;">
|
|
<div style="display: flex; justify-content: space-between; align-items: center;">
|
|
<div>
|
|
<strong><?php echo esc_html($model['id']); ?></strong><br>
|
|
<small><?php echo esc_html($model['owned_by']); ?></small>
|
|
</div>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox"
|
|
class="model-toggle"
|
|
data-provider="<?php echo esc_attr($name); ?>"
|
|
data-model="<?php echo esc_attr($model['id']); ?>"
|
|
<?php checked($model['enabled'] ?? true); ?>>
|
|
<span class="slider"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div id="provider-results-<?php echo esc_attr($name); ?>" class="provider-results" style="margin-top: 15px;"></div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Usage Examples -->
|
|
<div class="seo-info-box">
|
|
<h4><?php _e('Usage Examples', 'tigerstyle-heat'); ?></h4>
|
|
<p><?php _e('Once configured, you can use the AI providers in your code:', 'tigerstyle-heat'); ?></p>
|
|
<pre style="background: #f1f1f1; padding: 15px; border-radius: 5px; overflow-x: auto;"><code>// Get client for a specific provider and model
|
|
$client = tigerstyle_heat()->get_module('ai_provider')->get_client('openai-main', 'gpt-4');
|
|
|
|
// Generate meta description
|
|
$response = $client->chat_completion([
|
|
'messages' => [
|
|
['role' => 'user', 'content' => 'Generate an SEO meta description for: ' . $post_title]
|
|
],
|
|
'max_tokens' => 160
|
|
]);
|
|
|
|
// Use with any enabled model
|
|
$providers = tigerstyle_heat()->get_module('ai_provider')->get_api_providers();
|
|
foreach ($providers as $name => $config) {
|
|
$enabled_models = tigerstyle_heat()->get_module('ai_provider')->get_enabled_models($name);
|
|
// Use the models...
|
|
}</code></pre>
|
|
</div>
|
|
|
|
<!-- TigerStyle Life9 Backup Plugin Recommendation -->
|
|
<div class="seo-info-box" style="background: #fff3cd; border-left: 4px solid #ffc107;">
|
|
<h4><?php _e('🔒 Need Backup & Restore Functionality?', 'tigerstyle-heat'); ?></h4>
|
|
<p><?php _e('Backup & Restore functionality has been moved to our standalone <strong>TigerStyle Life9</strong> plugin for enhanced security and modularity.', 'tigerstyle-heat'); ?></p>
|
|
<div style="display: flex; gap: 15px; align-items: center; margin-top: 15px;">
|
|
<div style="flex: 1;">
|
|
<h5 style="margin: 0 0 10px 0;"><?php _e('✨ TigerStyle Life9 Features:', 'tigerstyle-heat'); ?></h5>
|
|
<ul style="margin: 0; padding-left: 20px;">
|
|
<li><?php _e('🔐 Military-grade encryption for backup files', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('🌐 Modern Alpine.js frontend interface', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('📦 Complete database and file backups', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('☁️ Multiple storage backends (local, cloud)', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('🔄 One-click restore functionality', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('⏰ Automated backup scheduling', 'tigerstyle-heat'); ?></li>
|
|
</ul>
|
|
</div>
|
|
<div style="text-align: center;">
|
|
<p style="margin: 0 0 10px 0; font-style: italic; color: #6c757d;"><?php _e('"Because cats have 9 lives,<br>but servers don\'t!"', 'tigerstyle-heat'); ?></p>
|
|
<?php if (is_plugin_active('tigerstyle-life9/tigerstyle-life9.php')): ?>
|
|
<span style="color: #28a745; font-weight: bold;">✅ <?php _e('TigerStyle Life9 is active!', 'tigerstyle-heat'); ?></span><br>
|
|
<a href="<?php echo admin_url('admin.php?page=tigerstyle-life9'); ?>" class="button button-primary" style="margin-top: 5px;">
|
|
<?php _e('Manage Backups', 'tigerstyle-heat'); ?>
|
|
</a>
|
|
<?php else: ?>
|
|
<span style="color: #ffc107; font-weight: bold;">📦 <?php _e('Install TigerStyle Life9', 'tigerstyle-heat'); ?></span><br>
|
|
<small style="color: #6c757d;"><?php _e('Available in the src/tigerstyle-life9 directory', 'tigerstyle-heat'); ?></small>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- TigerStyle Dash Performance Plugin Recommendation -->
|
|
<div class="seo-info-box" style="background: #e7f3ff; border-left: 4px solid #0073aa;">
|
|
<h4><?php _e('⚡ Need Lightning-Fast Performance?', 'tigerstyle-heat'); ?></h4>
|
|
<p><?php _e('Performance & Compression functionality has been moved to our dedicated <strong>TigerStyle Dash</strong> plugin for specialized speed optimization.', 'tigerstyle-heat'); ?></p>
|
|
<div style="display: flex; gap: 15px; align-items: center; margin-top: 15px;">
|
|
<div style="flex: 1;">
|
|
<h5 style="margin: 0 0 10px 0;"><?php _e('🏃♀️ TigerStyle Dash Features:', 'tigerstyle-heat'); ?></h5>
|
|
<ul style="margin: 0; padding-left: 20px;">
|
|
<li><?php _e('⚡ Advanced Brotli + Gzip compression with cat-like reflexes', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('🧠 Smart cache warming and intelligent purging', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('📊 Real-time performance analytics and optimization scoring', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('🎯 Core Web Vitals optimization for better Google rankings', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('💾 Reduce file sizes by 60-80% with lightning speed', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('🔧 WP Rocket-inspired compression with modern techniques', 'tigerstyle-heat'); ?></li>
|
|
</ul>
|
|
</div>
|
|
<div style="text-align: center;">
|
|
<p style="margin: 0 0 10px 0; font-style: italic; color: #6c757d;"><?php _e('"Dash past the competition<br>with lightning speed!"', 'tigerstyle-heat'); ?></p>
|
|
<?php if (is_plugin_active('tigerstyle-dash/tigerstyle-dash.php')): ?>
|
|
<span style="color: #28a745; font-weight: bold;">✅ <?php _e('TigerStyle Dash is active!', 'tigerstyle-heat'); ?></span><br>
|
|
<a href="<?php echo admin_url('admin.php?page=tigerstyle-dash'); ?>" class="button button-primary" style="margin-top: 5px;">
|
|
<?php _e('Optimize Performance', 'tigerstyle-heat'); ?>
|
|
</a>
|
|
<?php else: ?>
|
|
<span style="color: #0073aa; font-weight: bold;">🏃♀️ <?php _e('Install TigerStyle Dash', 'tigerstyle-heat'); ?></span><br>
|
|
<small style="color: #6c757d;"><?php _e('Available in the src/tigerstyle-dash directory', 'tigerstyle-heat'); ?></small>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- TigerStyle Scent OAuth2 Authentication Plugin Recommendation -->
|
|
<div class="seo-info-box" style="background: #fff3cd; border-left: 4px solid #ffc107;">
|
|
<h4><?php _e('👃 Need Enterprise Authentication?', 'tigerstyle-heat'); ?></h4>
|
|
<p><?php _e('OAuth2 authentication functionality is available through our dedicated <strong>TigerStyle Scent</strong> plugin for secure access control.', 'tigerstyle-heat'); ?></p>
|
|
|
|
<div style="display: flex; gap: 20px; align-items: flex-start;">
|
|
<div style="flex: 1;">
|
|
<h5 style="margin: 0 0 10px 0;"><?php _e('👃 TigerStyle Scent Features:', 'tigerstyle-heat'); ?></h5>
|
|
<ul style="margin: 0; padding-left: 20px; color: #5a5a5a;">
|
|
<li><?php _e('🛡️ Enterprise OAuth2 authorization server with cat-like security instincts', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('👃 Scent-based authentication tokens - digital pheromones for access control', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('🏰 Territory control with scope-based permissions and client management', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('⚡ Lightning-fast OAuth2 flows with feline reflexes and JWT support', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('🔒 Military-grade security with PKCE, refresh tokens, and introspection', 'tigerstyle-heat'); ?></li>
|
|
<li><?php _e('🔧 WordPress REST API integration with Bearer token authentication', 'tigerstyle-heat'); ?></li>
|
|
</ul>
|
|
</div>
|
|
<div style="text-align: center; min-width: 150px;">
|
|
<?php if (class_exists('TigerStyleScent')): ?>
|
|
<span style="color: #28a745; font-weight: bold;">✅ <?php _e('TigerStyle Scent is active!', 'tigerstyle-heat'); ?></span><br>
|
|
<a href="<?php echo admin_url('admin.php?page=tigerstyle-scent'); ?>" class="button button-primary" style="margin-top: 5px;">
|
|
<?php _e('Manage Authentication', 'tigerstyle-heat'); ?>
|
|
</a>
|
|
<?php else: ?>
|
|
<span style="color: #ffc107; font-weight: bold;">👃 <?php _e('Install TigerStyle Scent', 'tigerstyle-heat'); ?></span><br>
|
|
<small style="color: #6c757d;"><?php _e('Available in the src/WPOAuth2Server directory (needs rebranding)', 'tigerstyle-heat'); ?></small>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top: 15px; padding: 10px; background: #f8f9fa; border-radius: 5px;">
|
|
<p style="margin: 0; font-style: italic; color: #6c757d;">
|
|
<strong><?php _e('"Leave your digital scent trail', 'tigerstyle-heat'); ?></strong>
|
|
<?php _e('for secure authentication!"', 'tigerstyle-heat'); ?>
|
|
</p>
|
|
<div style="margin-top: 5px;">
|
|
<span style="color: #ffc107; font-weight: bold;">👃 <?php _e('Install TigerStyle Scent', 'tigerstyle-heat'); ?></span><br>
|
|
<small style="color: #6c757d;"><?php _e('Complete OAuth2 authentication server for WordPress', 'tigerstyle-heat'); ?></small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.status-success { color: #46b450; font-weight: bold; }
|
|
.status-pending { color: #f56e28; }
|
|
.status-error { color: #dc3232; }
|
|
.provider-card { transition: box-shadow 0.2s; }
|
|
.provider-card:hover { box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
|
|
.toggle-switch { position: relative; display: inline-block; width: 60px; height: 34px; }
|
|
.toggle-switch input { opacity: 0; width: 0; height: 0; }
|
|
.slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .4s; border-radius: 34px; }
|
|
.slider:before { position: absolute; content: ""; height: 26px; width: 26px; left: 4px; bottom: 4px; background-color: white; transition: .4s; border-radius: 50%; }
|
|
input:checked + .slider { background-color: #2196F3; }
|
|
input:checked + .slider:before { transform: translateX(26px); }
|
|
</style>
|
|
<?php
|
|
}
|
|
}
|