Reputation: 530
I need to insert an ad code at intervals in this way:
$insert_every_paragraphs
is a variable that indicates how often a paragraph should appear in the text. 10, for example.$minimum_paragraph_count
is used to see if the text is long enough for any ads, and also the very first ad should appear after this many paragraphs (then it should repeat the intervals in #1). 4, for example.[cms_ad:x100]
and PHP replaces them later (that part works fine).So in this example, it would work like this: after 4 paragraphs, insert x100. Then, every 10 paragraphs, insert another until x103 has been inserted. Don't insert x104, even if there are 100 paragraphs. But also, if there aren't at least 34 paragraphs, x103 would never appear.
What I have so far is this:
$paragraph_end = '</p>';
$insert_every_paragraphs = 10;
$minimum_paragraph_count = 4;
$embed_prefix = 'x';
$start_embed_id = 'x100';
$start_embed_count = intval( str_replace( $embed_prefix, '', $start_embed_id ) ); // ex 100
$end_embed_id = 'x103';
$end_embed_count = intval( str_replace( $embed_prefix, '', $end_embed_id ) ); // ex 104
$paragraph_positions = array();
$last_position = -1;
while ( stripos( $content, $paragraph_end, $last_position + 1 ) !== false ) {
// Get the position of the end of the next $paragraph_end.
$last_position = stripos( $content, $paragraph_end, $last_position + 1 ) + 3;
$paragraph_positions[] = $last_position;
}
// If the total number of paragraphs is bigger than the minimum number of paragraphs
if ( count( $paragraph_positions ) >= $minimum_paragraph_count ) {
// How many ads have been added?
$n = $start_embed_count;
// Store the position of the last insertion.
$previous_position = $start_embed_count;
$i = 0;
while ( $i < count( $paragraph_positions ) && $n <= $end_embed_count ) {
if ( 0 === ( $i + 1 ) % $insert_every_paragraphs && isset( $paragraph_positions[ $i ] ) ) {
$shortcode = "\n" . '[cms_ad:' . $embed_prefix . (int) $n . ']' . "\n";
$position = $paragraph_positions[ $i ] + 1;
if ( $position > $previous_position ) {
$content = substr_replace( $content, $shortcode, $paragraph_positions[ $i ] + 1, 0 );
// Increase the saved last position.
$previous_position = $position;
// Increment number of shortcodes added to the post.
$n++;
}
// Increase the position of later shortcodes by the length of the current shortcode.
foreach ( $paragraph_positions as $j => $pp ) {
if ( $j > $i ) {
$paragraph_positions[ $j ] = $pp + strlen( $shortcode );
}
}
}
$i++;
}
}
I thought this was working okay when the numbers were 4 and 6 instead of 4 and 10, but the error became clear when I started adjusting the values. It currently inserts an ad every 10 paragraphs, and of course it does not insert an ad after the fourth paragraph.
I'm not opposed to using explode
or other methods for this, of course, but this was what got me the farthest.
Upvotes: 1
Views: 1641
Reputation: 6540
Why not split the paragraphs into an array, add the ads, then join it together again. It will remove most of the string-concatination headache.
Please note i did not implement the formatting of the shortcode.
$insert_every_paragraphs = 2;
$minimum_paragraph_count = 1;
$adcodes = ['x100', 'x101', 'x102', 'x103'];
$paragraphs = [];
$split = explode('</p>',$content);
foreach($split as $paragraph){
//filter out empty paragraphs
if(strlen($paragraph)>3)
$paragraphs[] = $paragraph . '</p>';
}
$paragraph_count = count($paragraphs);
$ad_num = 0;
$counter = $minimum_paragraph_count;
for($i=0;$i<$paragraph_count;$i++){
if($counter==0){
$adcode = $adcodes[$ad_num];
$shortcode = "[cms_ad:$adcode]";
array_splice($paragraphs,$i+$ad_num,0,$shortcode);
$counter = $insert_every_paragraphs;
$ad_num++;
if($ad_num>=count($adcodes))
break;
}
$counter--;
}
$content = implode('',$paragraphs);
Upvotes: 3