]*>/i', $inner_html, $matches)) {
$detected_level = intval($matches[1]);
$block['attrs']['level'] = $detected_level;
error_log("IGNY8 BLOCKS: Fixed heading block #$index - detected level $detected_level from innerHTML");
} else {
// Default to H2 if we can't detect
$block['attrs']['level'] = 2;
error_log("IGNY8 BLOCKS: Fixed heading block #$index - defaulted to level 2");
}
}
}
$fixed_blocks[] = $block;
}
return serialize_blocks($fixed_blocks);
}
/**
* Inject plain Igny8 shortcodes after H2 for Classic Editor only (no block markup).
*/
function insert_igny8_image_shortcodes_classic($html_content) {
error_log("IGNY8 DEBUG: I AM ACTIVE AND RUNNING IN MODULE-AI.PHP - insert_igny8_image_shortcodes_classic()");
error_log("IGNY8 DEBUG: CALLED FROM - igny8_create_post_from_ai_response() function in ai/modules-ai.php");
error_log("IGNY8 DEBUG - CLASSIC: Starting shortcode injection");
error_log("IGNY8 DEBUG - CLASSIC: Input content length: " . strlen($html_content));
if (empty($html_content)) {
error_log("IGNY8 DEBUG - CLASSIC: Content is empty, returning");
return $html_content;
}
$pattern = '/(]*>.*?<\/h2>)/i';
$matches = [];
preg_match_all($pattern, $html_content, $matches, PREG_OFFSET_CAPTURE);
error_log("IGNY8 DEBUG - CLASSIC: Found " . count($matches[0]) . " H2 headings");
if (empty($matches[0])) {
error_log("IGNY8 DEBUG - CLASSIC: No H2 headings found, returning original content");
return $html_content;
}
$offset = 0;
$image_index = 0;
foreach (array_reverse($matches[0]) as $match) {
$image_index++;
error_log("IGNY8 DEBUG - CLASSIC: Processing H2 #{$image_index}");
// Skip first H2
if ($image_index === count($matches[0])) {
error_log("IGNY8 DEBUG - CLASSIC: Skipping first H2");
continue;
}
// Inject plain shortcodes (no Gutenberg markup)
$shortcode = "\n\n[igny8-image id=\"desktop-{$image_index}\"] [igny8-image id=\"mobile-{$image_index}\"]\n\n";
error_log("IGNY8 DEBUG - CLASSIC: Injecting shortcode: " . trim($shortcode));
$insert_pos = $match[1] + strlen($match[0]) + $offset;
$html_content = substr_replace($html_content, $shortcode, $insert_pos, 0);
$offset += strlen($shortcode);
}
error_log("IGNY8 DEBUG - CLASSIC: Final content length: " . strlen($html_content));
error_log("IGNY8 DEBUG - CLASSIC: Shortcodes in final content: " . (strpos($html_content, '[igny8-image') !== false ? 'YES' : 'NO'));
return $html_content;
}
/**
* Inject Gutenberg shortcode blocks after each heading block (core/heading, level 2)
* Adds minimal, meaningful logs. Silences irrelevant debug spam.
*
* @param string $block_content Serialized Gutenberg block content
* @return string|false Modified content or false if injection fails
*/
function insert_igny8_shortcode_blocks_into_blocks($block_content) {
error_log("IGNY8 DEBUG: I AM ACTIVE AND RUNNING IN MODULE-AI.PHP - insert_igny8_shortcode_blocks_into_blocks()");
error_log("IGNY8 DEBUG: CALLED FROM - igny8_create_post_from_ai_response() function in ai/modules-ai.php");
if (empty($block_content)) {
error_log("IGNY8 BLOCKS: No content passed to shortcode injector");
return $block_content;
}
$blocks = parse_blocks($block_content);
$output = [];
$h2_count = 0;
$injected = 0;
$heading_blocks_found = 0;
$valid_h2_blocks = 0;
error_log("IGNY8 BLOCKS: Parsed " . count($blocks) . " total blocks");
foreach ($blocks as $index => $block) {
$output[] = $block;
if (($block['blockName'] ?? null) === 'core/heading') {
$heading_blocks_found++;
$level = $block['attrs']['level'] ?? null;
error_log("IGNY8 BLOCKS: Heading block #$index - level: " . ($level ?? 'NULL') . ", innerHTML: " . substr($block['innerHTML'] ?? '', 0, 50) . "...");
if ($level !== 2) {
if ($level === null) {
error_log("IGNY8 BLOCKS: Skipping heading block #$index — missing 'level' attribute");
} else {
error_log("IGNY8 BLOCKS: Skipping heading block #$index — level $level (not H2)");
}
continue;
}
$valid_h2_blocks++;
$h2_count++;
if ($h2_count === 1) {
error_log("IGNY8 BLOCKS: Skipping first H2 (no shortcode)");
continue;
}
$shortcode = "[igny8-image id=\"desktop-{$h2_count}\"] [igny8-image id=\"mobile-{$h2_count}\"]";
error_log("IGNY8 BLOCKS: Injecting shortcode after H2 #{$h2_count}: " . $shortcode);
$output[] = [
'blockName' => 'core/shortcode',
'attrs' => [],
'innerBlocks' => [],
'innerHTML' => $shortcode,
'innerContent' => [$shortcode]
];
$injected++;
}
}
error_log("IGNY8 BLOCKS: Summary - Total headings: $heading_blocks_found, Valid H2s: $valid_h2_blocks, Shortcodes injected: $injected");
$result = serialize_blocks($output);
$parsed_result = parse_blocks($result);
$confirmed = false;
foreach ($parsed_result as $b) {
if (
($b['blockName'] ?? '') === 'core/shortcode' &&
strpos($b['innerContent'][0] ?? '', '[igny8-image') !== false
) {
$confirmed = true;
break;
}
}
if (!$confirmed) {
error_log("IGNY8 BLOCKS: ❌ Shortcode injection failed — no blocks found after serialization");
igny8_log_ai_event(
'Shortcode Injection Failed',
'writer',
'content_generation',
'error',
'No shortcodes found after injection (post-parse)',
'Editor type: block'
);
return false;
}
error_log("IGNY8 BLOCKS: ✅ Injected {$injected} shortcode blocks after H2 headings");
return $result;
}
/**
* Wrap plain HTML content as Gutenberg blocks
*
* @param string $html_content Plain HTML content
* @return string Gutenberg block markup
*/
function wrap_html_as_blocks($html_content) {
if (empty($html_content)) {
return $html_content;
}
// Split content into lines for processing
$lines = explode("\n", $html_content);
$block_content = [];
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) {
continue;
}
// Wrap different HTML elements as Gutenberg blocks
if (preg_match('/^]*>(.*?)<\/h2>$/i', $line, $matches)) {
$block_content[] = '' . $line . '';
} elseif (preg_match('/^]*>(.*?)<\/h3>$/i', $line, $matches)) {
$block_content[] = '' . $line . '';
} elseif (preg_match('/^
]*>(.*?)<\/p>$/i', $line, $matches)) {
$block_content[] = '' . $line . '';
} elseif (preg_match('/^
]*>(.*?)<\/ul>$/i', $line, $matches)) {
$block_content[] = '' . $line . '';
} elseif (preg_match('/^]*>(.*?)<\/ol>$/i', $line, $matches)) {
$block_content[] = '' . $line . '';
} elseif (preg_match('/^]*>(.*?)<\/blockquote>$/i', $line, $matches)) {
$block_content[] = '' . $line . '';
} elseif (preg_match('/^]*>(.*?)<\/table>$/i', $line, $matches)) {
$block_content[] = '' . $line . '';
} elseif (preg_match('/^\[igny8-image[^\]]*\]/', $line)) {
// Handle shortcodes - wrap in shortcode block
$block_content[] = '' . $line . '';
} else {
// For any other content, wrap as paragraph
$block_content[] = '' . $line . '
';
}
}
return implode("\n", $block_content);
}