3000) $score += 20; elseif ($length > 1500) $score += 15; elseif ($length > 800) $score += 10; elseif ($length > 400) $score += 5; $paragraphs = explode("\n", $content_clean); $paragraph_count = count(array_filter($paragraphs, function($p) { return trim($p) !== ''; })); if ($paragraph_count > 5) $score += 15; elseif ($paragraph_count > 3) $score += 10; elseif ($paragraph_count > 1) $score += 5; $sentences = preg_split('/[.!?]+/', $content_clean); $sentence_count = count(array_filter($sentences)); $avg_sentence_length = $sentence_count > 0 ? $length / $sentence_count : 0; if ($avg_sentence_length > 80 && $avg_sentence_length < 200) $score += 15; elseif ($avg_sentence_length > 50) $score += 10; elseif ($avg_sentence_length > 20) $score += 5; $valuable_keywords = [ 'analysis', 'research', 'study', 'report', 'data', 'statistics', 'findings', 'technology', 'innovation', 'development', 'solution', 'method', 'approach', 'strategy', 'insights', 'trends', 'market', 'industry', 'expert', 'professional', 'detailed', 'comprehensive', 'advanced', 'specialized', 'technical', 'scientific' ]; $keyword_matches = 0; foreach ($valuable_keywords as $keyword) { if (stripos($content_clean, $keyword) !== false) { $keyword_matches++; } } $score += min(20, $keyword_matches * 2); $spam_indicators = [ 'buy now', 'click here', 'limited time', 'special offer', 'discount', 'sale', 'free shipping', 'call now', 'order today', 'best price', 'guaranteed', 'amazing deal', 'don\'t miss', 'act fast', 'exclusive', 'bonus' ]; $spam_count = 0; foreach ($spam_indicators as $spam) { if (stripos($content_clean, $spam) !== false) { $spam_count++; } } if ($spam_count > 3) $score -= 30; elseif ($spam_count > 1) $score -= 15; $tech_patterns = [ '/\b\d+%\b/', '/\$\d+/', '/\b(API|SQL|HTTP|JSON|XML|CSS|HTML|PHP|JS)\b/i', '/\b\d{4}\b/', '/\b\d+(\.\d+)?\s*(million|billion|thousand)\b/i' ]; $tech_score = 0; foreach ($tech_patterns as $pattern) { if (preg_match($pattern, $content_clean)) { $tech_score += 2; } } $score += min(10, $tech_score); if (!empty($title)) { $title_length = mb_strlen($title); if ($title_length > 30 && $title_length < 80) $score += 5; if (preg_match('/[?:]/', $title)) $score += 3; if (!preg_match('/\b(top|best|amazing|incredible)\b/i', $title)) $score += 2; } $common_phrases = ['lorem ipsum', 'copy and paste', 'placeholder text']; $originality_penalty = 0; foreach ($common_phrases as $phrase) { if (stripos($content_clean, $phrase) !== false) { $originality_penalty += 5; } } $score -= $originality_penalty; return max(0, min(100, $score)); } /** * OPTIMIZATION: Check content similarity against recent posts */ function airsrefe_check_content_similarity($content, $days = 7) { $cache_key = 'airsrefe_similarity_' . md5($content); $cached = wp_cache_get($cache_key, 'airsrefe_plugin'); if ($cached !== false) { airsrefe_track_cache_hit(); return $cached; } airsrefe_track_cache_miss(); // Use a more efficient approach with PHP filtering $recent_posts = get_posts([ 'post_type' => 'post', 'posts_per_page' => 100, // Get more posts to filter 'fields' => 'ids', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'cache_results' => false ]); // Filter posts by processed date in PHP (more efficient) $filtered_posts = []; $cutoff_date = gmdate('Y-m-d H:i:s', strtotime("-{$days} days")); foreach ($recent_posts as $post_id) { $processed_date = get_post_meta($post_id, '_airsrefe_processed_date', true); if (!empty($processed_date) && $processed_date >= $cutoff_date) { $filtered_posts[] = $post_id; } } $content_hash = md5(wp_strip_all_tags($content)); $similar_found = false; foreach ($filtered_posts as $post_id) { $existing_hash = get_post_meta($post_id, '_airsrefe_content_hash', true); if ($existing_hash && $existing_hash === $content_hash) { $similar_found = true; break; } $existing_content = get_post_field('post_content', $post_id); if ($existing_content) { $existing_clean = wp_strip_all_tags($existing_content); $similarity = similar_text($content, $existing_clean, $percent); if ($percent > 80) { $similar_found = true; break; } } } wp_cache_set($cache_key, $similar_found, 'airsrefe_plugin', 3600); return $similar_found; } /** * OPTIMIZATION: Enhanced content filtering before AI processing */ function airsrefe_should_process_with_ai_enhanced($title, $content) { $quality_score = airsrefe_analyze_content_quality($content, $title); if ($quality_score < 30) { airsrefe_append_log("Content quality too low: {$quality_score}/100 - skipping AI processing"); return false; } if (airsrefe_check_content_similarity($content)) { airsrefe_append_log("Similar content found recently - skipping to avoid duplicates"); return false; } $content_length = mb_strlen(wp_strip_all_tags($content)); if ($content_length < 150) { airsrefe_append_log("Content too short ({$content_length} chars) - skipping AI processing"); return false; } return true; } function airsrefe_log_processing_result($original_title, $unique_title, $model, $success) { $logs = get_option('airsrefe_logs', []); $logs[] = [ 'date' => current_time('mysql'), 'original' => mb_substr($original_title, 0, 100), 'unique' => mb_substr($unique_title, 0, 100), 'model' => $model, 'success' => $success ]; if (count($logs) > 50) { $logs = array_slice($logs, -50); } update_option('airsrefe_logs', $logs); airsrefe_append_log(($success ? 'SUCCESS' : 'FAILED') . ' - ' . $original_title); } function airsrefe_generate_ai_post_enhanced($title, $content, $task_type = 'content', $priority = null) { $original_title = $title; $unique_title = $title; $unique_content = $content; $success = false; if (!$priority) { $priority = airsrefe_get_processing_priority(); } if (get_option('airsrefe_block_parsing') == 1) { airsrefe_append_log('Parsing blocked due to insufficient quota or budget limit'); airsrefe_log_processing_result($original_title, $unique_title, 'blocked', false); return ['title' => $title, 'content' => $content . "\n\n"]; } if (!airsrefe_should_process_with_ai_enhanced($title, $content)) { airsrefe_append_log('Content filtered out - not suitable for AI processing'); return ['title' => $title, 'content' => $content]; } $model = airsrefe_smart_model_selection($content, $task_type, $title); $budget_mode = airsrefe_get_budget_mode(); if ($model === false) { airsrefe_append_log('Content quality too low - skipping AI processing entirely'); return ['title' => $title, 'content' => $content]; } $predicted_cost = airsrefe_predict_request_cost($content, $title, $task_type, $model); if (!airsrefe_check_budget_with_prediction($predicted_cost)) { airsrefe_append_log('Request blocked due to budget prediction - downgrading or skipping'); if ($model === 'gpt-5') { $model = 'gpt-5-mini'; $predicted_cost = airsrefe_predict_request_cost($content, $title, $task_type, $model); if (!airsrefe_check_budget_with_prediction($predicted_cost)) { return ['title' => $title, 'content' => $content . "\n\n"]; } } elseif ($model === 'gpt-5-mini') { $model = 'gpt-5-nano'; $predicted_cost = airsrefe_predict_request_cost($content, $title, $task_type, $model); if (!airsrefe_check_budget_with_prediction($predicted_cost)) { return ['title' => $title, 'content' => $content . "\n\n"]; } } else { return ['title' => $title, 'content' => $content . "\n\n"]; } } airsrefe_check_budget_alerts(); airsrefe_append_log("Smart model selection: {$model} for {$task_type} (budget mode: {$budget_mode}, predicted cost: $" . number_format($predicted_cost, 4) . ")"); try { if (!airsrefe_check_circuit_breaker('openai')) { airsrefe_append_log('OpenAI API blocked by circuit breaker - using fallback processing'); return airsrefe_fallback_processing($title, $content, 'circuit_breaker_open'); } $api_key = airsrefe_get_api_key(); if (empty($api_key)) { airsrefe_append_log('OpenAI API Key not found or invalid'); airsrefe_log_processing_result($original_title, $unique_title, $model, false); return ['title' => $title, 'content' => $content . "\n\n"]; } // Log API key status (masked for security) $masked_key = substr($api_key, 0, 8) . str_repeat('*', max(0, strlen($api_key) - 16)) . substr($api_key, -8); airsrefe_append_log('Main function using API key: ' . $masked_key); $prompt = airsrefe_get_structure_preserving_prompt($task_type, $title, $content, $priority, $model); $content_hash = md5($title . '|' . $content . '|' . $task_type); $cached_result = airsrefe_get_cached_ai_result($content_hash, $task_type, $model); if ($cached_result !== false) { airsrefe_append_log("AI result loaded from cache - skipping API request"); return $cached_result; } $system_message = airsrefe_get_system_message($task_type); $total_input_tokens = airsrefe_estimate_total_tokens($prompt, $system_message, $model); $estimated_output_tokens = airsrefe_estimate_output_tokens($task_type, strlen($content)); $estimated_cost = airsrefe_calculate_request_cost($model, $total_input_tokens, $estimated_output_tokens); airsrefe_track_ai_request(); if (!airsrefe_check_budget_before_request($estimated_cost)) { airsrefe_append_log("Request cancelled - would exceed budget (estimated: $" . number_format($estimated_cost, 4) . ")"); return ['title' => $title, 'content' => $content . "\n\n"]; } $use_json = get_option('airsrefe_enable_json_responses', 1) && $task_type === 'content'; $response = airsrefe_make_api_request_with_retry($model, $prompt, $use_json); if ($response && isset($response['choices'][0]['message']['content'])) { airsrefe_record_circuit_success('openai'); $ai_text = $response['choices'][0]['message']['content']; $parsed_result = $use_json ? airsrefe_parse_json_response($ai_text, $title, $content) : airsrefe_parse_text_response($ai_text, $title, $content); $unique_title = $parsed_result['title']; $unique_content = $parsed_result['content']; $unique_content = airsrefe_restore_html_structure($content, $unique_content, $model); $actual_input_tokens = $response['usage']['prompt_tokens'] ?? $input_tokens; $actual_output_tokens = $response['usage']['completion_tokens'] ?? $estimated_output_tokens; $actual_cost = airsrefe_calculate_request_cost($model, $actual_input_tokens, $actual_output_tokens); airsrefe_record_cost($actual_cost, $model, $task_type); $original_clean = strtolower(trim(preg_replace('/\s+/', ' ', wp_strip_all_tags($original_title)))); $unique_clean = strtolower(trim(preg_replace('/\s+/', ' ', wp_strip_all_tags($unique_title)))); $content_changed = strlen($unique_content) > strlen($content) * 0.8 && strlen($unique_content) < strlen($content) * 1.5; similar_text($original_clean, $unique_clean, $percent); if ($percent < 90 || $content_changed) { $success = true; airsrefe_append_log(sprintf("AI processed successfully (title similarity: %s%%, content changed: %s, cost: $%s)", number_format($percent, 1), $content_changed ? 'yes' : 'no', number_format($actual_cost, 6))); } else { if (strlen($unique_content) > strlen($content) + 100) { $success = true; airsrefe_append_log(sprintf("AI processed successfully (content expanded significantly, cost: $%s)", number_format($actual_cost, 6))); } else { airsrefe_append_log(sprintf("AI result rejected - too similar (title: %s%%, content change: %s)", number_format($percent, 1), $content_changed ? 'acceptable' : 'minimal')); } } } else { airsrefe_append_log('No valid AI response received'); } } catch (Exception $e) { airsrefe_append_log('AI processing error: ' . $e->getMessage()); } airsrefe_log_processing_result($original_title, $unique_title, $model, $success); $result = [ 'title' => $unique_title, 'content' => $unique_content ]; if ($success) { airsrefe_cache_ai_result($content_hash, $task_type, $model, $result, $estimated_cost); } return $result; } function airsrefe_restore_html_structure($original_content, $rewritten_content, $model) { if (strpos($model, 'gpt-5') === 0) { $original_has_html = airsrefe_detect_html_structure($original_content); $rewritten_has_html = airsrefe_detect_html_structure($rewritten_content); if ($original_has_html && !$rewritten_has_html) { airsrefe_append_log("HTML structure lost, attempting to restore..."); $restored_content = airsrefe_apply_html_structure($original_content, $rewritten_content); if (strlen($restored_content) > strlen($rewritten_content) * 0.8) { airsrefe_append_log("HTML structure restored successfully"); return $restored_content; } } } return $rewritten_content; } function airsrefe_apply_html_structure($original_html, $plain_text) { $sentences = preg_split('/(?<=[.!?])\s+/', trim($plain_text), -1, PREG_SPLIT_NO_EMPTY); if (empty($sentences)) { return $plain_text; } $structure_elements = []; $dom = new DOMDocument(); // Safe libxml error handling $old_setting = libxml_use_internal_errors(true); libxml_clear_errors(); $load_result = $dom->loadHTML('' . $original_html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // Clear any errors and restore previous setting libxml_clear_errors(); libxml_use_internal_errors($old_setting); if (!$load_result) return $original_html; $xpath = new DOMXPath($dom); $text_nodes = $xpath->query('//text()[normalize-space()]'); foreach ($text_nodes as $node) { $parent_tag = $node->parentNode->nodeName; $text_content = trim($node->textContent); if (strlen($text_content) > 10) { $structure_elements[] = [ 'tag' => $parent_tag, 'length' => strlen($text_content) ]; } } $structured_content = ''; $sentence_index = 0; foreach ($structure_elements as $element) { if ($sentence_index >= count($sentences)) break; $sentences_needed = max(1, round($element['length'] / 100)); $content_part = ''; for ($i = 0; $i < $sentences_needed && $sentence_index < count($sentences); $i++) { $content_part .= $sentences[$sentence_index] . ' '; $sentence_index++; } $content_part = trim($content_part); if (!empty($content_part)) { switch ($element['tag']) { case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': $structured_content .= "<{$element['tag']}>{$content_part}\n\n"; break; case 'li': if (strpos($structured_content, '