*/ // Prevent direct access via ABSPATH check if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly // If this file is called directly, abort. if ( ! defined( 'WPINC' ) ) { die; } class Adcaver_Helper_Frontend { /** * Stores the Site ID for use in the script tag filter and shortcodes. * @var int */ private $site_id = 0; /** * Flag to check if the main ad server script has been enqueued. * @var bool */ private $ad_server_script_enqueued = false; /** * Stores the plugin options to avoid multiple get_option calls. * @var array */ private $options = array(); /** * Constructor: Stores options. * @since 1.0.1 */ public function __construct() { $this->options = get_option( ADCAVER_HELPER_OPTION_NAME, array() ); $this->site_id = isset( $this->options['site_id'] ) ? absint( $this->options['site_id'] ) : 0; } /** * Outputs the Adcaver verification meta tag in the
if a code is saved. * * Only outputs on the front page (homepage). * * @since 1.0.0 */ public function output_verification_meta_tag() { if ( ! is_front_page() || ! is_singular() ) { return; } $verification_code = isset( $this->options['verification_code'] ) ? trim( $this->options['verification_code'] ) : ''; if ( ! empty( $verification_code ) && strlen( $verification_code ) > 10 ) { $sanitized_code = sanitize_text_field( $verification_code ); echo '' . "\n"; } } /** * Conditionally enqueues overlay ad scripts and the main ad server script. * * @since 1.0.0 */ public function enqueue_frontend_scripts() { if ( is_admin() || is_customize_preview() ) { return; } if ( empty( $this->site_id ) ) { return; } $adcaver_server_url = rtrim( ADCAVER_SERVER_URL, '/' ) . '/'; $script_base_url = $adcaver_server_url . 'wp-content/plugins/zeal-ad-manager/public/'; $overlay_scripts_enqueued = false; if ( ! empty( $this->options['enable_vignette'] ) ) { $script_url = $script_base_url . 'zealup-vignette.js'; wp_enqueue_script( 'adcaver-vignette', $script_url, array(), ADCAVER_HELPER_VERSION, true ); $overlay_scripts_enqueued = true; } if ( ! empty( $this->options['enable_anchor'] ) ) { $script_url = $script_base_url . 'zealup-anchor.js'; wp_enqueue_script( 'adcaver-anchor', $script_url, array(), ADCAVER_HELPER_VERSION, true ); $overlay_scripts_enqueued = true; } if ( ! empty( $this->options['enable_sticky_bar'] ) ) { $script_url = $script_base_url . 'zealup-sticky-bar.js'; wp_enqueue_script( 'adcaver-sticky-bar', $script_url, array(), ADCAVER_HELPER_VERSION, true ); $overlay_scripts_enqueued = true; } if ( $overlay_scripts_enqueued ) { add_filter( 'script_loader_tag', array( $this, 'add_script_attributes' ), 10, 3 ); } $auto_placements_enabled = $this->check_if_auto_placements_enabled(); if ( $overlay_scripts_enqueued || $auto_placements_enabled ) { $this->maybe_enqueue_ad_server_script(); } } /** * Adds async and data-site-id attributes to the overlay ad script tags. * * @since 1.0.1 * @param string $tag The HTML script tag. * @param string $handle The script handle. * @param string $src The script source URL. * @return string Modified HTML script tag. */ public function add_script_attributes( $tag, $handle, $src ) { $overlay_handles = array( 'adcaver-vignette', 'adcaver-anchor', 'adcaver-sticky-bar' ); if ( in_array( $handle, $overlay_handles, true ) && ! empty( $this->site_id ) ) { if ( strpos( $tag, ' async' ) === false ) { $tag = str_replace( ' src=', ' async src=', $tag ); } if ( strpos( $tag, ' data-site-id=' ) === false ) { $tag = str_replace( ' src=', ' data-site-id="' . esc_attr( $this->site_id ) . '" src=', $tag ); } } return $tag; } /** * Enqueues the main ad server script if it hasn't been already. * * @since 1.0.1 */ private function maybe_enqueue_ad_server_script() { if ( ! $this->ad_server_script_enqueued && ! empty( $this->site_id ) ) { $adcaver_server_url = rtrim( ADCAVER_SERVER_URL, '/' ) . '/'; $script_url = $adcaver_server_url . 'wp-content/plugins/zeal-ad-manager/public/zam-ad-server.js'; wp_enqueue_script( 'adcaver-ad-server', $script_url, array(), ADCAVER_HELPER_VERSION, true ); wp_script_add_data( 'adcaver-ad-server', 'async', true ); $this->ad_server_script_enqueued = true; } } /** * Checks if any auto-placement settings are enabled. * * @since 1.0.1 * @return bool True if any auto-placement is enabled, false otherwise. */ private function check_if_auto_placements_enabled() { $all_placement_keys = array( 'auto_ad_posts_before_content', 'auto_ad_posts_after_p1', 'auto_ad_posts_after_p2', 'auto_ad_posts_after_p3', 'auto_ad_posts_mid_content', 'auto_ad_posts_after_content', 'auto_ad_pages_before_content', 'auto_ad_pages_after_content', 'auto_ad_homepage_before_content', 'auto_ad_homepage_after_content', ); foreach ( $all_placement_keys as $key ) { if ( ! empty( $this->options[ $key ] ) && 'disabled' !== $this->options[ $key ] ) { return true; } } return false; } /** * Filters the post content to automatically insert ad placeholders based on settings. * * @since 1.0.1 * @param string $content The original post content. * @return string The modified post content with ads inserted. */ public function auto_insert_ads_in_content( $content ) { if ( ! is_singular() || ! is_main_query() || empty( $this->site_id ) ) { return $content; } if ( is_feed() || is_admin() || doing_filter( 'get_the_excerpt' ) ) { return $content; } if ( is_front_page() ) { return $this->process_homepage_ads( $content ); } if ( is_page() ) { return $this->process_page_ads( $content ); } if ( is_single() ) { return $this->process_post_ads( $content ); } return $content; } /** * Processes ad insertion for homepage content. * * @since 1.0.1 * @param string $content The original content. * @return string The modified content with ads inserted. */ private function process_homepage_ads( $content ) { $before_content_type = isset( $this->options['auto_ad_homepage_before_content'] ) ? $this->options['auto_ad_homepage_before_content'] : 'disabled'; $after_content_type = isset( $this->options['auto_ad_homepage_after_content'] ) ? $this->options['auto_ad_homepage_after_content'] : 'disabled'; if ( 'disabled' !== $before_content_type ) { $ad_html = $this->get_ad_html_for_type( $before_content_type, $this->site_id ); if ( $ad_html ) { $content = $ad_html . $content; $this->maybe_enqueue_ad_server_script(); } } if ( 'disabled' !== $after_content_type ) { $ad_html = $this->get_ad_html_for_type( $after_content_type, $this->site_id ); if ( $ad_html ) { $content .= $ad_html; $this->maybe_enqueue_ad_server_script(); } } return $content; } /** * Processes ad insertion for page content. * * @since 1.0.1 * @param string $content The original content. * @return string The modified content with ads inserted. */ private function process_page_ads( $content ) { $before_content_type = isset( $this->options['auto_ad_pages_before_content'] ) ? $this->options['auto_ad_pages_before_content'] : 'disabled'; $after_content_type = isset( $this->options['auto_ad_pages_after_content'] ) ? $this->options['auto_ad_pages_after_content'] : 'disabled'; if ( 'disabled' !== $before_content_type ) { $ad_html = $this->get_ad_html_for_type( $before_content_type, $this->site_id ); if ( $ad_html ) { $content = $ad_html . $content; $this->maybe_enqueue_ad_server_script(); } } if ( 'disabled' !== $after_content_type ) { $ad_html = $this->get_ad_html_for_type( $after_content_type, $this->site_id ); if ( $ad_html ) { $content .= $ad_html; $this->maybe_enqueue_ad_server_script(); } } return $content; } /** * Processes ad insertion for post content. * * @since 1.0.1 * @param string $content The original content. * @return string The modified content with ads inserted. */ private function process_post_ads( $content ) { $before_content_type = isset( $this->options['auto_ad_posts_before_content'] ) ? $this->options['auto_ad_posts_before_content'] : 'disabled'; $after_p1_type = isset( $this->options['auto_ad_posts_after_p1'] ) ? $this->options['auto_ad_posts_after_p1'] : 'disabled'; $after_p2_type = isset( $this->options['auto_ad_posts_after_p2'] ) ? $this->options['auto_ad_posts_after_p2'] : 'disabled'; $after_p3_type = isset( $this->options['auto_ad_posts_after_p3'] ) ? $this->options['auto_ad_posts_after_p3'] : 'disabled'; $mid_content_type = isset( $this->options['auto_ad_posts_mid_content'] ) ? $this->options['auto_ad_posts_mid_content'] : 'disabled'; $after_content_type = isset( $this->options['auto_ad_posts_after_content'] ) ? $this->options['auto_ad_posts_after_content'] : 'disabled'; if ( 'disabled' !== $before_content_type ) { $ad_html = $this->get_ad_html_for_type( $before_content_type, $this->site_id ); if ( $ad_html ) { $content = $ad_html . $content; $this->maybe_enqueue_ad_server_script(); } } $closing_p = ''; $paragraphs = explode( $closing_p, $content ); $paragraph_count = count( $paragraphs ); $ads_to_insert = array(); if ( 'disabled' !== $after_p1_type && $paragraph_count > 1 ) { $ad_html = $this->get_ad_html_for_type( $after_p1_type, $this->site_id ); if ( $ad_html ) { $ads_to_insert[0] = $ad_html; $this->maybe_enqueue_ad_server_script(); } } if ( 'disabled' !== $after_p2_type && $paragraph_count > 2 ) { $ad_html = $this->get_ad_html_for_type( $after_p2_type, $this->site_id ); if ( $ad_html ) { $ads_to_insert[1] = $ad_html; $this->maybe_enqueue_ad_server_script(); } } if ( 'disabled' !== $after_p3_type && $paragraph_count > 3 ) { $ad_html = $this->get_ad_html_for_type( $after_p3_type, $this->site_id ); if ( $ad_html ) { $ads_to_insert[2] = $ad_html; $this->maybe_enqueue_ad_server_script(); } } if ( 'disabled' !== $mid_content_type && $paragraph_count > 4 ) { $mid_point = floor( $paragraph_count / 2 ); $ad_html = $this->get_ad_html_for_type( $mid_content_type, $this->site_id ); if ( $ad_html ) { $ads_to_insert[$mid_point - 1] = $ad_html; $this->maybe_enqueue_ad_server_script(); } } if ( ! empty( $ads_to_insert ) ) { krsort( $ads_to_insert ); foreach ( $ads_to_insert as $position => $ad_html ) { if ( isset( $paragraphs[$position] ) ) { $paragraphs[$position] .= $closing_p . $ad_html; } } $content = implode( $closing_p, $paragraphs ); } if ( 'disabled' !== $after_content_type ) { $ad_html = $this->get_ad_html_for_type( $after_content_type, $this->site_id ); if ( $ad_html ) { $content .= $ad_html; $this->maybe_enqueue_ad_server_script(); } } return $content; } /** * Helper function to generate the ad unit HTML based on ad type. * * @since 1.0.1 * @param string $type Ad type ('spotlight', 'banner', 'story'). * @param int $site_id Publisher Site ID. * @return string|false Ad unit HTML or false if type is invalid. */ private function get_ad_html_for_type( $type, $site_id ) { $template = ''; switch ( $type ) { case 'spotlight': $template = 'spotlight'; break; case 'banner': $template = 'banner'; break; case 'story': $template = 'story'; break; default: return false; } if ( empty( $site_id ) ) { return false; } return sprintf( '', esc_attr( $site_id ), esc_attr( $template ) ); } }