string, 'sections' => array] */ function igny8_parse_content_sections($content) { if (empty($content)) { return ['intro' => '', 'sections' => []]; } // Use DOMDocument to parse HTML $dom = new DOMDocument('1.0', 'UTF-8'); libxml_use_internal_errors(true); // Wrap content in a div to ensure proper parsing $wrapped_content = '
' . $content . '
'; $dom->loadHTML('' . $wrapped_content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); libxml_clear_errors(); $intro_html = ''; $sections = []; $current_section = null; // Get the wrapper div $xpath = new DOMXPath($dom); $nodes = $xpath->query('//div/*'); if ($nodes->length === 0) { return ['intro' => $content, 'sections' => []]; } // Iterate through all child nodes foreach ($nodes as $node) { // Check if node is an H2 heading if ($node->nodeName === 'h2') { // Save previous section if exists if ($current_section !== null) { $sections[] = $current_section; } // Start new section $current_section = [ 'heading' => trim($node->textContent), 'content' => '', 'id' => sanitize_title($node->textContent) ]; } elseif ($current_section !== null) { // Add to current section $current_section['content'] .= $dom->saveHTML($node); } else { // Add to intro (before first H2) $intro_html .= $dom->saveHTML($node); } } // Save last section if ($current_section !== null) { $sections[] = $current_section; } return [ 'intro' => trim($intro_html), 'sections' => $sections ]; } /** * Get in-article images from imported images meta * * @param int $post_id Post ID * @return array Indexed array of image data by position */ function igny8_get_in_article_images($post_id) { $imported_images = get_post_meta($post_id, '_igny8_imported_images', true); if (empty($imported_images) || !is_array($imported_images)) { return []; } $in_article_images = []; foreach ($imported_images as $img) { // Skip featured images if (isset($img['is_featured']) && $img['is_featured']) { continue; } $position = isset($img['position']) ? (int)$img['position'] : count($in_article_images) + 1; $in_article_images[$position] = $img; } return $in_article_images; } /** * Get featured image prompt from imported images meta * * @param int $post_id Post ID * @return string|null Image prompt or null */ function igny8_get_featured_image_prompt($post_id) { $imported_images = get_post_meta($post_id, '_igny8_imported_images', true); if (empty($imported_images) || !is_array($imported_images)) { return null; } foreach ($imported_images as $img) { if (isset($img['is_featured']) && $img['is_featured'] && isset($img['prompt'])) { return $img['prompt']; } } return null; } /** * Format status label for display * * @param string $status Post status * @return string Formatted label */ function igny8_format_status_label($status) { $labels = [ 'draft' => 'Draft', 'pending' => 'Pending Review', 'publish' => 'Published', 'private' => 'Private', 'future' => 'Scheduled', 'trash' => 'Trash' ]; return isset($labels[$status]) ? $labels[$status] : ucfirst($status); } /** * Get status CSS class * * @param string $status Post status * @return string CSS class */ function igny8_get_status_class($status) { $classes = [ 'draft' => 'igny8-status-draft', 'pending' => 'igny8-status-pending', 'publish' => 'igny8-status-publish', 'private' => 'igny8-status-private', 'future' => 'igny8-status-future' ]; return isset($classes[$status]) ? $classes[$status] : 'igny8-status-default'; } /** * Calculate word count from content * * @param string $content HTML content * @return int Word count */ function igny8_calculate_word_count($content) { if (empty($content)) { return 0; } // Strip HTML tags and count words $text = wp_strip_all_tags($content); return str_word_count($text); } /** * Parse secondary keywords from meta * * @param string $keywords Comma-separated keywords * @return array Array of keywords */ function igny8_parse_keywords($keywords) { if (empty($keywords)) { return []; } // Split by comma and trim each keyword $keywords_array = array_map('trim', explode(',', $keywords)); // Remove empty values return array_filter($keywords_array); } /** * Get section badges based on keyword/tag matching * * @param string $heading Section heading text * @param int $post_id Post ID * @return array Array of badges with 'text' and 'type' keys */ function igny8_get_section_badges($heading, $post_id) { $badges = []; $heading_lower = strtolower($heading); // Get post taxonomies and keywords $tags = get_the_tags($post_id); $categories = get_the_category($post_id); $primary_kw = get_post_meta($post_id, '_igny8_primary_keyword', true); $secondary_kws = get_post_meta($post_id, '_igny8_secondary_keywords', true); // Priority 1: Primary keyword if ($primary_kw && stripos($heading_lower, strtolower($primary_kw)) !== false) { $badges[] = ['text' => $primary_kw, 'type' => 'primary']; } // Priority 2: Tags if ($tags && !is_wp_error($tags) && count($badges) < 2) { foreach ($tags as $tag) { if (stripos($heading_lower, strtolower($tag->name)) !== false) { $badges[] = ['text' => $tag->name, 'type' => 'tag']; if (count($badges) >= 2) break; } } } // Priority 3: Categories if ($categories && !is_wp_error($categories) && count($badges) < 2) { foreach ($categories as $cat) { if (stripos($heading_lower, strtolower($cat->name)) !== false) { $badges[] = ['text' => $cat->name, 'type' => 'category']; if (count($badges) >= 2) break; } } } // Priority 4: Secondary keywords if ($secondary_kws && count($badges) < 2) { $kw_array = is_array($secondary_kws) ? $secondary_kws : explode(',', $secondary_kws); foreach ($kw_array as $kw) { $kw = trim($kw); if (!empty($kw) && stripos($heading_lower, strtolower($kw)) !== false) { $badges[] = ['text' => $kw, 'type' => 'keyword']; if (count($badges) >= 2) break; } } } return $badges; } /** * Check if section content contains a table * * @param string $section_html Section HTML content * @return bool True if contains table */ function igny8_section_has_table($section_html) { return (stripos($section_html, ']*>(.*?)<\/h2>/i', $content, $matches); if (!empty($matches[1])) { foreach ($matches[1] as $index => $heading) { $heading_text = strip_tags($heading); $slug = sanitize_title($heading_text); $toc_items[] = [ 'number' => $index + 1, 'text' => $heading_text, 'id' => $slug ]; } } return $toc_items; } /** * Render widget placeholder * * @param string $position 'left' or 'right' * @param int $section_index Section index * @return void */ function igny8_render_widget_placeholder($position, $section_index) { // Check if widgets are enabled in settings $widgets_enabled = get_option('igny8_widgets_enabled', false); if (!$widgets_enabled) { return; } $placeholder_class = 'igny8-widget-placeholder igny8-widgets-enabled'; $placeholder_class .= ' igny8-widget-' . $position; $placeholder_class .= ' igny8-widget-section-' . $section_index; ?>