Here is my approach to the question. Sorry for posting a bit late ( and missing the bounty :-( ), but it has been a hectic week, so I did everything in bits and pieces.
**QUICK RUNDOWN**
- I have not removed the attachments in the first paragraph. I don't really see why content must be vandalized for the sake of an ad
- I have done quite a lot of checks in my code to try and make sure that ads are only inserted in between text only paragraphs. Text only paragraphs are taken to be paragraphs that does not contain img, li and ul tags
- I have documented each block of code properly, so you can easily work through each section. I have also added `todo` doc blocks which you need to attend to, if necessary
- I have used `wptexturize` to apply p tags to `the_content`. Each double line break constitutes a paragraph
- Modify and use this code as you see fit. I have tested it, so it is bug free on my side.
Here is the code. Hope this works for you as expected. *PS! All of this goes into your functions.php. No need for any other code or mods to your template files
<?php
add_filter( 'the_content', 'so_25888630_ad_between_paragraphs' );
function so_25888630_ad_between_paragraphs($content){
/**-----------------------------------------------------------------------------
*
* @author Pieter Goosen <http://stackoverflow.com/users/1908141/pieter-goosen>
* @return Ads in between $content
* @link
[To see links please register here]
*
* Special thanks to the following answers on my questions that helped me to
* to achieve this
* -
[To see links please register here]
* -
[To see links please register here]
* -
[To see links please register here]
* -
[To see links please register here]
*
*------------------------------------------------------------------------------*/
if( in_the_loop() ){ //Simply make sure that these changes effect the main query only
/**-----------------------------------------------------------------------------
*
* wptexturize is applied to the $content. This inserts p tags that will help to
* split the text into paragraphs. The text is split into paragraphs after each
* closing p tag. Remember, each double break constitutes a paragraph.
*
* @todo If you really need to delete the attachments in paragraph one, you want
* to do it here before you start your foreach loop
*
*------------------------------------------------------------------------------*/
$closing_p = '</p>';
$paragraphs = explode( $closing_p, wptexturize($content) );
/**-----------------------------------------------------------------------------
*
* The amount of paragraphs is counted to determine add frequency. If there are
* less than four paragraphs, only one ad will be placed. If the paragraph count
* is more than 4, the text is split into two sections, $first and $second according
* to the midpoint of the text. $totals will either contain the full text (if
* paragraph count is less than 4) or an array of the two separate sections of
* text
*
* @todo Set paragraph count to suite your needs
*
*------------------------------------------------------------------------------*/
$count = count( $paragraphs );
if( 4 >= $count ) {
$totals = array( $paragraphs );
}else{
$midpoint = floor($count / 2);
$first = array_slice($paragraphs, 0, $midpoint );
if( $count%2 == 1 ) {
$second = array_slice( $paragraphs, $midpoint, $midpoint, true );
}else{
$second = array_slice( $paragraphs, $midpoint, $midpoint-1, true );
}
$totals = array( $first, $second );
}
$new_paras = array();
foreach ( $totals as $key_total=>$total ) {
/**-----------------------------------------------------------------------------
*
* This is where all the important stuff happens
* The first thing that is done is a work count on every paragraph
* Each paragraph is is also checked if the following tags, a, li and ul exists
* If any of the above tags are found or the text count is less than 10, 0 is
* returned for this paragraph. ($p will hold these values for later checking)
* If none of the above conditions are true, 1 will be returned. 1 will represent
* paragraphs that qualify for add insertion, and these will determine where an ad
* will go
* returned for this paragraph. ($p will hold these values for later checking)
*
* @todo You can delete or add rules here to your liking
*
*------------------------------------------------------------------------------*/
$p = array();
foreach ( $total as $key_paras=>$paragraph ) {
$word_count = count(explode(' ', $paragraph));
if( preg_match( '~<(?:img|ul|li)[ >]~', $paragraph ) || $word_count < 10 ) {
$p[$key_paras] = 0;
}else{
$p[$key_paras] = 1;
}
}
/**-----------------------------------------------------------------------------
*
* Return a position where an add will be inserted
* This code checks if there are two adjacent 1's, and then return the second key
* The ad will be inserted between these keys
* If there are no two adjacent 1's, "no_ad" is returned into array $m
* This means that no ad will be inserted in that section
*
*------------------------------------------------------------------------------*/
$m = array();
foreach ( $p as $key=>$value ) {
if( 1 === $value && array_key_exists( $key-1, $p ) && $p[$key] === $p[$key-1] && !$m){
$m[] = $key;
}elseif( !array_key_exists( $key+1, $p ) && !$m ) {
$m[] = 'no-ad';
}
}
/**-----------------------------------------------------------------------------
*
* Use two different ads, one for each section
* Only ad1 is displayed if there is less than 4 paragraphs
*
* @todo Replace "PLACE YOUR ADD NO 1 HERE" with your add or code. Leave p tags
* @todo I will try to insert widgets here to make it dynamic
*
*------------------------------------------------------------------------------*/
if( $key_total == 0 ){
$ad = array( 'ad1' => '<p>PLACE YOUR ADD NO 1 HERE</p>' );
}else{
$ad = array( 'ad2' => '<p>PLACE YOUR ADD NO 2 HERE</p>' );
}
/**-----------------------------------------------------------------------------
*
* This code loops through all the paragraphs and checks each key against $mail
* and $key_para
* Each paragraph is returned to an array called $new_paras. $new_paras will
* hold the new content that will be passed to $content.
* If a key matches the value of $m (which holds the array key of the position
* where an ad should be inserted) an add is inserted. If $m holds a value of
* 'no_ad', no ad will be inserted
*
*------------------------------------------------------------------------------*/
foreach ( $total as $key_para=>$para ) {
if( !in_array( 'no_ad', $m ) && $key_para === $m[0] ){
$new_paras[key($ad)] = $ad[key($ad)];
$new_paras[$key_para] = $para;
}else{
$new_paras[$key_para] = $para;
}
}
}
/**-----------------------------------------------------------------------------
*
* $content should be a string, not an array. $new_paras is an array, which will
* not work. $new_paras are converted to a string with implode, and then passed
* to $content which will be our new content
*
*------------------------------------------------------------------------------*/
$content = implode( ' ', $new_paras );
}
return $content;
}
**EDIT**
From your comments:
- You should use the following code to debug `<pre><?php var_dump($NAME_OF_VARIABLE); ?></pre>`. For your first issue, I will use `?><pre><?php var_dump($paragraphs); ?></pre><?php` just after this line `$paragraphs = explode( $closing_p, wpautop($content) );` to exactly see how the content is split up. This will give you an idea if your content is being split up correctly.
- Also use `?><pre><?php var_dump($p); ?></pre><?php` just after this line `$p = array();` to inspect what value is given to a specific paragraph. Remember, paragraphs with img, li and ul tags should have a `0`, also paragraphs with less than 10 words. The rest should have a 1
- *EDIT* -> Issue with stripped paragraphs is resolved. Thanks for pointing that flaw out to me. Never realized this. I have updated the code, so just simply copy and paste it
**EDIT 2**
Please note, you cannot test your code with the online tool you are using. This is not a true reflection of of what is output by `the_content()`. The output that you see using your online tool is filtered and marked up before being send to the screen as `the_content()`. If you inspect your output with a browser like google chrome, you will see that p tags are correctly applied.
I have also changed the a tag with image tag in the code