要正确计算段落数并保持一致,最好是利用原始帖子内容,然后应用wpautop
过滤到原始内容。这样,WordPress将处理所有变量,这些变量最终将决定段落的构建和显示方式
我们还可以考虑其他一些因素,以使其尽可能可靠
因为这只需要一篇文章,所以我们将使用查询的对象从中获取原始文章内容
在插入附加内容之前,确保我们有最少的段落
使用in_the_loop()
仅以主查询循环为目标的条件
-我决定将所有这些都添加到一个类中
/**
* Class AdsINParagraphs
*
* Class to inject ads into single post\'s content between paragraphs
* as required
*/
class GoogleAdsINParagraphs
{
/**
* @var string $ad
* @access protected
* @since 1.1.0
*/
protected $ad;
/**
* @var int|string $min
* @access protected
* @since 1.1.0
*/
protected $min;
/**
* @var array $inject
* @access protected
* @since 1.1.0
*/
protected $inject;
/**
* @var $post = NULL
* @access protected
* @since 1.1.0
*/
protected $post = NULL;
/**
* @var $paragraphs = NULL
* @access protected
* @since 1.1.0
*/
protected $paragraphs = NULL;
/**
* @var $paraCount = 0
* @access protected
* @since 1.1.0
*/
protected $paraCount = 0;
/**
* @var $contentReplacement = NULL
* @access protected
* @since 1.1.0
*/
protected $contentReplacement = NULL;
/**
* Public method __construct()
*
* Constructor for the GoogleAdsINParagraphs class
*
* @param string $ad The add that should be injected
* @param string|int $min The minimum amount of paragraphs that must exist
* @param array $inject An array of paragraph numbers where the add should be injected
* If you need an ad before the content, simply pass 0 as first value
* @access public
* @since 1.1.0
*/
public function __construct( $ad = NULL, $min = 4, $inject = [] )
{
$this->ad = $ad;
$this->min = $min;
$this->inject = $inject;
}
/**
* Public method init()
*
* Initialize the \'the_content\' filter callback
*
* @access public
* @since 1.1.0
*/
public function init()
{
add_filter( \'the_content\', [$this, \'postContent\'] );
}
/**
* Protected method initHelperMethods()
*
* Initialize all the helper functions for the \'the_content\' filter callback
*
* @access protected
* @since 1.1.0
*/
protected function initHelperMethods()
{
$this->post();
$this->paragraphs();
$this->paraCount();
$this->contentReplacement();
}
/**
* Protected method post()
*
* Gets the current post object and sanitize the post object. Sanitation
* is done as precaution should the query object being altered by some other
* program/function/malicious code
*
* @access protected
* @since 1.1.0
*/
protected function post()
{
$post_raw = get_queried_object();
// Sanitize the post object in case that something externally changed the queried object
$post = sanitize_post( $post_raw );
$this->post = $post;
}
/**
* Protected method paragraphs()
*
* Gets the current post\'s post content, sanitizes it and then applies the wpautop filter
* function to it to apply p tags to the raw content. After the filter function is applied,
* the content is exploded into an array of paragraphs
*
* @access protected
* @since 1.1.0
*/
protected function paragraphs()
{
// Just in case, as extra precaution, run the raw post comment through wp_kses_post
$noEvilContent = wp_kses_post( $this->post->post_content );
$peedContent = wpautop( $noEvilContent );
$paragraphs = explode( \'<p>\', $peedContent );
$this->paragraphs = $paragraphs;
}
/**
* Protected method paraCount()
*
* Counts the amount of paragraphs created by the paragraphs() method
*
* @access protected
* @since 1.1.0
*/
protected function paraCount()
{
$paraCount = count( $this->paragraphs );
$this->paraCount = (int) $paraCount;
}
/**
* Protected method contentReplacement()
*
* This is where everything happens. The following checks are run
* before ads are inserted into the content
* - Check if there is at least the set minimum amount of paragraphs.
* Checks are done against $this->min
* - Check if there at least enough paragraphs to fullfil the lowest
* passed number in $this->inject
* - Check to see if $this->inject is a valid array with values
*
* If all checks pass, ads is inserted into the content. If any value
* in $this->inject is more than the amount of paragraphs, the ad is ignored
* and not inserted
*
* @access protected
* @since 1.1.0
*/
protected function contentReplacement()
{
// Lets first run all our checks
$this->contentReplacement = $contentReplacement = NULL;
// Make sure that we have at least more paragraphs than our minimum, bail if not
if ( $this->paraCount < $this->min )
return $this->contentReplacement;
// Make sure that $this->inject is an array and not empty
if ( !is_array( $this->inject )
|| !$this->inject
)
return $this->contentReplacement;
/**
* We will do the following checks and validation on $this->inject
* - validate the array of ID\'s and remove negative numbers
* - sort $this->inject array numerically ASC according to passed ID\'s
* - remove possible dublicates
*/
$this->inject = filter_var(
$this->inject,
FILTER_VALIDATE_INT,
[
\'flags\' => FILTER_REQUIRE_ARRAY,
\'options\' => [
\'min_range\' => 0
]
]
);
asort( $this->inject );
$this->inject = array_unique( $this->inject );
// Make sure that we actaully have enough paragraphs to inject an add into
if ( $this->paraCount < $this->inject[0] )
return $this->contentReplacement;
// Now we can start to inject our ads into our content. Set $output as empty string
$output = \'\';
foreach ( $this->paragraphs as $key=>$paragraph ) {
// Add ad in front of content if $this->inject[0] === 0
if ( 0 === $key
&& 0 === $this->inject[0]
) {
$output .= \'<p>\' . $this->ad . \'</p>\' . $paragraph;
} elseif ( !in_array( $key, $this->inject ) ) {
$output .= $paragraph;
} else {
$output .= $paragraph . \'<p>\' . $this->ad . \'</p>\';
}
} // endforeach
$this->contentReplacement = $output;
}
/**
* Public method postContent()
*
* This is the callback method for the \'the_content\' filter. The content passed by reference
* inside the filter is replaced by any valid value from $this->contentReplacement. This is done
* purely for convenience
*
* @access public
* @since 1.1.0
* @return $content
*/
public function postContent( $content )
{
// Lets first run our checks, make sure this is a single page and the main query
if ( !is_single() )
return $content;
if ( !in_the_loop() )
return $content;
// Initialize our other helper methods. They should only run inside our condition
$this->initHelperMethods();
// Make sure $this->contentReplacement is not NULL, if so, just return $content
if ( NULL === $this->contentReplacement )
return $content;
// We can now replace $content with $this->contentReplacement
$content = $this->contentReplacement;
return $content;
}
} // end of class GoogleAdsINParagraphs
您现在可以按如下方式使用它
$ad = \'PLACE YOUR AD HERE\';
$add_ads = new GoogleAdsINParagraphs(
$ad, // Your ad which you want to add
4, // There should be at least 4 paragraphs
[4, 20] // Array of paragraph numbers after which you want to inject an add
);
$add_ads->init();