Place content between paragraphs without images

I use the following code to place some ad code inside my content.

<?php $content = apply_filters('the_content', $post->post_content); $content = explode (' ', $content); $halfway_mark = ceil(count($content) / 2); $first_half_content = implode(' ', array_slice($content, 0, $halfway_mark)); $second_half_content = implode(' ', array_slice($content, $halfway_mark)); echo $first_half_content.'...'; echo ' YOUR ADS CODE'; echo $second_half_content; ?> 

How can I change this so that the 2 paragraphs (top and bottom) enclosed in the ad code should not have images. If the top or bottom paragraph has an image, try the next 2 paragraphs.

Example : correct implementation on the right.

enter image description here

+6
source share
4 answers

preg_replace version

This code goes through each paragraph, ignoring those that contain image tags. The $pcount incremented for each paragraph found without an image, if the image occurs, however, $pcount is reset to zero. As soon as $pcount reaches the point where it reaches two, advertising markup will be inserted immediately before this paragraph. This should leave the markup between two safe paragraphs. Then, the ad layout variable is canceled, so only one ad is inserted.

The following code is for customization purposes only and can be changed to separate the content differently, you can also change the regular expression that is used - just in case you use double BRs or something else to separate your paragraphs.

 /// set our advert content $advert = '<marquee>BUY THIS STUFF!!</marquee>' . "\n\n"; /// calculate mid point $mpoint = floor(strlen($content) / 2); /// modify back to the start of a paragraph $mpoint = strripos($content, '<p', -$mpoint); /// split html so we only work on second half $first = substr($content, 0, $mpoint); $second = substr($content, $mpoint); $pcount = 0; $regexp = '/<p>.+?<\/p>/si'; 

The rest is the main part of the code that triggers the replacement. This can be modified to insert more than one ad or to support more thorough image verification.

 $content = $first . preg_replace_callback($regexp, function($matches){ global $pcount, $advert; if ( !$advert ) { $return = $matches[0]; } else if ( stripos($matches[0], '<img ') !== FALSE ) { $return = $matches[0]; $pcount = 0; } else if ( $pcount === 1 ) { $return = $advert . $matches[0]; $advert = ''; } else { $return = $matches[0]; $pcount++; } return $return; }, $second); 

After executing this code, the $content variable will contain rich HTML.


PHP versions up to 5.3

Since your chosen test area does not support PHP 5.3 and therefore does not support anonymous functions, you need to use a slightly modified and less compressed version; a named function is used instead.

In addition, in order to support content that actually leaves no room for advertising in the second half, I changed $mpoint so that it was calculated at 80% of the end. This will result in the inclusion of more in the $second part - but also means that your advertisements will usually be placed higher in the premium. This code did not implement any reserve in it, because your question does not mention what should happen in the event of a failure.

 $advert = '<marquee>BUY THIS STUFF!!</marquee>' . "\n\n"; $mpoint = floor(strlen($content) * 0.8); $mpoint = strripos($content, '<p', -$mpoint); $first = substr($content, 0, $mpoint); $second = substr($content, $mpoint); $pcount = 0; $regexp = '/<p>.+?<\/p>/si'; function replacement_callback($matches){ global $pcount, $advert; if ( !$advert ) { $return = $matches[0]; } else if ( stripos($matches[0], '<img ') !== FALSE ) { $return = $matches[0]; $pcount = 0; } else if ( $pcount === 1 ) { $return = $advert . $matches[0]; $advert = ''; } else { $return = $matches[0]; $pcount++; } return $return; } echo $first . preg_replace_callback($regexp, 'replacement_callback', $second); 
+3
source

You can try the following:

  <?php $ad_code = 'SOME SCRIPT HERE'; // Your code. $content = apply_filters('the_content', $post->post_content); // Split the content at the <p> tags. $content = explode ('<p>', $content); // Find the mid of the article. $content_length = count($content); $content_mid = floor($content_length / 2); // Save no image p index. $last_no_image_p_index = NULL; // Loop beginning from the mid of the article to search for images. for ($i = $content_mid; $i < $content_length; $i++) { // If we do not find an image, let it go down. if (stripos($content[$i], '<img') === FALSE) { // In case we already have a last no image p, we check // if it was the one right before this one, so we have // two p tags with no images in there. if ($last_no_image_p_index === ($i - 1)) { // We break here. break; } else { $last_no_image_p_index = $i; } } } // If no none image p tag was found, we use the last one. if (is_null($last_no_image_p_index)) { $last_no_image_p_index = ($content_length - 1); } // Add ad code here with trailing <p>, so the implode later will work correctly. $content = array_slice($content, $last_no_image_p_index, 0, $ad_code . '</p>'); $content = implode('<p>', $content); ?> 

He will try to find a place for an ad from the middle of your article, and if none are found, the ad will be completed.

Relationship func0der

+1
source

I think this will work:

Blow up the paragraphs first, then you have to loop it and check if you find img inside them. If you find it inside, try the following.

Think of it as psuedo-code, as it has not been tested. You will also have to make a loop, comments in the code :) Sorry, if it contains errors, it is written in Notepad.

 <?php $i = 0; // counter $arrBoolImg = array(); // array for the paragraph booleans $content = apply_filters('the_content', $post->post_content); $contents = str_replace ('<p>', '<explode><p>', $content); // here we add a custom tag, so we can explode $contents = explode ('<explode>', $contents); // then explode it, so we can iterate the paragraphs // fill array with boolean array returned $arrBoolImg = hasImages($contents); $halfway_mark = ceil(count($contents) / 2); /* TODO (by you): --- When you have $arrBoolImg filled, you can itarate through it. You then simply loop from the middle of the array $contents (plural), that is exploded from above. The startingpoing for your loop is the middle, the upper bounds is the +2 or what ever :-) Then you simply insert your magic.. And then glue it back together, as you did before. I think this will work. even though the code may have some bugs, since I wrote it in Notepad. */ function hasImages($contents) { /* This function loops through the $contents array and checks if they have images in them The return value, is an array with boolean values, so one can iterate through it. */ $arrRet = array(); // array for the paragraph booleans if (count($content)>=1) { foreach ($contents as $v) { // iterate the content if (strpos($v, '<img') === false) { // did not find img $arrRet[$i] = false; } else { // found img $arrRet[$i] = true; } $i++; } // end for each loop return $arrRet; } // end if count } // end hasImages func ?> 
0
source

[This is just an idea, I don't have enough reputation for comment ...]

After calling the @Olavxxx method and filling up your logical array, you can simply skip this array in an alternating manner, starting from the middle: suppose your array takes 8 entries. By calculating the middle, using your method, you get 4. So you check the combination of 4 + 3 values, if that doesn't work, you check 4 + 5, then 3 + 2, ...

So your loop looks something like

 $middle = ceil(count($content) / 2); $i = 1; while ($i <= $middle) { $j = $middle + (-1) ^ $i * $i; $k = $j + 1; if (!$hasImagesArray[$j] && !$hasImagesArray[$k]) break; // position found $i++; } 

This is for you to implement additional restrictions, to make sure that the addition is not shown far up or down in the article ...

Note that you need to take care of special cases, for example, arrays that are too short to prevent IndexOutOfBounds exceptions.

0
source

All Articles