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); // Load HTML with proper encoding $dom->loadHTML('' . $content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); libxml_clear_errors(); $intro_html = ''; $sections = []; $current_section = null; // Get body node $body = $dom->getElementsByTagName('body')->item(0); if (!$body) { return ['intro' => $content, 'sections' => []]; } // Iterate through all child nodes foreach ($body->childNodes 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); }