init_hooks(); } private function init_hooks() { // Override word counting functions add_filter('ai_seo_article_generator_word_count', array($this, 'accurate_hebrew_word_count'), 10, 1); // Fix content before validation add_filter('ai_seo_article_generator_generated_content', array($this, 'fix_malformed_content'), 2, 2); } /** * Accurate Hebrew word counting */ public function accurate_hebrew_word_count($content) { // Remove HTML tags first $text = wp_strip_all_tags($content); // Remove extra whitespace $text = preg_replace('/\s+/', ' ', trim($text)); // Hebrew word pattern: Hebrew letters, numbers, and common punctuation $hebrew_words = preg_match_all('/[א-ת\d]+/u', $text); // English word pattern $english_words = preg_match_all('/[a-zA-Z]+/', $text); // Mixed words (Hebrew + English) $mixed_words = preg_match_all('/[א-תa-zA-Z\d]+/u', $text); // Use the highest count as it's more accurate for mixed content $total_words = max($hebrew_words, $english_words, $mixed_words); // Fallback to PHP's str_word_count if our count seems too low $php_count = str_word_count($text); // Use the higher count (more conservative approach) $final_count = max($total_words, $php_count); $this->debug_log("Word Count Analysis: Hebrew={$hebrew_words}, English={$english_words}, Mixed={$mixed_words}, PHP={$php_count}, Final={$final_count}"); return $final_count; } /** * Fix malformed content that ends abruptly */ public function fix_malformed_content($content, $data) { // Check if content ends abruptly (malformed HTML) if ($this->is_content_malformed($content)) { $this->debug_log("⚠️ Malformed content detected, attempting repair"); $content = $this->repair_malformed_content($content, $data); } return $content; } /** * Check if content is malformed */ private function is_content_malformed($content) { $content = trim($content); // Check for common malformation patterns $malformation_patterns = array( // Incomplete HTML tags '/<[^>]*$/', // Orphaned closing tags '/\s*<\/[^>]*>\s*$/', // Incomplete attributes '/="\s*$/', // Mid-word truncation '/[א-תa-zA-Z]\s*$/', // Incomplete HTML entities '/&[a-zA-Z]*;?\s*$/' ); foreach ($malformation_patterns as $pattern) { if (preg_match($pattern, $content)) { $this->debug_log("Malformation detected with pattern: {$pattern}"); return true; } } // Check for unbalanced HTML tags if ($this->has_unbalanced_tags($content)) { $this->debug_log("Unbalanced HTML tags detected"); return true; } return false; } /** * Check for unbalanced HTML tags */ private function has_unbalanced_tags($content) { $tags = array('h2', 'h3', 'h4', 'p', 'ul', 'ol', 'li', 'strong', 'em'); foreach ($tags as $tag) { $opening = preg_match_all("/<{$tag}[^>]*>/i", $content); $closing = preg_match_all("/<\/{$tag}>/i", $content); if ($opening !== $closing) { $this->debug_log("Unbalanced {$tag} tags: {$opening} opening, {$closing} closing"); return true; } } return false; } /** * Repair malformed content */ private function repair_malformed_content($content, $data) { $is_hebrew = isset($data['is_hebrew']) && $data['is_hebrew']; // Remove incomplete HTML at the end $content = $this->remove_incomplete_html($content); // Close any unclosed tags $content = $this->close_unclosed_tags($content); // Add proper ending if missing $content = $this->add_proper_ending($content, $is_hebrew); $this->debug_log("Content repaired, new length: " . strlen($content)); return $content; } /** * Remove incomplete HTML from the end */ private function remove_incomplete_html($content) { // Remove incomplete tags at the end $content = preg_replace('/<[^>]*$/', '', $content); // Remove incomplete attributes $content = preg_replace('/\s+[a-zA-Z-]+=\s*"?[^"]*$/', '', $content); // Remove trailing broken HTML entities $content = preg_replace('/&[a-zA-Z]*;?\s*$/', '', $content); // Remove orphaned closing tags at the end $content = preg_replace('/\s*<\/[^>]*>\s*$/', '', $content); return trim($content); } /** * Close unclosed HTML tags */ private function close_unclosed_tags($content) { $tags_to_close = array('h2', 'h3', 'h4', 'p', 'ul', 'ol', 'li', 'strong', 'em'); $unclosed_tags = array(); foreach ($tags_to_close as $tag) { $opening = preg_match_all("/<{$tag}[^>]*>/i", $content); $closing = preg_match_all("/<\/{$tag}>/i", $content); $difference = $opening - $closing; if ($difference > 0) { // Add missing closing tags for ($i = 0; $i < $difference; $i++) { $unclosed_tags[] = $tag; } } } // Close tags in reverse order (last opened, first closed) $unclosed_tags = array_reverse($unclosed_tags); foreach ($unclosed_tags as $tag) { $content .= "{$tag}>"; $this->debug_log("Added missing closing tag: {$tag}>"); } return $content; } /** * Add proper ending to content */ private function add_proper_ending($content, $is_hebrew) { // Check if content ends properly if (!preg_match('/[.!?]\s*(<\/[^>]+>)*\s*$/', $content)) { if ($is_hebrew) { $content .= "\n\n
במדריך זה סקרנו את כל הנושאים החשובים והרלוונטיים. חשוב לזכור שהתחום מתפתח מהר ויש להישאר מעודכנים עם החידושים האחרונים.
\n"; $content .= "ההמלצה היא להתחיל בשלבים קטנים, לבדוק את התוצאות ולהרחיב בהדרגה. בצורה זו ניתן להבטיח הטמעה מוצלחת ותוצאות מיטביות.
"; } else { $content .= "\n\nIn this guide, we covered all the important and relevant topics. It's important to remember that the field develops rapidly and staying updated with the latest innovations is crucial.
\n"; $content .= "The recommendation is to start with small steps, test the results, and expand gradually. This way, successful implementation and optimal results can be ensured.
"; } $this->debug_log("Added proper ending to content"); } return $content; } /** * Debug logging */ private function debug_log($message) { if (get_option('ai_seo_article_generator_debug_logging', 0)) { if (function_exists('error_log')) { error_log('AI SEO Hebrew Fixer: ' . $message); } } } } // Replace the word counting function in the API class if (!function_exists('ai_seo_accurate_word_count')) { function ai_seo_accurate_word_count($content) { // Remove HTML tags first $text = wp_strip_all_tags($content); // Remove extra whitespace $text = preg_replace('/\s+/', ' ', trim($text)); // Count Hebrew words (including mixed Hebrew-English) $hebrew_pattern = '/[\p{Hebrew}\p{N}]+/u'; $hebrew_count = preg_match_all($hebrew_pattern, $text); // Count English words $english_pattern = '/[a-zA-Z]+/'; $english_count = preg_match_all($english_pattern, $text); // Use simple space-based counting as fallback $space_count = count(array_filter(explode(' ', $text))); // Return the highest count (most conservative) $final_count = max($hebrew_count, $english_count, $space_count); return $final_count; } }