plugin = ai_seo_article_generator(); $this->init_hooks(); } private function init_hooks() { add_filter('ai_seo_article_generator_generated_content', array($this, 'process_citations'), 15, 2); add_action('save_post', array($this, 'save_citations_meta'), 10, 2); add_action('wp_ajax_ai_seo_validate_citation', array($this, 'ajax_validate_citation')); add_action('admin_enqueue_scripts', array($this, 'enqueue_citation_scripts')); } /** * Process citations in generated content */ public function process_citations($content, $data) { // Extract citation placeholders and replace with trackable citations $content = $this->replace_citation_placeholders($content, $data); // Add authority signals $content = $this->add_authority_signals($content, $data); // Generate suggested citations $suggested_citations = $this->generate_citation_suggestions($content, $data); // Store citations for later processing if (!empty($suggested_citations)) { $this->store_citations($content, $suggested_citations, $data); } return $content; } /** * Replace citation placeholders with structured citations */ private function replace_citation_placeholders($content, $data) { $is_hebrew = isset($data['is_hebrew']) && $data['is_hebrew']; $main_keyword = isset($data['main_keyword']) ? $data['main_keyword'] : ''; // Hebrew citation patterns $hebrew_patterns = array( '/\*\[מקור:([^\]]+)\]\*/' => '[מקור נדרש]', '/\*\[נתון:([^\]]+)\]\*/' => '[נתון נדרש]', '/\*\[מחקר:([^\]]+)\]\*/' => '[מחקר נדרש]' ); // English citation patterns $english_patterns = array( '/\*\[Source:([^\]]+)\]\*/' => '[Source needed]', '/\*\[Study:([^\]]+)\]\*/' => '[Study needed]', '/\*\[Data:([^\]]+)\]\*/' => '[Data needed]' ); $patterns = $is_hebrew ? $hebrew_patterns : $english_patterns; foreach ($patterns as $pattern => $replacement) { $content = preg_replace($pattern, $replacement, $content); } // Generate automatic citations for statistical claims $content = $this->auto_generate_citation_markers($content, $main_keyword, $is_hebrew); return $content; } /** * Automatically add citation markers for claims that need sources */ private function auto_generate_citation_markers($content, $main_keyword, $is_hebrew) { // Patterns that typically need citations if ($is_hebrew) { $patterns = array( '/(\d+%[^.]*?(?:לפי|על פי|מחקר|נתונים))/' => '$1 [מקור נדרש]', '/(מחקר (?:מראה|הוכיח|גילה)[^.]{20,80})/' => '$1 [מקור נדרש]', '/(נתונים (?:מראים|מצביעים)[^.]{20,80})/' => '$1 [מקור נדרש]' ); } else { $patterns = array( '/(\d+% of[^.]{20,80})/' => '$1 [Source needed]', '/((?:Studies|Research) shows?[^.]{20,80})/' => '$1 [Source needed]', '/(According to[^.]{20,80})/' => '$1 [Source needed]' ); } foreach ($patterns as $pattern => $replacement) { $content = preg_replace($pattern, $replacement, $content); } return $content; } /** * Add authority signals to content */ private function add_authority_signals($content, $data) { $main_keyword = isset($data['main_keyword']) ? $data['main_keyword'] : ''; $is_hebrew = isset($data['is_hebrew']) && $data['is_hebrew']; // Add structured authority signals $authority_signals = $this->generate_authority_signals($main_keyword, $is_hebrew); if (!empty($authority_signals)) { // Insert authority section near the end $sections = explode('', $content); $last_section = array_pop($sections); $authority_section = $this->build_authority_section($authority_signals, $is_hebrew); $content = implode('', $sections) . '' . $authority_section . $last_section; } return $content; } /** * Generate authority signals for the topic */ private function generate_authority_signals($main_keyword, $is_hebrew) { $signals = array(); // Determine topic category for appropriate authority sources $topic_category = $this->categorize_topic($main_keyword); $authority_sources = $this->get_authority_sources_by_category($topic_category, $is_hebrew); // Select relevant sources $selected_sources = array_slice($authority_sources, 0, 3); foreach ($selected_sources as $source) { $signals[] = array( 'type' => $source['type'], 'name' => $source['name'], 'url' => $source['url'], 'description' => $source['description'], 'relevance_score' => $this->calculate_relevance_score($source, $main_keyword) ); } return $signals; } /** * Categorize topic to suggest appropriate authority sources */ private function categorize_topic($keyword) { $categories = array( 'technology' => array('טכנולוגיה', 'מחשב', 'אינטרנט', 'software', 'tech', 'digital'), 'health' => array('בריאות', 'רפואה', 'health', 'medical', 'wellness'), 'business' => array('עסק', 'כסף', 'השקעה', 'business', 'finance', 'marketing'), 'education' => array('חינוך', 'לימודים', 'education', 'learning', 'course'), 'legal' => array('משפט', 'חוק', 'legal', 'law', 'regulation') ); foreach ($categories as $category => $terms) { foreach ($terms as $term) { if (stripos($keyword, $term) !== false) { return $category; } } } return 'general'; } /** * Get authority sources by category */ private function get_authority_sources_by_category($category, $is_hebrew) { $sources = array(); if ($is_hebrew) { switch ($category) { case 'technology': $sources = array( array('type' => 'government', 'name' => 'משרד הכלכלה והתעשייה', 'url' => 'https://www.gov.il/he/departments/ministry_of_economy_and_industry', 'description' => 'מקור רשמי לנתוני טכנולוגיה'), array('type' => 'academic', 'name' => 'הטכניון', 'url' => 'https://www.technion.ac.il/', 'description' => 'מוסד אקדמי מוביל בטכנולוגיה'), array('type' => 'industry', 'name' => 'איגוד האינטרנט הישראלי', 'url' => 'https://www.isoc.org.il/', 'description' => 'ארגון מקצועי') ); break; case 'health': $sources = array( array('type' => 'government', 'name' => 'משרד הבריאות', 'url' => 'https://www.gov.il/he/departments/ministry_of_health', 'description' => 'מקור רשמי לנתוני בריאות'), array('type' => 'medical', 'name' => 'הדסה', 'url' => 'https://www.hadassah.org.il/', 'description' => 'בית חולים מוביל'), array('type' => 'academic', 'name' => 'הפקולטה לרפואה - האוניברסיטה העברית', 'url' => 'https://medicine.huji.ac.il/', 'description' => 'מוסד אקדמי רפואי') ); break; case 'business': $sources = array( array('type' => 'government', 'name' => 'הלשכה המרכזית לסטטיסטיקה', 'url' => 'https://www.cbs.gov.il/', 'description' => 'נתונים כלכליים רשמיים'), array('type' => 'financial', 'name' => 'בנק ישראל', 'url' => 'https://www.boi.org.il/', 'description' => 'הבנק המרכזי'), array('type' => 'industry', 'name' => 'לשכת המסחר', 'url' => 'https://www.chamber.org.il/', 'description' => 'ארגון עסקי מרכזי') ); break; default: $sources = array( array('type' => 'government', 'name' => 'אתר ממשלת ישראל', 'url' => 'https://www.gov.il/', 'description' => 'מקור רשמי ממשלתי'), array('type' => 'academic', 'name' => 'האוניברסיטה העברית', 'url' => 'https://www.huji.ac.il/', 'description' => 'מוסד אקדמי מוביל'), array('type' => 'media', 'name' => 'הארץ', 'url' => 'https://www.haaretz.co.il/', 'description' => 'מקור תקשורתי אמין') ); } } else { switch ($category) { case 'technology': $sources = array( array('type' => 'industry', 'name' => 'IEEE', 'url' => 'https://www.ieee.org/', 'description' => 'Leading technology organization'), array('type' => 'academic', 'name' => 'MIT Technology Review', 'url' => 'https://www.technologyreview.com/', 'description' => 'Authoritative tech publication'), array('type' => 'research', 'name' => 'Gartner', 'url' => 'https://www.gartner.com/', 'description' => 'Technology research firm') ); break; case 'health': $sources = array( array('type' => 'government', 'name' => 'CDC', 'url' => 'https://www.cdc.gov/', 'description' => 'Centers for Disease Control'), array('type' => 'medical', 'name' => 'Mayo Clinic', 'url' => 'https://www.mayoclinic.org/', 'description' => 'Leading medical institution'), array('type' => 'academic', 'name' => 'PubMed', 'url' => 'https://pubmed.ncbi.nlm.nih.gov/', 'description' => 'Medical research database') ); break; default: $sources = array( array('type' => 'encyclopedia', 'name' => 'Wikipedia', 'url' => 'https://en.wikipedia.org/', 'description' => 'Comprehensive encyclopedia'), array('type' => 'academic', 'name' => 'Google Scholar', 'url' => 'https://scholar.google.com/', 'description' => 'Academic search engine'), array('type' => 'news', 'name' => 'Reuters', 'url' => 'https://www.reuters.com/', 'description' => 'International news agency') ); } } return $sources; } /** * Calculate relevance score for authority source */ private function calculate_relevance_score($source, $keyword) { $score = 50; // Base score // Higher score for government and academic sources if (in_array($source['type'], array('government', 'academic', 'medical'))) { $score += 30; } // Higher score if source name contains keyword terms if (stripos($source['name'], $keyword) !== false) { $score += 20; } return min(100, $score); } /** * Build authority section HTML */ private function build_authority_section($authority_signals, $is_hebrew) { if ($is_hebrew) { $section_title = '

מקורות מומלצים לקריאה נוספת

'; $intro_text = '

המידע במאמר זה מבוסס על מקורות אמינים ומוכרים:

'; } else { $section_title = '

Recommended Sources for Further Reading

'; $intro_text = '

The information in this article is based on reliable and recognized sources:

'; } $html = $section_title . $intro_text . ''; return $html; } /** * Generate citation suggestions based on content */ private function generate_citation_suggestions($content, $data) { $main_keyword = isset($data['main_keyword']) ? $data['main_keyword'] : ''; $is_hebrew = isset($data['is_hebrew']) && $data['is_hebrew']; $suggestions = array(); // Find claims that need citations $citation_needed_spans = array(); if (preg_match_all('/]*>([^<]+)<\/span>/', $content, $matches, PREG_OFFSET_CAPTURE)) { foreach ($matches[0] as $index => $match) { $citation_needed_spans[] = array( 'text' => $matches[1][$index][0], 'position' => $match[1], 'context' => $this->extract_context_around_position($content, $match[1], 100) ); } } // Generate suggestions for each citation needed foreach ($citation_needed_spans as $span) { $suggestion = $this->generate_single_citation_suggestion($span['context'], $main_keyword, $is_hebrew); if ($suggestion) { $suggestions[] = $suggestion; } } return $suggestions; } /** * Generate a single citation suggestion */ private function generate_single_citation_suggestion($context, $keyword, $is_hebrew) { // Extract the type of claim $claim_type = $this->identify_claim_type($context, $is_hebrew); // Generate appropriate citation suggestion $suggestion = array( 'type' => $claim_type, 'context' => substr($context, 0, 200), 'keyword' => $keyword, 'suggested_queries' => $this->generate_search_queries($context, $keyword, $claim_type, $is_hebrew), 'source_types' => $this->get_recommended_source_types($claim_type), 'urgency' => $this->calculate_citation_urgency($claim_type, $context) ); return $suggestion; } /** * Identify the type of claim that needs citation */ private function identify_claim_type($context, $is_hebrew) { if ($is_hebrew) { $patterns = array( 'statistic' => '/\d+%|\d+\s*אחוז|נתונים|סטטיסטיקה/', 'research' => '/מחקר|חקר|מחקרים|לימוד/', 'expert' => '/מומחה|פרופסור|דוקטור|מומחים/', 'news' => '/לפי דיווח|נמסר|הודיע|פורסם/', 'definition' => '/מגדיר|הגדרה|משמעות|פירוש/' ); } else { $patterns = array( 'statistic' => '/\d+%|percent|statistics?|data/', 'research' => '/research|study|studies|investigation/', 'expert' => '/expert|professor|doctor|specialist/', 'news' => '/reported|announced|published|according to/', 'definition' => '/defined?|definition|meaning|refers to/' ); } foreach ($patterns as $type => $pattern) { if (preg_match($pattern, $context)) { return $type; } } return 'general'; } /** * Generate search queries for finding sources */ private function generate_search_queries($context, $keyword, $claim_type, $is_hebrew) { $base_queries = array(); if ($is_hebrew) { switch ($claim_type) { case 'statistic': $base_queries = array( $keyword . ' נתונים סטטיסטיקה', $keyword . ' מחקר נתונים', $keyword . ' הלמ״ס נתונים' ); break; case 'research': $base_queries = array( $keyword . ' מחקר אקדמי', $keyword . ' מחקר מדעי', $keyword . ' עבודת מחקר' ); break; default: $base_queries = array( $keyword . ' מקור אמין', $keyword . ' מידע רשמי', $keyword . ' מומחה' ); } } else { switch ($claim_type) { case 'statistic': $base_queries = array( $keyword . ' statistics data', $keyword . ' research data', $keyword . ' official statistics' ); break; case 'research': $base_queries = array( $keyword . ' academic research', $keyword . ' scientific study', $keyword . ' peer reviewed' ); break; default: $base_queries = array( $keyword . ' reliable source', $keyword . ' official information', $keyword . ' expert opinion' ); } } return $base_queries; } /** * Get recommended source types for claim type */ private function get_recommended_source_types($claim_type) { $source_types = array( 'statistic' => array('government', 'research_institute', 'academic'), 'research' => array('academic', 'peer_reviewed', 'university'), 'expert' => array('expert_interview', 'professional_organization', 'industry_leader'), 'news' => array('news_agency', 'newspaper', 'press_release'), 'definition' => array('dictionary', 'encyclopedia', 'authoritative_source'), 'general' => array('government', 'academic', 'reputable_organization') ); return isset($source_types[$claim_type]) ? $source_types[$claim_type] : $source_types['general']; } /** * Calculate urgency of citation */ private function calculate_citation_urgency($claim_type, $context) { $urgency = 'medium'; // High urgency for statistics and medical claims if (in_array($claim_type, array('statistic', 'research'))) { $urgency = 'high'; } // Check for urgency indicators in context $high_urgency_terms = array('proven', 'הוכח', 'studies show', 'מחקרים מראים', 'data shows', 'נתונים מראים'); foreach ($high_urgency_terms as $term) { if (stripos($context, $term) !== false) { $urgency = 'high'; break; } } return $urgency; } /** * Store citations for post meta */ private function store_citations($content, $citations, $data) { // Store in transient for now - will be saved to post meta when post is saved $cache_key = 'ai_seo_citations_' . md5($content); set_transient($cache_key, array( 'citations' => $citations, 'timestamp' => time(), 'keyword' => isset($data['main_keyword']) ? $data['main_keyword'] : '' ), HOUR_IN_SECONDS); } /** * Save citations to post meta */ public function save_citations_meta($post_id, $post) { if (!get_post_meta($post_id, 'ai_seo_article_generator_generated', true)) { return; } // Look for stored citations $content = $post->post_content; $cache_key = 'ai_seo_citations_' . md5($content); $stored_citations = get_transient($cache_key); if ($stored_citations) { update_post_meta($post_id, 'ai_seo_article_generator_citations', $stored_citations['citations']); update_post_meta($post_id, 'ai_seo_article_generator_citation_timestamp', $stored_citations['timestamp']); delete_transient($cache_key); } } /** * AJAX handler for citation validation */ public function ajax_validate_citation() { check_ajax_referer('ai_seo_article_generator_nonce', 'nonce'); if (!current_user_can('edit_posts')) { wp_send_json_error(__('Insufficient permissions', 'ai-seo-article-generator')); } $url = sanitize_url($_POST['url']); $validation_result = $this->validate_citation_url($url); wp_send_json_success($validation_result); } /** * Validate citation URL */ private function validate_citation_url($url) { $validation = array( 'valid' => false, 'authority_score' => 0, 'issues' => array(), 'recommendations' => array() ); // Basic URL validation if (!filter_var($url, FILTER_VALIDATE_URL)) { $validation['issues'][] = 'Invalid URL format'; return $validation; } // Check domain authority (simplified) $domain = parse_url($url, PHP_URL_HOST); $authority_score = $this->calculate_domain_authority($domain); $validation['authority_score'] = $authority_score; if ($authority_score >= 70) { $validation['valid'] = true; } else { $validation['issues'][] = 'Low domain authority'; $validation['recommendations'][] = 'Consider using a more authoritative source'; } return $validation; } /** * Calculate domain authority score (simplified) */ private function calculate_domain_authority($domain) { // High authority domains $high_authority = array( 'gov.il', 'edu', 'org', 'cbs.gov.il', 'boi.org.il', 'who.int', 'cdc.gov', 'nih.gov', 'ieee.org', 'nature.com', 'science.org' ); // Medium authority domains $medium_authority = array( 'wikipedia.org', 'britannica.com', 'reuters.com', 'bbc.com', 'haaretz.co.il', 'ynet.co.il', 'nytimes.com' ); foreach ($high_authority as $auth_domain) { if (strpos($domain, $auth_domain) !== false) { return 90; } } foreach ($medium_authority as $auth_domain) { if (strpos($domain, $auth_domain) !== false) { return 70; } } return 40; // Default score for unknown domains } /** * Enqueue citation management scripts */ public function enqueue_citation_scripts($hook) { if (strpos($hook, 'ai-seo-article-generator') === false) { return; } wp_enqueue_script( 'ai-seo-citation-manager', AI_SEO_ARTICLE_GENERATOR_PLUGIN_URL . 'assets/js/citation-manager.js', array('jquery'), AI_SEO_ARTICLE_GENERATOR_VERSION, true ); wp_localize_script('ai-seo-citation-manager', 'aiSeoCitations', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('ai_seo_article_generator_nonce'), 'i18n' => array( 'validating' => __('Validating citation...', 'ai-seo-article-generator'), 'valid_source' => __('Valid source', 'ai-seo-article-generator'), 'invalid_source' => __('Invalid source', 'ai-seo-article-generator'), 'add_citation' => __('Add Citation', 'ai-seo-article-generator'), 'remove_citation' => __('Remove Citation', 'ai-seo-article-generator') ) )); } // Helper methods private function extract_context_around_position($content, $position, $length) { $start = max(0, $position - $length / 2); $context = substr($content, $start, $length); // Clean HTML tags from context return wp_strip_all_tags($context); } }