scoring = new AEO_Bob_Scoring(); } else { // Fallback behavior if class cannot be loaded $this->scoring = null; } } /** * Analyze content and return AEO score with breakdown * * @param string $content Raw post content (HTML) * @param array $meta Meta data (title, description, etc.) * @return array Score analysis with breakdown and issues */ public function analyze($content, $meta = []) { // Validate input to prevent silent 0 scores $stripped_content = trim(wp_strip_all_tags($content)); if (empty($stripped_content)) { return array( 'score' => 0, 'breakdown' => array(), 'issues' => array('Content is empty or contains no meaningful text') ); } // Check minimum content length if (mb_strlen($stripped_content) < 80) { return array( 'score' => 0, 'breakdown' => array(), 'issues' => array('Content is too short for meaningful analysis (minimum 80 characters)') ); } if ($this->scoring === null) { return array( 'score' => 0, 'breakdown' => array(), 'issues' => array('AEO_Bob_Scoring class not available') ); } $result = $this->scoring->analyze($content, $meta); // Ensure we never return a silent 0 score if (!isset($result['score']) || $result['score'] === 0) { $result['score'] = 0; if (!isset($result['issues']) || empty($result['issues'])) { $result['issues'] = array('Unable to analyze content - check content format and try again'); } } return $result; } /** * Get score category based on total score * * @param int $score Total AEO score * @return string Category label */ public function get_score_category($score) { if ($score >= 80) { return 'Optimal'; } elseif ($score >= 60) { return 'Good'; } else { return 'Needs Improvement'; } } /** * Get score color for UI display * * @param int $score Total AEO score * @return string Hex color code */ public function get_score_color($score) { if ($score >= 80) { return '#28a745'; // Green } elseif ($score >= 60) { return '#ffc107'; // Yellow } else { return '#dc3545'; // Red } } /** * Get priority issues that need immediate attention * * @param array $issues Array of issue tags * @return array Priority issues */ public function get_priority_issues($issues) { $priority_issues = [ 'no_faq' => 'Add FAQ section with 2-5 Q&A pairs', 'weak_lead' => 'Strengthen opening with direct answer', 'poor_structure' => 'Add H1 heading and improve structure', 'readability_issues' => 'Adjust content complexity', 'long_paras' => 'Break up long paragraphs', 'no_tldr' => 'Add summary or TL;DR section', 'monotonous_sentences' => 'Vary sentence lengths', 'keyword_gaps' => 'Improve keyword coverage', 'meta_issues' => 'Optimize title and meta description' ]; $priorities = []; foreach ($issues as $issue) { if (isset($priority_issues[$issue])) { $priorities[] = [ 'tag' => $issue, 'description' => $priority_issues[$issue] ]; } } return $priorities; } /** * Generate improvement suggestions based on analysis * * @param array $analysis Full analysis result * @return array Improvement suggestions */ public function get_improvement_suggestions($analysis) { $suggestions = []; $breakdown = $analysis['breakdown'] ?? []; foreach ($breakdown as $factor) { $key = $factor['key']; $points = $factor['points']; $max = $factor['max']; $notes = $factor['notes'] ?? []; // Generate suggestions for low-scoring factors if ($points < $max * 0.7) { $suggestions[] = $this->get_factor_suggestion($key, $points, $max, $notes); } } return $suggestions; } /** * Get specific suggestion for a factor * * @param string $key Factor key * @param int $points Current points * @param int $max Maximum points * @param array $notes Factor notes * @return array Suggestion */ private function get_factor_suggestion($key, $points, $max, $notes) { $suggestions_map = [ 'direct_answer' => [ 'title' => 'Improve Direct Answer', 'description' => 'Add a clear, direct answer in the first 120 words that addresses the main question or topic.', 'actions' => [ 'Start with a direct statement answering the main question', 'Include question words (what, how, why, when, where)', 'Use definitional language (is, means, refers to)', 'Promise value or benefits early' ] ], 'headings_structure' => [ 'title' => 'Improve Content Structure', 'description' => 'Add proper headings and structure to make content more scannable.', 'actions' => [ 'Add an H1 heading that summarizes the main topic', 'Include 3+ H2 or H3 subheadings', 'Use bullet points or numbered lists', 'Break content into logical sections' ] ], 'snippetability' => [ 'title' => 'Add Summary Section', 'description' => 'Make content more snippetable with clear summaries.', 'actions' => [ 'Add a TL;DR or summary section', 'Use short, punchy opening sentences (5-20 words)', 'Include key takeaways or bottom line', 'Make the main point clear upfront' ] ], 'faq_presence' => [ 'title' => 'Add FAQ Content', 'description' => 'Include frequently asked questions to address user queries.', 'actions' => [ 'Add 2-5 Q&A pairs as headings or sections', 'Use question words in headings', 'Address common user concerns', 'Make questions specific and actionable' ] ], 'readability' => [ 'title' => 'Improve Readability', 'description' => 'Adjust content complexity for optimal readability.', 'actions' => [ 'Aim for Flesch-Kincaid Grade Level 7-10', 'Use shorter sentences for complex topics', 'Simplify technical jargon', 'Break up dense paragraphs' ] ], 'paragraph_length' => [ 'title' => 'Optimize Paragraph Length', 'description' => 'Adjust paragraph length for better readability.', 'actions' => [ 'Keep paragraphs between 60-140 words', 'Break up paragraphs longer than 180 words', 'Use single-sentence paragraphs for emphasis', 'Group related ideas together' ] ], 'sentence_variance' => [ 'title' => 'Vary Sentence Length', 'description' => 'Mix short, medium, and long sentences for better flow.', 'actions' => [ 'Include some short sentences (≤10 words)', 'Use medium sentences (11-20 words)', 'Add longer sentences for detail (21+ words)', 'Vary sentence structure and rhythm' ] ], 'entity_coverage' => [ 'title' => 'Improve Keyword Coverage', 'description' => 'Better integrate target keywords and entities.', 'actions' => [ 'Include keywords from title in content', 'Use related terms and synonyms', 'Avoid keyword stuffing', 'Naturally integrate target terms' ] ], 'meta_hints' => [ 'title' => 'Optimize Meta Information', 'description' => 'Improve title and meta description for better visibility.', 'actions' => [ 'Keep title between 35-65 characters', 'Write meta description 120-160 characters', 'Include target keywords in title', 'Make meta description compelling' ] ] ]; $suggestion = $suggestions_map[$key] ?? [ 'title' => 'Improve ' . ucwords(str_replace('_', ' ', $key)), 'description' => 'This factor needs improvement based on the analysis.', 'actions' => ['Review the analysis notes for specific guidance'] ]; $suggestion['current_score'] = $points; $suggestion['max_score'] = $max; $suggestion['notes'] = $notes; return $suggestion; } }