oont-contents/plugins/insert-headers-and-footers/includes/auto-insert/class-wpcode-auto-insert-single.php
2025-02-08 15:10:23 +01:00

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();