Have faith 😉
Unfortunately, your code ain’t correct in multiple ways. It assumes that the content only consists of content enclosed by paragraphs and doesn’t work correctly if not.
This would be one solution:
add_filter('the_content', 'prefix_insert_post_ads');
/**
* Content Filter
*/
function prefix_insert_post_ads($content) {
$insertion = 'Your AD Code';
if (is_single() && ! is_admin()) {
return prefix_insert_after_paragraphs($content, $insertion, array(4,20));
}
return $content;
}
// Function that makes the magic happen correctly
function prefix_insert_after_paragraphs($content, $insertion, $paragraph_indexes) {
// find all paragraph ending offsets
preg_match_all('#</p>#i', $content, $matches, PREG_SET_ORDER+PREG_OFFSET_CAPTURE);
// reduce matches to offset positions
$matches = array_map(function($match) {
return $match[0][1] + 4; // return string offset + length of </p> Tag
}, $matches);
// reverse sort indexes: plain text insertion just works nicely in reverse order
rsort($paragraph_indexes);
// cycle through and insert on demand
foreach ($paragraph_indexes as $paragraph_index) {
if ($paragraph_index <= count($matches)) {
$offset_position = $matches[$paragraph_index-1];
$content = substr($content, 0, $offset_position) . $insertion . substr($content, $offset_position);
}
}
return $content;
}
Best regards from Salzburg!