- WordPress core y plugins - Tema Twenty Twenty-Four configurado - Plugin allow-unfiltered-html.php simplificado - .gitignore configurado para excluir wp-config.php y uploads 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
803 lines
22 KiB
PHP
Executable File
803 lines
22 KiB
PHP
Executable File
<?php
|
||
// phpcs:ignoreFile
|
||
|
||
/**
|
||
* Advanced Ads.
|
||
*
|
||
* @package AdvancedAds
|
||
* @author Thomas Maier <support@wpadvancedads.com>
|
||
* @license GPL-2.0+
|
||
* @link https://wpadvancedads.com
|
||
* @copyright 2013-2018 Thomas Maier, Advanced Ads GmbH
|
||
*/
|
||
|
||
use AdvancedAds\Constants;
|
||
use AdvancedAds\Abstracts\Ad;
|
||
use AdvancedAds\Abstracts\Group;
|
||
use AdvancedAds\Framework\Utilities\Params;
|
||
use AdvancedAds\Utilities\WordPress;
|
||
use AdvancedAds\Utilities\Conditional;
|
||
use AdvancedAds\Installation\Capabilities;
|
||
|
||
/**
|
||
* Plugin class. This class should ideally be used to work with the
|
||
* public-facing side of the WordPress site.
|
||
*
|
||
* @package Advanced_Ads
|
||
* @author Thomas Maier <support@wpadvancedads.com>
|
||
*/
|
||
class Advanced_Ads {
|
||
|
||
/**
|
||
* Instance of this class.
|
||
*
|
||
* @var object
|
||
*/
|
||
private static $instance = null;
|
||
|
||
/**
|
||
* Ad types
|
||
*
|
||
* @deprecated 1.48.2
|
||
*
|
||
* @var array Ad types
|
||
*/
|
||
public $ad_types = [];
|
||
|
||
/**
|
||
* Plugin options
|
||
*
|
||
* @var array $options
|
||
*/
|
||
protected $options;
|
||
|
||
/**
|
||
* Interal plugin options – set by the plugin
|
||
*
|
||
* @var array $internal_options
|
||
*/
|
||
protected $internal_options;
|
||
|
||
/**
|
||
* Adblocker Plugin options
|
||
*
|
||
* @var array (if loaded)
|
||
*/
|
||
protected $adblocker_options = null;
|
||
|
||
/**
|
||
* Whether the loop started in an inner `the_content`.
|
||
*
|
||
* @var bool
|
||
*/
|
||
protected $was_in_the_loop = false;
|
||
|
||
/**
|
||
* Signifies Whether the loop has started and the caller is in the loop.
|
||
*
|
||
* We need it because Some the "Divi" theme calls the `loop_start/loop_end` hooks
|
||
* instead of calling `the_post()` to signify that the caller is in the loop.
|
||
*
|
||
* @var bool
|
||
*/
|
||
protected $in_the_loop = false;
|
||
|
||
/**
|
||
* Is the query the main query?, when WP_Query is used
|
||
*
|
||
* @var bool
|
||
*/
|
||
private $is_main_query;
|
||
|
||
/**
|
||
* Save number of ads
|
||
*
|
||
* @var array
|
||
*/
|
||
private $number_of_ads = [];
|
||
|
||
/**
|
||
* Initialize frontend features
|
||
*/
|
||
private function __construct() {
|
||
add_action( 'plugins_loaded', [ $this, 'wp_plugins_loaded' ] );
|
||
|
||
// allow add-ons to interact.
|
||
add_action( 'init', [ $this, 'advanced_ads_loaded' ], 9 );
|
||
|
||
add_filter( 'the_content', [ $this, 'set_was_in_the_loop' ], ~PHP_INT_MAX );
|
||
}
|
||
|
||
/**
|
||
* Return an instance of this class.
|
||
*
|
||
* @return Advanced_Ads A single instance of this class.
|
||
*/
|
||
public static function get_instance() {
|
||
|
||
// if the single instance hasn't been set, set it now.
|
||
if ( null === self::$instance ) {
|
||
self::$instance = new self();
|
||
}
|
||
|
||
return self::$instance;
|
||
}
|
||
|
||
/**
|
||
* Initialize the plugin by setting localization and loading public scripts
|
||
* and styles.
|
||
*/
|
||
public function wp_plugins_loaded() {
|
||
// register hooks and filters for auto ad injection.
|
||
$this->init_injection();
|
||
|
||
// add meta robots noindex, nofollow to images, which are part of 'Image ad' ad type.
|
||
add_action( 'wp_head', [ $this, 'noindex_attachment_images' ] );
|
||
|
||
// use custom CSS or other custom header code.
|
||
add_action( 'wp_head', [ $this, 'custom_header_code' ] );
|
||
|
||
// check if ads are disabled in secondary queries.
|
||
add_action( 'the_post', [ $this, 'set_query_type' ], 10, 2 );
|
||
add_action( 'loop_start', [ $this, 'set_loop_start' ], 10, 0 );
|
||
add_action( 'loop_end', [ $this, 'set_loop_end' ], 10, 0 );
|
||
add_action( 'transition_post_status', [ $this, 'transition_ad_status' ], 10, 3 );
|
||
|
||
// register debug parameter
|
||
$this->debug_parameter();
|
||
|
||
Advanced_Ads_Display_Conditions::get_instance();
|
||
( new Advanced_Ads_Frontend_Checks() );
|
||
Advanced_Ads_Ad_Health_Notices::get_instance();
|
||
}
|
||
|
||
/**
|
||
* Allow add-ons to hook
|
||
*/
|
||
public function advanced_ads_loaded() {
|
||
do_action( 'advanced-ads-plugin-loaded' );
|
||
}
|
||
|
||
/**
|
||
* Load filters to inject ads into various sections of our site
|
||
*/
|
||
public function init_injection() {
|
||
add_filter( 'the_content', [ $this, 'inject_content' ], $this->get_content_injection_priority() );
|
||
}
|
||
|
||
/**
|
||
* Log error messages when debug is enabled
|
||
*
|
||
* @param string $message error message.
|
||
* @link http://www.smashingmagazine.com/2011/03/08/ten-things-every-wordpress-plugin-developer-should-know/
|
||
*/
|
||
public static function log( $message ) {
|
||
if ( true === WP_DEBUG ) {
|
||
if ( is_array( $message ) || is_object( $message ) ) {
|
||
error_log( __( 'Advanced Ads Error following:', 'advanced-ads' ) );
|
||
error_log( print_r( $message, true ) );
|
||
} else {
|
||
/* translators: %s is an error message generated by the plugin. */
|
||
$message = sprintf( __( 'Advanced Ads Error: %s', 'advanced-ads' ), $message );
|
||
error_log( $message );
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Compat method
|
||
*
|
||
* @return array with plugin options
|
||
*/
|
||
public function options() {
|
||
// we can’t store options if WPML String Translations is enabled, or it would not translate the "Ad Label" option.
|
||
if ( ! isset( $this->options ) || class_exists( 'WPML_ST_String' ) ) {
|
||
$this->options = get_option( ADVADS_SLUG, [] );
|
||
}
|
||
|
||
// allow to change options dynamically
|
||
$this->options = apply_filters( 'advanced-ads-options', $this->options );
|
||
|
||
return $this->options;
|
||
}
|
||
|
||
/**
|
||
* Compat method
|
||
*
|
||
* @return array with adblocker options
|
||
*/
|
||
public function get_adblocker_options() {
|
||
// we can’t store options if WPML String Translations is enabled, or it would not translate the "Ad Label" option.
|
||
if ( ! isset( $this->adblocker_options ) || class_exists( 'WPML_ST_String' ) ) {
|
||
$this->adblocker_options = wp_parse_args(
|
||
get_option( ADVADS_SETTINGS_ADBLOCKER, [] ),
|
||
[
|
||
'method' => false,
|
||
]
|
||
);
|
||
}
|
||
|
||
return $this->adblocker_options;
|
||
}
|
||
|
||
/**
|
||
* Compat method
|
||
*
|
||
* @return array with internal plugin options
|
||
*/
|
||
public function internal_options() {
|
||
if ( ! isset( $this->internal_options ) ) {
|
||
$defaults = [
|
||
'version' => ADVADS_VERSION,
|
||
'installed' => time(), // when was this installed.
|
||
];
|
||
$this->internal_options = get_option( ADVADS_SLUG . '-internal', [] );
|
||
|
||
// save defaults.
|
||
if ( [] === $this->internal_options ) {
|
||
$this->internal_options = $defaults;
|
||
$this->update_internal_options( $this->internal_options );
|
||
|
||
( new Capabilities() )->create_capabilities();
|
||
}
|
||
|
||
// for versions installed prior to 1.5.3 set installed date for now.
|
||
if ( ! isset( $this->internal_options['installed'] ) ) {
|
||
$this->internal_options['installed'] = time();
|
||
$this->update_internal_options( $this->internal_options );
|
||
}
|
||
}
|
||
|
||
return $this->internal_options;
|
||
}
|
||
|
||
/**
|
||
* Injected ad into content (before and after)
|
||
* Displays ALL ads
|
||
*
|
||
* @param string $content post content.
|
||
*
|
||
* @return string
|
||
*/
|
||
public function inject_content( $content = '' ) {
|
||
$options = $this->options();
|
||
|
||
// do not inject in content when on a BuddyPress profile upload page (avatar & cover image).
|
||
if ( ( function_exists( 'bp_is_user_change_avatar' ) && \bp_is_user_change_avatar() ) || ( function_exists( 'bp_is_user_change_cover_image' ) && bp_is_user_change_cover_image() ) ) {
|
||
return $content;
|
||
}
|
||
|
||
// do not inject ads multiple times, e.g., when the_content is applied multiple times.
|
||
if ( $this->has_many_the_content() ) {
|
||
return $content;
|
||
}
|
||
|
||
|
||
// Check if ads are disabled in secondary queries.
|
||
if ( ! empty( $options['disabled-ads']['secondary'] ) ) {
|
||
// this function was called by ajax (in secondary query).
|
||
if ( wp_doing_ajax() ) {
|
||
return $content;
|
||
}
|
||
// get out of wp_router_page post type if ads are disabled in secondary queries.
|
||
if ( 'wp_router_page' === get_post_type() ) {
|
||
return $content;
|
||
}
|
||
}
|
||
|
||
// No need to inject ads because all tags are stripped from excepts.
|
||
if ( doing_filter( 'get_the_excerpt' ) ) {
|
||
return $content;
|
||
}
|
||
|
||
// make sure that no ad is injected into another ad.
|
||
if ( get_post_type() === Constants::POST_TYPE_AD ) {
|
||
return $content;
|
||
}
|
||
|
||
// Do not inject on admin pages.
|
||
if ( is_admin() && ! wp_doing_ajax() ) {
|
||
return $content;
|
||
}
|
||
|
||
// Do not inject in writing REST requests.
|
||
if ( Conditional::is_gutenberg_writing_request() && Conditional::is_rest_request() ) {
|
||
return $content;
|
||
}
|
||
|
||
if ( ! $this->can_inject_into_content() ) {
|
||
return $content;
|
||
}
|
||
|
||
$placements = wp_advads_get_all_placements();
|
||
|
||
if ( ! apply_filters( 'advanced-ads-can-inject-into-content', true, $content, $placements ) ) {
|
||
return $content;
|
||
}
|
||
|
||
foreach ( $placements as $placement_id => $placement ) {
|
||
$item = $placement->get_item();
|
||
$type_object_id = $placement->get_type_object()->get_id();
|
||
|
||
if (
|
||
empty( $item )
|
||
|| 'default' === $type_object_id
|
||
|| ! apply_filters( 'advanced-ads-can-inject-into-content-' . $placement_id, true, $content, $placement )
|
||
) {
|
||
continue;
|
||
}
|
||
|
||
$placement_options = $placement->get_data();
|
||
|
||
switch ( $type_object_id ) {
|
||
case 'post_top':
|
||
$placement_content = get_the_placement(
|
||
$placement_id,
|
||
'',
|
||
$placement_options
|
||
);
|
||
$content = $placement_content . $content;
|
||
break;
|
||
case 'post_bottom':
|
||
$content .= get_the_placement(
|
||
$placement_id,
|
||
'',
|
||
$placement_options
|
||
);
|
||
break;
|
||
case 'post_content':
|
||
$content = Advanced_Ads_In_Content_Injector::inject_in_content( $placement_id, $placement_options, $content );
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( ! empty( Params::cookie( 'advads_frontend_picker' ) ) ) {
|
||
// Make possible to know where the content starts and ends.
|
||
$content = '<ins style="display: none;" class="advads-frontend-picker-boundary-helper"></ins>
|
||
' . $content;
|
||
}
|
||
|
||
return $content;
|
||
}
|
||
|
||
/**
|
||
* Whether injection using `the_content` is allowed
|
||
*
|
||
* @return bool
|
||
*/
|
||
private function can_inject_into_content() {
|
||
global $wp_query;
|
||
|
||
if ( is_feed() || Conditional::is_rest_request() ) {
|
||
return true;
|
||
}
|
||
|
||
$options = $this->options();
|
||
|
||
/**
|
||
* Allows experienced user to control up to the nth post ads will be injected via post content placement in a post list.
|
||
*
|
||
* Post displaying an excerpt instead of the full content will still be skipped (mainly controlled by the active theme).
|
||
*
|
||
* @param int|string $archive_injection_count the string "true" when ads is injected into all posts.
|
||
*/
|
||
$archive_injection_count = apply_filters( 'advanced-ads-content-injection-index', $options['content-injection-everywhere'] ?? 1 );
|
||
|
||
// Run only within the loop on single pages of public post types.
|
||
$public_post_types = get_post_types(
|
||
[
|
||
'public' => true,
|
||
'publicly_queryable' => true,
|
||
],
|
||
'names',
|
||
'or'
|
||
);
|
||
|
||
// Check if admin allows injection in all places.
|
||
$injection_enabled = $options['content-injection-enabled'] ?? 'off';
|
||
|
||
if ( ( $injection_enabled === 'off' || 0 === $archive_injection_count ) && ( ! is_singular( $public_post_types ) || ( ! Conditional::is_amp() && ! $this->in_the_loop() && ! $this->was_in_the_loop ) ) ) {
|
||
return false;
|
||
}
|
||
|
||
if ( is_main_query() && ! empty( $options ) && 'true' !== $archive_injection_count && isset( $wp_query->current_post ) && $wp_query->current_post >= $archive_injection_count ) {
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* General check if ads can be displayed for the whole page impression
|
||
*
|
||
* @return bool true, if ads can be displayed.
|
||
* @todo move this to set_disabled_constant().
|
||
*/
|
||
public function can_display_ads() {
|
||
$options = $this->options();
|
||
|
||
/**
|
||
* Check if ads are disabled on the currently displayed page. Allow user to define their own rules if needed.
|
||
*
|
||
* @param bool $ads_disabled whether ads are disabled by the plugin options.
|
||
* @param array $options plugin options.
|
||
*
|
||
* @return bool `true` if ads are disabled
|
||
*/
|
||
$ads_disabled = apply_filters( 'advanced-ads-disabled-ads', Conditional::is_ad_disabled(), $options );
|
||
|
||
if ( $ads_disabled ) {
|
||
return false;
|
||
}
|
||
|
||
|
||
// check if ads are disabled in secondary queries.
|
||
// and this is not main query and this is not ajax (because main query does not exist in ajax but ad needs to be shown).
|
||
if ( ! empty( $options['disabled-ads']['secondary'] ) && ! $this->is_main_query() && ! wp_doing_ajax() ) {
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Add meta robots noindex, nofollow to images, which are part of 'Image ad' ad type
|
||
*/
|
||
public function noindex_attachment_images() {
|
||
global $post;
|
||
|
||
if ( is_attachment() && is_object( $post ) && isset( $post->post_parent ) ) {
|
||
$post_parent = get_post( $post->post_parent );
|
||
$parent_is_ad = $post_parent && Constants::POST_TYPE_AD === $post_parent->post_type;
|
||
// if the image was not attached to any post and if at least one image ad contains the image. Needed for backward compatibility.
|
||
$parent_is_image_ad = ( empty( $post->post_parent ) && 0 < get_post_meta( get_the_ID(), '_advanced-ads_parent_id', true ) );
|
||
|
||
if ( $parent_is_ad || $parent_is_image_ad ) {
|
||
echo '<meta name="robots" content="noindex,nofollow" />';
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Show custom CSS in the header
|
||
*/
|
||
public function custom_header_code(){
|
||
if ( ! defined( 'ADVANCED_ADS_DISABLE_EDIT_BAR' ) && Conditional::user_can( 'advanced_ads_edit_ads' ) ) {
|
||
?><style>
|
||
div.advads-edit-bar{position:absolute;height:0;display:none;z-index:10000;animation:advads-edit-appear 2s linear 1;}
|
||
@keyframes advads-edit-appear {
|
||
0% {opacity: 0.0;pointer-events: none;}
|
||
66% {opacity: 0.0;}
|
||
100% {opacity: 1.0;}
|
||
}
|
||
a.advads-edit-button{position:absolute;top:0;left:0;text-decoration:none !important;box-shadow:none;border-bottom:none;color:#0074a2;margin-top:-5px;}
|
||
a.advads-edit-button span{top:10px;line-height:25px;margin-left:-5px;width:26px;height:26px;border-radius:13px;border:solid 1px #0074a2;background:#fff}
|
||
<?php
|
||
printf(
|
||
'div[class^="%s"]:hover > div.advads-edit-bar {display: inline-block; vertical-align: top;}',
|
||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||
wp_advads()->get_frontend_prefix()
|
||
);
|
||
?>
|
||
</style>
|
||
<?php
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Supports the "$this->is_main_query=true" while main query is being executed
|
||
*
|
||
* @param WP_Post $post The Post object (passed by reference).
|
||
* @param WP_Query $query The current Query object (passed by reference).
|
||
*/
|
||
public function set_query_type( $post, $query = null ) {
|
||
if ( $query instanceof WP_Query ) {
|
||
$this->is_main_query = $query->is_main_query();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check if main query is being executed
|
||
*
|
||
* @return bool true while main query is being executed or not in the loop, false otherwise
|
||
*/
|
||
public function is_main_query() {
|
||
if ( ! $this->in_the_loop() ) {
|
||
// the secondary query check only designed for within post content.
|
||
return true;
|
||
}
|
||
|
||
return true === $this->is_main_query;
|
||
}
|
||
|
||
/**
|
||
* Sets whether the loop has started.
|
||
*/
|
||
public function set_loop_start() {
|
||
$this->in_the_loop = true;
|
||
}
|
||
|
||
/**
|
||
* Sets whether the loop has ended.
|
||
*/
|
||
public function set_loop_end() {
|
||
$this->in_the_loop = false;
|
||
}
|
||
|
||
|
||
/**
|
||
* Whether the loop has started and the caller is in the loop.
|
||
*
|
||
* @return bool
|
||
*/
|
||
public function in_the_loop() {
|
||
if ( in_the_loop() ) {
|
||
return true;
|
||
}
|
||
|
||
if ( $this->in_the_loop ) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Find the calls to `the_content` inside functions hooked to `the_content`.
|
||
*
|
||
* @return bool
|
||
*/
|
||
public function has_many_the_content() {
|
||
global $wp_current_filter;
|
||
if ( count( array_keys( $wp_current_filter, 'the_content', true ) ) > 1 ) {
|
||
// More then one `the_content` in the stack.
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Get an "Advertisement" label to use before single ad or before first ad in a group
|
||
*
|
||
* @param Ad|Group $item Ad or group.
|
||
* @param string $placement_state default/enabled/disabled.
|
||
*
|
||
* @return string label, empty string if label should not be displayed.
|
||
*/
|
||
public function get_label( $item, $placement_state = 'default' ) {
|
||
if ( 'disabled' === $placement_state ) {
|
||
return '';
|
||
}
|
||
|
||
$advads_options = self::get_instance()->options();
|
||
|
||
if ( 'enabled' !== $placement_state && empty( $advads_options['custom-label']['enabled'] ) ) {
|
||
return '';
|
||
}
|
||
|
||
$label = $advads_options['custom-label']['text'] ?? _x( 'Advertisements', 'label above ads', 'advanced-ads' );
|
||
$allowed_tags = [
|
||
'a' => [
|
||
'href' => true,
|
||
'title' => true,
|
||
],
|
||
'b' => [],
|
||
'blockquote' => [
|
||
'cite' => true,
|
||
],
|
||
'cite' => [],
|
||
'code' => [],
|
||
'del' => [
|
||
'datetime' => true,
|
||
],
|
||
'em' => [],
|
||
'i' => [],
|
||
'q' => [
|
||
'cite' => true,
|
||
],
|
||
's' => [],
|
||
'span' => [
|
||
'style' => true,
|
||
],
|
||
'strike' => [],
|
||
'br' => [],
|
||
'strong' => [],
|
||
];
|
||
|
||
// ad level label
|
||
if ( ! empty( $item->get_prop( 'ad_label' ) ) ) {
|
||
$label = $item->get_prop( 'ad_label' );
|
||
}
|
||
|
||
$label = ! empty( $advads_options['custom-label']['html_enabled'] ) ? wp_kses( $label, $allowed_tags ) : esc_html( $label );
|
||
$template = sprintf( '<div class="%s">%s</div>', wp_advads()->get_frontend_prefix() . 'adlabel', $label );
|
||
|
||
return apply_filters( 'advanced-ads-custom-label', $template, $label );
|
||
}
|
||
|
||
/**
|
||
* Retrieve the number of ads in any status
|
||
* excludes trash status by default
|
||
*
|
||
* @deprecated 1.48.2
|
||
*
|
||
* @param string|array $post_status default post status.
|
||
*
|
||
* @return int number of ads.
|
||
*/
|
||
public static function get_number_of_ads( $post_status = 'any' ) {
|
||
_deprecated_function( __METHOD__, '1.48.0', 'AdvancedAds\Utilities\WordPress::get_count_ads()' );
|
||
|
||
return WordPress::get_count_ads( $post_status );
|
||
}
|
||
|
||
/**
|
||
* Get the array with ad placements
|
||
*
|
||
* @deprecated 2.0.0 wp_advads_get_all_placements
|
||
*
|
||
* @return array $ad_placements
|
||
*/
|
||
public static function get_ad_placements_array() {
|
||
return wp_advads_get_all_placements();
|
||
}
|
||
|
||
/**
|
||
* Return the Advanced_Ads_Model responsible for loading ads, groups and placements into the frontend
|
||
*
|
||
* @deprecated 2.0.0 use new entity functions.
|
||
*
|
||
* @return mixed
|
||
*/
|
||
public function get_model() {
|
||
if ( ! isset( $this->model ) ) {
|
||
$this->model = new Advanced_Ads_Model();
|
||
}
|
||
|
||
return $this->model;
|
||
}
|
||
|
||
/**
|
||
* Store whether the loop started in an inner `the_content`.
|
||
*
|
||
* If so, let us assume that we are in the loop when we are in the outermost `the_content`.
|
||
* Makes sense only when a hooked to `the_content` function that produces an inner `the_content` has
|
||
* lesser priority then `$this->plugin->get_content_injection_priority()`.
|
||
*
|
||
* @param string $content Post content (unchanged).
|
||
*
|
||
* @return string
|
||
*/
|
||
public function set_was_in_the_loop( $content ) {
|
||
if ( self::get_instance()->has_many_the_content() ) {
|
||
$this->was_in_the_loop = $this->was_in_the_loop || $this->in_the_loop();
|
||
} else {
|
||
// Next top level `the_content`, forget that the loop started.
|
||
$this->was_in_the_loop = false;
|
||
}
|
||
|
||
return $content;
|
||
}
|
||
|
||
/**
|
||
* Listen to URL parameters for debugging
|
||
*/
|
||
private function debug_parameter() {
|
||
$referer = Params::server( 'HTTP_REFERER' );
|
||
if ( wp_doing_ajax() && $referer ) {
|
||
$query_string = wp_parse_url( $referer, PHP_URL_QUERY );
|
||
if ( $query_string ) {
|
||
parse_str( $query_string, $query );
|
||
}
|
||
|
||
if ( empty( $query['aa-debug'] ) ) {
|
||
return;
|
||
}
|
||
|
||
$debug_query = $query['aa-debug'];
|
||
} else {
|
||
$debug_query = Params::get( 'aa-debug' );
|
||
if ( empty( $debug_query ) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
$parameters = explode( ',', sanitize_text_field( $debug_query ) );
|
||
foreach ( $parameters as $parameter ) {
|
||
switch ( trim( $parameter ) ) {
|
||
case 'dummy':
|
||
// switch all ads to "dummy"
|
||
add_filter( 'advanced-ads-ad-option-type', function() {
|
||
return 'dummy';
|
||
} );
|
||
break;
|
||
case 'vcoff':
|
||
// disable ad visitor conditions
|
||
add_filter( 'advanced-ads-ad-option-visitors', '__return_empty_array' );
|
||
break;
|
||
case 'cboff':
|
||
// disable cache-busting for all ads
|
||
add_filter( 'advanced-ads-ad-select-args', function( $args ) {
|
||
$args['cache-busting'] = 'ignore';
|
||
return $args;
|
||
} );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get priority used for injection inside content
|
||
*/
|
||
public function get_content_injection_priority() {
|
||
$options = $this->options();
|
||
|
||
return isset( $options['content-injection-priority'] ) ? (int) $options['content-injection-priority'] : 100;
|
||
}
|
||
|
||
/**
|
||
* Update internal plugin options
|
||
*
|
||
* @param array $options new internal options.
|
||
*/
|
||
public function update_internal_options( array $options ) {
|
||
// do not allow to clear options.
|
||
if ( [] === $options ) {
|
||
return;
|
||
}
|
||
|
||
$this->internal_options = $options;
|
||
update_option( ADVADS_SLUG . '-internal', $options );
|
||
}
|
||
|
||
/**
|
||
* Fires when a post is transitioned from one status to another.
|
||
*
|
||
* @param string $new_status New post status.
|
||
* @param string $old_status Old post status.
|
||
* @param WP_Post $post Post object.
|
||
*/
|
||
public function transition_ad_status( $new_status, $old_status, $post ) {
|
||
if ( ! isset( $post->post_type ) || Constants::POST_TYPE_AD !== $post->post_type || ! isset( $post->ID ) ) {
|
||
return;
|
||
}
|
||
|
||
$ad = wp_advads_get_ad( $post->ID );
|
||
|
||
if ( $old_status !== $new_status ) {
|
||
/**
|
||
* Fires when an ad has transitioned from one status to another.
|
||
*
|
||
* @param Ad $ad Ad object.
|
||
*/
|
||
do_action( "advanced-ads-ad-status-{$old_status}-to-{$new_status}", $ad );
|
||
}
|
||
|
||
if ( 'publish' === $new_status && 'publish' !== $old_status ) {
|
||
/**
|
||
* Fires when an ad has transitioned from any other status to `publish`.
|
||
*
|
||
* @param Ad $ad Ad object.
|
||
*/
|
||
do_action( 'advanced-ads-ad-status-published', $ad );
|
||
}
|
||
|
||
if ( 'publish' === $old_status && 'publish' !== $new_status ) {
|
||
/**
|
||
* Fires when an ad has transitioned from `publish` to any other status.
|
||
*
|
||
* @param Ad $ad Ad object.
|
||
*/
|
||
do_action( 'advanced-ads-ad-status-unpublished', $ad );
|
||
}
|
||
|
||
if ( $old_status === 'publish' && $new_status === Constants::AD_STATUS_EXPIRED ) {
|
||
/**
|
||
* Fires when an ad is expired.
|
||
*
|
||
* @param int $id
|
||
* @param Ad $ad
|
||
*/
|
||
do_action( 'advanced-ads-ad-expired', $ad->get_id(), $ad );
|
||
}
|
||
}
|
||
}
|