281 lines
8.3 KiB
PHP
281 lines
8.3 KiB
PHP
<?php
|
|
/**
|
|
* Class to auto-insert snippets on single posts.
|
|
*
|
|
* @package wpcode
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Class WPCode_Auto_Insert_Single.
|
|
*/
|
|
class WPCode_Auto_Insert_Single extends WPCode_Auto_Insert_Type {
|
|
|
|
/**
|
|
* The type unique name (slug).
|
|
*
|
|
* @var string
|
|
*/
|
|
public $name = 'single';
|
|
|
|
/**
|
|
* The category of this type.
|
|
*
|
|
* @var string
|
|
*/
|
|
public $category = 'page';
|
|
|
|
/**
|
|
* Used to make sure we only output the before post code once.
|
|
*
|
|
* @var bool
|
|
*/
|
|
private $did_before_post_output = false;
|
|
|
|
/**
|
|
* Load the available options and labels.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function init() {
|
|
$this->locations = array(
|
|
'before_post' => array(),
|
|
'after_post' => array(),
|
|
'before_content' => array(),
|
|
'after_content' => array(),
|
|
'before_paragraph' => array(),
|
|
'after_paragraph' => array(),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Load the label.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function load_label() {
|
|
$this->label = __( 'Page, Post, Custom Post Type', 'insert-headers-and-footers' );
|
|
}
|
|
|
|
/**
|
|
* Load the available locations.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function load_locations() {
|
|
$this->locations = array(
|
|
'before_post' => array(
|
|
'label' => esc_html__( 'Insert Before Post', 'insert-headers-and-footers' ),
|
|
'description' => esc_html__( 'Insert snippet at the beginning of a post.', 'insert-headers-and-footers' ),
|
|
),
|
|
'after_post' => array(
|
|
'label' => esc_html__( 'Insert After Post', 'insert-headers-and-footers' ),
|
|
'description' => esc_html__( 'Insert snippet at the end of a post.', 'insert-headers-and-footers' ),
|
|
),
|
|
'before_content' => array(
|
|
'label' => esc_html__( 'Insert Before Content', 'insert-headers-and-footers' ),
|
|
'description' => esc_html__( 'Insert snippet at the beginning of the post content.', 'insert-headers-and-footers' ),
|
|
),
|
|
'after_content' => array(
|
|
'label' => esc_html__( 'Insert After Content', 'insert-headers-and-footers' ),
|
|
'description' => esc_html__( 'Insert snippet at the end of the post content.', 'insert-headers-and-footers' ),
|
|
),
|
|
'before_paragraph' => array(
|
|
'label' => esc_html__( 'Insert Before Paragraph', 'insert-headers-and-footers' ),
|
|
'description' => esc_html__( 'Insert snippet before paragraph # of the post content.', 'insert-headers-and-footers' ),
|
|
),
|
|
'after_paragraph' => array(
|
|
'label' => esc_html__( 'Insert After Paragraph', 'insert-headers-and-footers' ),
|
|
'description' => esc_html__( 'Insert snippet after paragraph # of the post content.', 'insert-headers-and-footers' ),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Checks if we are on a singular page and we should be executing hooks.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function conditions() {
|
|
return is_singular();
|
|
}
|
|
|
|
/**
|
|
* Add hooks specific to single posts.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function hooks() {
|
|
add_action( 'the_post', array( $this, 'insert_before_post' ) );
|
|
add_filter( 'render_block_core/template-part', array( $this, 'insert_before_post_fse' ), 15, 2 );
|
|
add_action( 'the_content', array( $this, 'insert_after_post' ) );
|
|
add_filter( 'the_content', array( $this, 'insert_before_content' ) );
|
|
add_filter( 'the_content', array( $this, 'insert_after_content' ) );
|
|
add_filter( 'the_content', array( $this, 'insert_after_before_paragraph' ) );
|
|
}
|
|
|
|
/**
|
|
* Insert snippet before the post.
|
|
*
|
|
* @param WP_Post $post_object The post object being loaded.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function insert_before_post( $post_object ) {
|
|
if ( ! did_action( 'get_header' ) || get_the_ID() !== $post_object->ID || $this->did_before_post_output ) {
|
|
return;
|
|
}
|
|
$this->output_location( 'before_post' );
|
|
$this->did_before_post_output = true;
|
|
}
|
|
|
|
/**
|
|
* In FSE themes there's no "get_header" action to check for, so we hook after the core template-part header block.
|
|
*
|
|
* @param string $block_content The normal block HTML that would be sent to the screen.
|
|
* @param array $block An array of data about the block, and the way the user configured it.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function insert_before_post_fse( $block_content, $block ) {
|
|
// If the get_header action ran we use the classic output method above.
|
|
if ( did_action( 'get_header' ) ) {
|
|
return $block_content;
|
|
}
|
|
if ( ! isset( $block['attrs']['slug'] ) || 'header' !== $block['attrs']['slug'] ) {
|
|
return $block_content;
|
|
}
|
|
$before_post = '';
|
|
$snippets = $this->get_snippets_for_location( 'before_post' );
|
|
foreach ( $snippets as $snippet ) {
|
|
$before_post .= wpcode()->execute->get_snippet_output( $snippet );
|
|
}
|
|
|
|
return $block_content . $before_post;
|
|
}
|
|
|
|
/**
|
|
* Insert snippet output after the content.
|
|
*
|
|
* @param string $content The content of the post.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function insert_after_content( $content ) {
|
|
$snippets = $this->get_snippets_for_location( 'after_content' );
|
|
foreach ( $snippets as $snippet ) {
|
|
$content .= wpcode()->execute->get_snippet_output( $snippet );
|
|
}
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Insert snippet after the post
|
|
*
|
|
* @param string $content The post content.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function insert_after_post( $content ) {
|
|
$snippets = $this->get_snippets_for_location( 'after_post' );
|
|
foreach ( $snippets as $snippet ) {
|
|
$content .= wpcode()->execute->get_snippet_output( $snippet );
|
|
}
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Insert snippets before the content.
|
|
*
|
|
* @param string $content The post content.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function insert_before_content( $content ) {
|
|
$snippets = $this->get_snippets_for_location( 'before_content' );
|
|
$snippets_output = '';
|
|
foreach ( $snippets as $snippet ) {
|
|
$snippets_output .= wpcode()->execute->get_snippet_output( $snippet );
|
|
}
|
|
|
|
return $snippets_output . $content;
|
|
}
|
|
|
|
/**
|
|
* Insert content before or after paragraphs based on settings.
|
|
*
|
|
* @param string $content The post content.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function insert_after_before_paragraph( $content ) {
|
|
|
|
$snippets = $this->get_snippets_for_location( 'before_paragraph' );
|
|
foreach ( $snippets as $snippet ) {
|
|
$auto_insert_number = $snippet->get_auto_insert_number();
|
|
$auto_insert_number = empty( $auto_insert_number ) ? 1 : absint( $auto_insert_number );
|
|
$snippet_output = wpcode()->execute->get_snippet_output( $snippet );
|
|
$content = $this->insert_between_paragraphs( $snippet_output, $auto_insert_number, $content, 'before' );
|
|
}
|
|
|
|
$snippets = $this->get_snippets_for_location( 'after_paragraph' );
|
|
foreach ( $snippets as $snippet ) {
|
|
$auto_insert_number = $snippet->get_auto_insert_number();
|
|
$auto_insert_number = empty( $auto_insert_number ) ? 1 : absint( $auto_insert_number );
|
|
$snippet_output = wpcode()->execute->get_snippet_output( $snippet );
|
|
$content = $this->insert_between_paragraphs( $snippet_output, $auto_insert_number, $content, 'after' );
|
|
}
|
|
|
|
return $content;
|
|
}
|
|
|
|
|
|
/**
|
|
* Insert snippet code before or after paragraphs in a post.
|
|
*
|
|
* @param string $content_to_insert The content to insert (snippet code output).
|
|
* @param int $p_number The paragraph number.
|
|
* @param string $content_to_add_to The content in which the content should be added.
|
|
* @param string $before_or_after Add it before or after the paragraph.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function insert_between_paragraphs( $content_to_insert, $p_number, $content_to_add_to, $before_or_after = 'after' ) {
|
|
if ( 'before' === $before_or_after ) {
|
|
preg_match_all( '/<p(.*?)>/', $content_to_add_to, $matches );
|
|
} else {
|
|
preg_match_all( '/<\/p>/', $content_to_add_to, $matches );
|
|
}
|
|
$paragraphs = $matches[0];
|
|
|
|
// We don't have enough paragraphs to add the snippet.
|
|
if ( count( $paragraphs ) < $p_number ) {
|
|
return $content_to_add_to;
|
|
}
|
|
|
|
$p_number = -- $p_number;
|
|
$offset = 0;
|
|
foreach ( $paragraphs as $p_index => $p ) {
|
|
$position = strpos( $content_to_add_to, $p, $offset );
|
|
if ( $p_index === $p_number ) {
|
|
if ( 'before' === $before_or_after ) {
|
|
$content_to_add_to = substr( $content_to_add_to, 0, $position ) . $content_to_insert . substr( $content_to_add_to, $position );
|
|
} else {
|
|
$content_to_add_to = substr( $content_to_add_to, 0, $position + 4 ) . $content_to_insert . substr( $content_to_add_to, $position + 4 );
|
|
}
|
|
break;
|
|
} else {
|
|
$offset = $position + 1;
|
|
}
|
|
}
|
|
|
|
return $content_to_add_to;
|
|
}
|
|
}
|
|
|
|
new WPCode_Auto_Insert_Single();
|