362 lines
10 KiB
PHP
362 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* Template Helper Functions
|
|
*
|
|
* Helper functions for IGNY8 content template
|
|
*
|
|
* @package Igny8Bridge
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Parse content HTML into intro and H2 sections
|
|
*
|
|
* @param string $content HTML content
|
|
* @return array ['intro' => 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 = '<div>' . $content . '</div>';
|
|
$dom->loadHTML('<?xml encoding="UTF-8">' . $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) {
|
|
static $used_keywords = [];
|
|
|
|
$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 not used)
|
|
if ($primary_kw && !in_array(strtolower($primary_kw), $used_keywords) && stripos($heading_lower, strtolower($primary_kw)) !== false) {
|
|
$badges[] = ['text' => $primary_kw, 'type' => 'primary'];
|
|
$used_keywords[] = strtolower($primary_kw);
|
|
return $badges; // Return only 1 badge
|
|
}
|
|
|
|
// Priority 2: Tags (if not used)
|
|
if ($tags && !is_wp_error($tags)) {
|
|
foreach ($tags as $tag) {
|
|
if (!in_array(strtolower($tag->name), $used_keywords) && stripos($heading_lower, strtolower($tag->name)) !== false) {
|
|
$badges[] = ['text' => $tag->name, 'type' => 'tag'];
|
|
$used_keywords[] = strtolower($tag->name);
|
|
return $badges; // Return only 1 badge
|
|
}
|
|
}
|
|
}
|
|
|
|
// Priority 3: Categories (if not used)
|
|
if ($categories && !is_wp_error($categories)) {
|
|
foreach ($categories as $cat) {
|
|
if (!in_array(strtolower($cat->name), $used_keywords) && stripos($heading_lower, strtolower($cat->name)) !== false) {
|
|
$badges[] = ['text' => $cat->name, 'type' => 'category'];
|
|
$used_keywords[] = strtolower($cat->name);
|
|
return $badges; // Return only 1 badge
|
|
}
|
|
}
|
|
}
|
|
|
|
// Priority 4: Secondary keywords (if not used)
|
|
if ($secondary_kws) {
|
|
$kw_array = is_array($secondary_kws) ? $secondary_kws : explode(',', $secondary_kws);
|
|
foreach ($kw_array as $kw) {
|
|
$kw = trim($kw);
|
|
if (!empty($kw) && !in_array(strtolower($kw), $used_keywords) && stripos($heading_lower, strtolower($kw)) !== false) {
|
|
$badges[] = ['text' => $kw, 'type' => 'keyword'];
|
|
$used_keywords[] = strtolower($kw);
|
|
return $badges; // Return only 1 badge
|
|
}
|
|
}
|
|
}
|
|
|
|
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, '<table') !== false);
|
|
}
|
|
|
|
/**
|
|
* Get image aspect ratio from position
|
|
*
|
|
* @param int $position Image position (0-3)
|
|
* @return string 'square' or 'landscape'
|
|
*/
|
|
function igny8_get_image_aspect($position) {
|
|
// Even positions (0, 2) = square
|
|
// Odd positions (1, 3) = landscape
|
|
return ($position % 2 === 0) ? 'square' : 'landscape';
|
|
}
|
|
|
|
/**
|
|
* Determine if image description should be shown
|
|
*
|
|
* @param int $section_index Section index (0-based)
|
|
* @return bool True if should show description
|
|
*/
|
|
function igny8_show_image_description($section_index) {
|
|
// First 4 sections (0-3) show descriptions
|
|
return ($section_index < 4);
|
|
}
|
|
|
|
/**
|
|
* Generate table of contents from content
|
|
*
|
|
* @param string $content HTML content
|
|
* @return array Array of TOC items with 'number', 'text', and 'id' keys
|
|
*/
|
|
function igny8_generate_table_of_contents($content) {
|
|
$toc_items = [];
|
|
|
|
// Parse content for H2 headings
|
|
preg_match_all('/<h2[^>]*>(.*?)<\/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;
|
|
|
|
?>
|
|
<div class="<?php echo esc_attr($placeholder_class); ?>"
|
|
data-widget-position="<?php echo esc_attr($position); ?>"
|
|
data-section-index="<?php echo esc_attr($section_index); ?>">
|
|
<?php
|
|
/**
|
|
* Action hook for widget placeholder content
|
|
*
|
|
* @param string $position Widget position (left/right)
|
|
* @param int $section_index Section index
|
|
*/
|
|
do_action('igny8_widget_placeholder', $position, $section_index);
|
|
?>
|
|
</div>
|
|
<?php
|
|
}
|