Plugin packaging and docs
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
<?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);
|
||||
}
|
||||
Reference in New Issue
Block a user