Commit inicial - WordPress Análisis de Precios Unitarios

- 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>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

View File

@@ -0,0 +1,282 @@
<?php // phpcs:ignoreFile
use AdvancedAds\Abstracts\Ad;
use AdvancedAds\Constants;
use AdvancedAds\Framework\Utilities\Params;
use AdvancedAds\Utilities\Conditional;
/**
* Class Advanced_Ads_AdSense_Admin
*/
class Advanced_Ads_AdSense_Admin {
/**
* AdSense options.
*
* @var Advanced_Ads_AdSense_Data
*/
private $data;
/**
* Noncetodo: check if this is still used
* todo: check if this is still used
*
* @var string $nonce
*/
private $nonce;
/**
* Instance of Advanced_Ads_AdSense_Admin
*
* @var null
*/
private static $instance = null;
/**
* Notices
* todo: still used?
*
* @var null
*/
protected $notice = null;
/**
* Settings page hook
*
* @var string
*/
private $settings_page_hook = 'advanced-ads-adsense-settings-page';
const ADSENSE_NEW_ACCOUNT_LINK = 'https://www.google.com/adsense/start/?utm_source=AdvancedAdsPlugIn&utm_medium=partnerships&utm_campaign=AdvancedAdsPartner1';
/**
* Advanced_Ads_AdSense_Admin constructor.
*/
private function __construct() {
$this->data = Advanced_Ads_AdSense_Data::get_instance();
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
add_action( 'admin_print_scripts', [ $this, 'print_scripts' ] );
add_filter( 'advanced-ads-ad-notices', [ $this, 'ad_notices' ], 10, 2 );
add_action( 'advanced-ads-ad-pre-save', [ $this, 'save_ad_options' ], 10, 2 );
}
/**
* Save ad options.
*
* @param Ad $ad Ad instance.
* @param array $post_data Post data array.
*
* @return void
*/
public function save_ad_options( Ad $ad, $post_data ): void {
if ( ! $ad->is_type( 'adsense' ) ) {
return;
}
// Remove ad size options for responsive AdSense ads.
$content = json_decode( str_replace( "\n", '', wp_unslash( $post_data['content'] ) ), true );
if ( in_array( $content['unitType'] ?? 'none', [
'responsive',
'link',
'link-responsive',
'matched-content',
'in-article',
'in-feed',
], true )
) {
$ad->set_width( 0 );
$ad->set_height( 0 );
}
}
/**
* Load JavaScript needed on some pages.
*/
public function print_scripts() {
global $pagenow;
if ( $this->is_on_screen() ) {
$db = Advanced_Ads_AdSense_Data::get_instance();
$pub_id = $db->get_adsense_id();
?>
<script type="text/javascript">
if ( 'undefined' == typeof gadsenseData ) {
window.gadsenseData = {};
}
// todo: check why we are using echo here.
gadsenseData['pagenow'] = '<?php echo esc_attr( $pagenow ); ?>';
</script>
<?php
}
}
/**
* Add AdSense-related scripts.
*/
public function enqueue_scripts() {
if ( Conditional::is_screen_advanced_ads() ) {
self::enqueue_connect_adsense();
}
if ( $this->is_on_screen() ) {
$scripts = [];
// Allow modifications of script files to enqueue.
$scripts = apply_filters( 'advanced-ads-gadsense-ad-param-script', $scripts );
foreach ( $scripts as $handle => $value ) {
if ( empty( $handle ) ) {
continue;
}
if ( ! empty( $handle ) && empty( $value ) ) {
// Allow inclusion of WordPress's built-in script like jQuery.
wp_enqueue_script( $handle );
} else {
if ( ! isset( $value['version'] ) ) {
$value['version'] = null; }
wp_enqueue_script( $handle, $value['path'], $value['dep'], $value['version'] );
}
}
$styles = [];
// Allow modifications of default style files to enqueue.
$styles = apply_filters( 'advanced-ads-gadsense-ad-param-style', $styles );
foreach ( $styles as $handle => $value ) {
if ( ! isset( $value['path'] ) ||
! isset( $value['dep'] ) ||
empty( $handle )
) {
continue;
}
if ( ! isset( $value['version'] ) ) {
$value['version'] = null; }
wp_enqueue_style( $handle, $value['path'], $value['dep'], $value['version'] );
}
}
}
/**
* Get instance of Advanced_Ads_AdSense_Admin.
*
* @return Advanced_Ads_AdSense_Admin|null
*/
public static function get_instance() {
if ( null == self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Show AdSense ad specific notices in parameters box
*
* @param array $notices some notices to show in the parameters box.
* @param string $box ID of the meta box.
*/
public function ad_notices( $notices, $box ) {
switch ( $box['id'] ) {
case 'ad-parameters-box':
// Add warning if this is a responsive ad unit without custom sizes and position is set to left or right.
// Hidden by default and made visible with JS.
$notices[] = [
'text' => sprintf(
/* translators: %s is a URL. */
__( 'Responsive AdSense ads dont work reliably with <em>Position</em> set to left or right. Either switch the <em>Type</em> to "normal" or follow <a href="%s" target="_blank">this tutorial</a> if you want the ad to be wrapped in text.', 'advanced-ads' ),
'https://wpadvancedads.com/adsense-responsive-custom-sizes/?utm_source=advanced-ads&utm_medium=link&utm_campaign=adsense-custom-sizes-tutorial'
),
'class' => 'advads-ad-notice-responsive-position advads-notice-inline advads-error hidden',
];
// Show hint about AdSense In-feed add-on.
if ( ! class_exists( 'Advanced_Ads_In_Feed', false ) && ! class_exists( 'Advanced_Ads_Pro_Admin', false ) ) {
$notices[] = [
'text' => sprintf(
/* translators: %s is a URL. */
__( '<a href="%s" target="_blank">Install the free AdSense In-feed add-on</a> in order to place ads between posts.', 'advanced-ads' ),
wp_nonce_url(
self_admin_url( 'update.php?action=install-plugin&plugin=advanced-ads-adsense-in-feed' ),
'install-plugin_advanced-ads-adsense-in-feed'
)
),
'class' => 'advads-ad-notice-in-feed-add-on advads-notice-inline advads-idea hidden',
];
}
break;
}
return $notices;
}
/**
* Enqueue AdSense connection script.
*/
public static function enqueue_connect_adsense() {
if ( ! wp_script_is( 'advads/connect-adsense', 'registered' ) ) {
wp_enqueue_script( 'advads/connect-adsense', GADSENSE_BASE_URL . 'admin/assets/js/connect-adsense.js', [ 'jquery' ], ADVADS_VERSION );
}
if ( ! has_action( 'admin_footer', [ 'Advanced_Ads_AdSense_Admin', 'print_connect_adsense' ] ) ) {
add_action( 'admin_footer', [ 'Advanced_Ads_AdSense_Admin', 'print_connect_adsense' ] );
}
}
/**
* Prints AdSense connection markup.
*/
public static function print_connect_adsense() {
require_once GADSENSE_BASE_PATH . 'admin/views/connect-adsense.php';
}
/**
* Get Auto Ads messages.
*/
public static function get_auto_ads_messages() {
return [
'enabled' => sprintf(
/* translators: %s is a URL. */
__( 'The AdSense verification and Auto ads code is already activated in the <a href="%s">AdSense settings</a>.', 'advanced-ads' ),
admin_url( 'admin.php?page=advanced-ads-settings#top#adsense' )
)
. ' ' . __( 'No need to add the code manually here, unless you want to include it into certain pages only.', 'advanced-ads' ),
'disabled' => sprintf(
'%s <button id="adsense_enable_pla" type="button" class="button">%s</button>',
sprintf(
/* translators: %s is a URL. */
__( 'The AdSense verification and Auto ads code should be set up in the <a href="%s">AdSense settings</a>. Click on the following button to enable it now.', 'advanced-ads' ),
admin_url( 'admin.php?page=advanced-ads-settings#top#adsense' )
),
esc_attr__( 'Activate', 'advanced-ads' )
),
];
}
/**
* Get the ad selector markup
*
* @param bool $hide_idle_ads Whether to hide idle ads.
*/
public static function get_mapi_ad_selector( $hide_idle_ads = true ) {
global $closeable, $use_dashicons, $network, $ad_units, $display_slot_id;
$closeable = true;
$use_dashicons = false;
$network = Advanced_Ads_Network_Adsense::get_instance();
$ad_units = $network->get_external_ad_units();
$display_slot_id = true;
$pub_id = Advanced_Ads_AdSense_Data::get_instance()->get_adsense_id();
require_once GADSENSE_BASE_PATH . 'admin/views/external-ads-list.php';
}
/**
* Is on screen.
*
* @return boolean
*/
private function is_on_screen(): bool {
global $pagenow, $post_type;
return ( 'post-new.php' === $pagenow && Constants::POST_TYPE_AD === $post_type ) ||
( 'post.php' === $pagenow && Constants::POST_TYPE_AD === $post_type && 'edit' === Params::get( 'action' ) );
}
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" overflow="visible"><path fill="#fff" d="M19.878 99C9.469 99 1 90.532 1 80.123V2a1 1 0 0 1 1-1h78.122C90.531 1 99 9.469 99 19.878V98a1 1 0 0 1-1 1H19.878z"/><path d="M80.122 2C89.98 2 98 10.02 98 19.878V98H19.878C10.02 98 2 89.981 2 80.123V2h78.122m0-2H2a2 2 0 0 0-2 2v78.123C0 91.083 8.917 100 19.878 100H98a2 2 0 0 0 2-2V19.878C100 8.917 91.083 0 80.122 0h0zm5.326 17.555H14.635a2.961 2.961 0 1 1 0-5.921h70.813a2.961 2.961 0 1 1 0 5.921zm0 70.812H14.635a2.961 2.961 0 1 1 0-5.921h70.813a2.961 2.961 0 1 1 0 5.921z" fill="#0074a2"/><path fill="#39f" d="M73.604 76.524H26.478a2.96 2.96 0 0 1-2.961-2.961V26.438a2.96 2.96 0 0 1 2.961-2.961h47.126a2.96 2.96 0 0 1 2.961 2.961v47.126c-.001 1.634-1.326 2.96-2.961 2.96z"/><path fill="#add6ff" d="M55.313 42.02c1.806-3.091.733-7.041-2.396-8.825s-7.131-.727-8.937 2.364l-.225.423-6.105 10.445c-.136.208-.261.42-.375.642l-6.341 10.94 11.331 6.352 6.309-10.848a6.75 6.75 0 0 0 .374-.642l6.106-10.447.259-.404"/><path fill="#fff" d="M42.319 64.327c-1.797 3.141-5.848 4.297-8.957 2.485s-4.217-5.747-2.418-8.888 5.811-4.3 8.921-2.488 4.249 5.751 2.454 8.891"/><path fill="#d6ebff" d="M66.769 44.089a6.48 6.48 0 0 0-8.837 2.361l-6.468 11.175c-1.782 3.083-.73 7.023 2.35 8.806.007.003.012.007.018.011a6.48 6.48 0 0 0 8.839-2.362l6.468-11.175a6.45 6.45 0 0 0-2.355-8.807"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" overflow="visible"><path fill="#fff" d="M19.878 99C9.469 99 1 90.531 1 80.121V2a1 1 0 0 1 1-1h78.122C90.531 1 99 9.468 99 19.877V98a1 1 0 0 1-1 1H19.878z"/><path d="M80.122 2C89.98 2 98 10.02 98 19.877V98H19.878C10.02 98 2 89.979 2 80.121V2h78.122m0-2H2a2 2 0 0 0-2 2v78.121C0 91.082 8.917 100 19.878 100H98a2 2 0 0 0 2-2V19.877C100 8.917 91.083 0 80.122 0h0zm5.324 17.554H14.633a2.961 2.961 0 1 1 0-5.921h70.813a2.961 2.961 0 1 1 0 5.921zm0 70.813H14.633a2.962 2.962 0 0 1 0-5.923h70.813a2.96 2.96 0 0 1 2.961 2.962c0 1.634-1.326 2.961-2.961 2.961z" fill="#0074a2"/><path fill="#ffbf00" d="M85.444 76.522H14.633a2.96 2.96 0 0 1-2.96-2.961V26.436a2.96 2.96 0 0 1 2.96-2.96h70.812a2.96 2.96 0 0 1 2.961 2.96v47.125c-.001 1.636-1.327 2.961-2.962 2.961z"/><path fill="#ffe599" d="M54.384 37.389c1.49-2.549.606-5.804-1.973-7.276s-5.878-.599-7.367 1.949l-.184.35-5.034 8.611c-.113.17-.213.345-.309.526l-5.228 9.019 9.339 5.236 5.202-8.942c.112-.17.218-.348.31-.53l5.031-8.609.213-.334"/><path fill="#fff" d="M43.673 55.777c-1.48 2.59-4.819 3.54-7.384 2.047s-3.475-4.735-1.994-7.325 4.792-3.545 7.356-2.051 3.501 4.739 2.021 7.327"/><path fill="#fff2cc" d="M63.829 39.093a5.34 5.34 0 0 0-7.285 1.947l-5.333 9.212c-1.469 2.542-.601 5.79 1.94 7.259 2.562 1.477 5.822.607 7.3-1.939l5.329-9.212c1.469-2.539.602-5.791-1.94-7.259"/><path fill="#fff" d="M79.523 70.602h-58.97a2.96 2.96 0 1 1 0-5.922h58.97a2.96 2.96 0 1 1 0 5.922z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100" overflow="visible"><path fill="#fff" d="M19.878 99C9.469 99 1 90.531 1 80.122V2a1 1 0 0 1 1-1h78.122C90.531 1 99 9.468 99 19.877V98a1 1 0 0 1-1 1H19.878z"/><g fill="#0074a2"><path d="M80.122 2C89.98 2 98 10.02 98 19.877V98H19.878C10.02 98 2 89.98 2 80.122V2h78.122m0-2H2a2 2 0 0 0-2 2v78.122C0 91.083 8.917 100 19.878 100H98a2 2 0 0 0 2-2V19.877C100 8.917 91.083 0 80.122 0h0z"/><use xlink:href="#B"/><use xlink:href="#B" y="11.843"/></g><path fill="#52cc52" d="M85.408 64.809H14.596c-1.57 0-2.845-1.273-2.845-2.844V38.278c0-1.571 1.274-2.845 2.845-2.845h70.812c1.57 0 2.844 1.274 2.844 2.845v23.687c0 1.57-1.273 2.844-2.844 2.844z"/><path d="M79.484 47.161h-35.28a2.961 2.961 0 1 1 0-5.921h35.28a2.961 2.961 0 1 1 0 5.921zm0 11.843h-35.28a2.961 2.961 0 1 1 0-5.922h35.28a2.961 2.961 0 1 1 0 5.922z" fill="#fff"/><g fill="#0074a2"><path d="M79.484 76.769H44.206a2.96 2.96 0 1 1 0-5.922h35.278a2.96 2.96 0 1 1 0 5.922z"/><use xlink:href="#B" y="71.057"/><path d="M32.858 20.581a5.99 5.99 0 0 1-5.99 5.987 5.99 5.99 0 0 1-5.987-5.987 5.99 5.99 0 0 1 5.987-5.988 5.99 5.99 0 0 1 5.99 5.988zm0 59.213a5.99 5.99 0 0 1-5.99 5.989 5.99 5.99 0 0 1-5.987-5.989 5.99 5.99 0 0 1 5.987-5.986 5.99 5.99 0 0 1 5.99 5.986z"/></g><path fill="#baebba" d="M28.688 46.717a2.74 2.74 0 0 0-1.023-3.767 2.81 2.81 0 0 0-3.812 1.01l-.096.18-2.604 4.457c-.058.088-.112.179-.16.273l-2.705 4.669 4.833 2.709 2.691-4.629c.061-.088.113-.18.161-.274l2.604-4.456.111-.172"/><path fill="#fff" d="M23.145 56.233c-.767 1.341-2.496 1.833-3.823 1.061s-1.798-2.451-1.032-3.792 2.481-1.836 3.81-1.062 1.81 2.454 1.045 3.793"/><path fill="#dcf5dc" d="M33.575 47.598c-1.317-.76-3.005-.309-3.771 1.008l-2.759 4.768a2.75 2.75 0 0 0 1.003 3.758c1.327.766 3.014.315 3.779-1.005l2.758-4.768a2.75 2.75 0 0 0-1.004-3.757"/><defs ><path id="B" d="M79.484 17.553H44.206a2.96 2.96 0 1 1 0-5.921h35.278a2.96 2.96 0 1 1 0 5.921z"/></defs></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" overflow="visible"><path fill="#fff" d="M19.878 99C9.469 99 1 90.531 1 80.122V2a1 1 0 0 1 1-1h78.122C90.531 1 99 9.468 99 19.877V98a1 1 0 0 1-1 1H19.878z"/><path d="M80.122 2C89.98 2 98 10.02 98 19.877V98H19.878C10.02 98 2 89.98 2 80.122V2h78.122m0-2H2a2 2 0 0 0-2 2v78.122C0 91.083 8.917 100 19.878 100H98a2 2 0 0 0 2-2V19.877C100 8.917 91.083 0 80.122 0h0zm-.599 17.556H20.559a2.961 2.961 0 1 1 0-5.921h58.965a2.96 2.96 0 0 1 2.962 2.961c-.001 1.634-1.327 2.96-2.963 2.96zm0 11.842H20.559a2.961 2.961 0 1 1 0-5.921h58.965a2.96 2.96 0 0 1 2.962 2.96c-.001 1.635-1.327 2.961-2.963 2.961z" fill="#0074a2"/><path fill="#d95757" d="M85.446 88.496H14.635c-1.57 0-2.844-1.273-2.844-2.845V38.28c0-1.57 1.273-2.844 2.844-2.844h70.812c1.57 0 2.844 1.274 2.844 2.844v47.372c-.001 1.571-1.274 2.844-2.845 2.844z"/><path fill="#fff" d="M79.523 53.083h-35.28a2.96 2.96 0 1 1 0-5.921h35.28a2.96 2.96 0 1 1 0 5.921z"/><path fill="#f0bcbc" d="M28.727 46.719a2.74 2.74 0 0 0-1.021-3.766c-1.337-.762-3.043-.311-3.813 1.009l-.095.18-2.605 4.458c-.058.087-.11.178-.16.274l-2.704 4.666 4.834 2.712 2.689-4.631a2.49 2.49 0 0 0 .161-.272l2.604-4.457.11-.173"/><path fill="#fff" d="M23.183 56.235c-.766 1.341-2.495 1.834-3.821 1.061s-1.799-2.45-1.031-3.792 2.479-1.836 3.807-1.061 1.811 2.453 1.045 3.792"/><path fill="#f7dddd" d="M33.615 47.6c-1.319-.759-3.005-.309-3.769 1.009l-2.762 4.768a2.75 2.75 0 0 0 1.003 3.758c1.327.765 3.015.315 3.78-1.004l2.759-4.768a2.75 2.75 0 0 0-1.006-3.757"/><path fill="#fff" d="M79.523 76.77h-35.28a2.96 2.96 0 0 1 0-5.923h35.28c1.636 0 2.962 1.326 2.962 2.962s-1.326 2.961-2.962 2.961z"/><path fill="#f0bcbc" d="M28.727 70.404a2.74 2.74 0 0 0-1.021-3.766 2.81 2.81 0 0 0-3.813 1.009l-.095.18-2.605 4.458a3.34 3.34 0 0 0-.16.272l-2.704 4.668 4.834 2.709 2.689-4.628c.059-.088.114-.179.161-.273l2.604-4.457.11-.172"/><path fill="#fff" d="M23.183 79.921c-.766 1.341-2.495 1.834-3.821 1.061s-1.799-2.451-1.031-3.791 2.479-1.836 3.807-1.062 1.811 2.453 1.045 3.792"/><path fill="#f7dddd" d="M33.615 71.286a2.76 2.76 0 0 0-3.769 1.008l-2.762 4.77a2.75 2.75 0 0 0 1.003 3.756c1.327.765 3.015.315 3.78-1.003l2.759-4.769c.76-1.315.309-2.997-1.006-3.758"/></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,928 @@
/**
* actually this method was moved inside the ad network class.
* however the responsive addon depends on it, so i made it global again.
* this makes it downward compatible (with an older version of responsive),
* but you should probably adjust the responsive plugin to make use of
* the static method (AdvancedAdsNetworkAdsense.gadsenseFormatAdContent)
*
* in case you come across a missing method originating from the deleted new-ad.js,
* please just make the methods static and create a wrapper function like the one below
*/
window.gadsenseFormatAdContent = function () {
AdvancedAdsNetworkAdsense.gadsenseFormatAdContent();
};
class AdvancedAdsNetworkAdsense extends AdvancedAdsAdNetwork {
constructor( codes ) {
super( 'adsense' );
this.name = 'adsense';
this.codes = codes;
this.parseCodeBtnClicked = false;
this.preventCloseAdSelector = false;
// this.adUnitName = null;
// the legacy code of gadsense executes a script inside a php template and will may not have been executed
// at this stage. the AdvancedAdsAdNetwork class already knows the publisher id, so we will overwrite
// the field in gadsenseData to be up to date at all times.
// TODO: the use of gadsenseData.pubId could be removed from this class in favor of this.vars.pubId
gadsenseData.pubId = this.vars.pubId;
}
/**
* Legacy method
*
* Format the post content field
*/
static gadsenseFormatAdContent() {
const slotId = jQuery( '#ad-parameters-box #unit-code' ).val();
const unitType = jQuery( '#ad-parameters-box #unit-type' ).val();
const publisherId = jQuery( '#advads-adsense-pub-id' ).val() ? jQuery( '#advads-adsense-pub-id' ).val() : gadsenseData.pubId;
let adContent = {
slotId: slotId,
unitType: unitType,
pubId: publisherId
};
if ( unitType === 'responsive' ) {
let resize = jQuery( '#ad-parameters-box #ad-resize-type' ).val();
if ( resize === '0' ) {
resize = 'auto';
}
adContent.resize = resize;
}
if ( unitType === 'in-feed' ) {
adContent.layout_key = jQuery( '#ad-parameters-box #ad-layout-key' ).val();
}
if ( typeof adContent.resize !== 'undefined' && adContent.resize !== 'auto' ) {
jQuery( document ).trigger( 'gadsenseFormatAdResponsive', [adContent] );
}
jQuery( document ).trigger( 'gadsenseFormatAdContent', [adContent] );
if ( typeof window.gadsenseAdContent !== 'undefined' ) {
adContent = window.gadsenseAdContent;
delete( window.gadsenseAdContent );
}
jQuery( '#advads-ad-content-adsense' ).val( JSON.stringify( adContent, false, 2 ) );
}
openSelector() {
}
closeAdSelector() {
if ( this.preventCloseAdSelector ) {
return;
}
AdvancedAdsAdmin.AdImporter.closeAdSelector();
}
getSelectedId() {
const pubId = gadsenseData.pubId || false;
const slotId = jQuery( '#unit-code' ).val().trim();
return pubId && slotId ? 'ca-' + pubId + ':' + slotId : null;
}
selectAdFromList( slotId ) {
this.preventCloseAdSelector = true;
this.onSelectAd( slotId );
AdvancedAdsAdmin.AdImporter.openExternalAdsList();
const report = Advanced_Ads_Adsense_Report_Helper.getReportObject();
if ( report ) {
report.filter = slotId.split( ':' )[1];
report.updateHtmlAttr();
report.refresh();
}
}
updateAdFromList( slotId ) {
this.getRemoteCode( slotId );
}
getRefreshAdsParameters() {
return {
nonce: AdsenseMAPI.nonce,
action: 'advanced_ads_get_ad_units_adsense',
account: gadsenseData.pubId,
inactive: ! this.hideIdle
};
}
onManualSetup() {
jQuery( '.advads-adsense-code' ).css( 'display', 'none' );
jQuery( '#remote-ad-unsupported-ad-type' ).css( 'display', 'none' );
this.undoReadOnly();
}
/**
* Parse the code of an adsense ad and adjust the GUI
* call it, when an ad unit was selected.
* returns the parsed obj or false, when the ad code could not be parsed
*/
processAdCode( code ) {
const parsed = this.parseAdContentFailsafe( code );
if ( parsed ) {
this.undoReadOnly();
this.setDetailsFromAdCode( parsed );
this.makeReadOnly();
jQuery( '#remote-ad-code-error' ).hide();
jQuery( '#remote-ad-unsupported-ad-type' ).hide();
this.closeAdSelector();
} else {
jQuery( '#remote-ad-code-error' ).show();
}
return parsed;
}
/**
* Clone of legacy method
*
* @param slotID
*/
onSelectAd( slotID ) {
if ( typeof this.codes[slotID] !== 'undefined' ) {
this.getSavedDetails( slotID );
} else {
this.getRemoteCode( slotID );
}
}
/**
* Legacy method
*
* @param slotID
*/
getSavedDetails( slotID ) {
if ( typeof this.codes[slotID] !== 'undefined' ) {
const parsed = this.processAdCode( this.codes[slotID] );
if ( parsed !== false ) {
jQuery( '#remote-ad-unsupported-ad-type' ).css( 'display', 'none' );
this.closeAdSelector();
this.preventCloseAdSelector = false;
}
}
}
/**
* Legacy method
*
* @param slotID
*/
getRemoteCode( slotID ) {
if ( slotID === '' ) {
return;
}
jQuery( '#mapi-loading-overlay' ).css( 'display', 'block' );
const self = this;
jQuery.ajax( {
type: 'post',
url: ajaxurl,
data: {
nonce: AdsenseMAPI.nonce,
action: 'advads_mapi_get_adCode',
unit: slotID
},
success: function ( response ) {
jQuery( '#mapi-loading-overlay' ).css( 'display', 'none' );
if ( typeof response.code !== 'undefined' ) {
jQuery( '#remote-ad-code-msg' ).empty();
if ( self.processAdCode( response.code ) !== false ) {
self.codes[slotID] = response.code;
AdvancedAdsAdmin.AdImporter.unitIsSupported( slotID );
}
AdvancedAdsAdmin.AdImporter.highlightSelectedRowInExternalAdsList();
jQuery( '[data-slotid="' + slotID + '"]' ).children( '.unittype' ).text( response.type );
self.closeAdSelector();
} else {
if ( typeof response.raw !== 'undefined' ) {
jQuery( '#remote-ad-code-msg' ).html( response.raw );
} else if ( typeof response.msg !== 'undefined' ) {
if ( typeof response.reload !== 'undefined' ) {
AdvancedAdsAdmin.AdImporter.emptyMapiSelector( response.msg );
} else {
if ( response.msg === 'doesNotSupportAdUnitType' ) {
AdvancedAdsAdmin.AdImporter.unitIsNotSupported( slotID );
} else {
jQuery( '#remote-ad-code-msg' ).html( response.msg );
}
}
if ( typeof response.raw !== 'undefined' ) {
console.log( response.raw );
}
}
}
},
error: function () {
jQuery( '#mapi-loading-overlay' ).css( 'display', 'none' );
}
} );
}
/**
* Legacy method
*
* Parse ad content.
*
* @return {!Object}
*/
parseAdContent( content ) {
const rawContent = typeof content !== 'undefined' ? content.trim() : '';
const theContent = jQuery( '<div />' ).html( rawContent );
const adByGoogle = theContent.find( 'ins' );
let theAd = {};
theAd.slotId = adByGoogle.attr( 'data-ad-slot' ) || '';
if ( typeof adByGoogle.attr( 'data-ad-client' ) !== 'undefined' ) {
theAd.pubId = adByGoogle.attr( 'data-ad-client' ).substr( 3 );
}
if ( theAd.slotId !== undefined && theAd.pubId !== '' ) {
theAd.display = adByGoogle.css( 'display' );
theAd.format = adByGoogle.attr( 'data-ad-format' );
theAd.layout = adByGoogle.attr( 'data-ad-layout' ); // for In-feed and In-article
theAd.layout_key = adByGoogle.attr( 'data-ad-layout-key' ); // for InFeed
theAd.style = adByGoogle.attr( 'style' ) || '';
// Normal ad.
if ( typeof theAd.format === 'undefined' && theAd.style.indexOf( 'width' ) !== - 1 ) {
theAd.type = 'normal';
theAd.width = adByGoogle.css( 'width' ).replace( 'px', '' );
theAd.height = adByGoogle.css( 'height' ).replace( 'px', '' );
} else if ( typeof theAd.format !== 'undefined' && theAd.format === 'auto' ) {
// Responsive ad, auto resize.
theAd.type = 'responsive';
} else if ( typeof theAd.format !== 'undefined' && theAd.format === 'link' ) {
// Older link unit format; for new ads the format type is no longer needed; link units are created through the AdSense panel
if ( theAd.style.indexOf( 'width' ) !== - 1 ) {
// Is fixed size.
theAd.width = adByGoogle.css( 'width' ).replace( 'px', '' );
theAd.height = adByGoogle.css( 'height' ).replace( 'px', '' );
theAd.type = 'link';
} else {
// Is responsive.
theAd.type = 'link-responsive';
}
} else if ( typeof theAd.format !== 'undefined' && theAd.format === 'autorelaxed' ) {
// Responsive Matched Content
theAd.type = 'matched-content';
} else if ( typeof theAd.format !== 'undefined' && theAd.format === 'fluid' ) {
// In-article & In-feed ads.
if ( typeof theAd.layout !== 'undefined' && theAd.layout === 'in-article' ) {
// In-article.
theAd.type = 'in-article';
} else {
// In-feed.
theAd.type = 'in-feed';
}
}
}
/**
* Synchronous code
*/
if ( rawContent.indexOf( 'google_ad_slot' ) !== - 1 ) {
const adClient = rawContent.match( /google_ad_client ?= ?["']([^'"]+)/ );
const adSlot = rawContent.match( /google_ad_slot ?= ?["']([^'"]+)/ );
const adFormat = rawContent.match( /google_ad_format ?= ?["']([^'"]+)/ );
const adWidth = rawContent.match( /google_ad_width ?= ?([\d]+)/ );
const adHeight = rawContent.match( /google_ad_height ?= ?([\d]+)/ );
theAd = {};
theAd.pubId = adClient[1].substr( 3 );
if ( adSlot !== null ) {
theAd.slotId = adSlot[1];
}
if ( adFormat !== null ) {
theAd.format = adFormat[1];
}
if ( adWidth !== null ) {
theAd.width = parseInt( adWidth[1] );
}
if ( adHeight !== null ) {
theAd.height = parseInt( adHeight[1] );
}
if ( typeof theAd.format === 'undefined' ) {
theAd.type = 'normal';
}
}
if ( theAd.slotId === '' && gadsenseData.pubId && gadsenseData.pubId !== '' ) {
theAd.type = jQuery( '#unit-type' ).val();
}
// Page-Level ad.
if ( rawContent.indexOf( 'enable_page_level_ads' ) !== - 1 || /script[^>]+data-ad-client=/.test( rawContent ) ) {
theAd = {'parse_message': 'pageLevelAd'};
} else if ( ! theAd.type ) {
// Unknown ad.
theAd = {'parse_message': 'unknownAd'};
}
jQuery( document ).trigger( 'gadsenseParseAdContent', [theAd, adByGoogle] );
return theAd;
}
parseAdContentFailsafe( code ) {
if ( typeof code === 'string' ) {
try {
code = JSON.parse( code );
} catch ( e ) {
return this.parseAdContent( code );
}
}
return code;
}
/**
* Handle result of parsing content.
*
* Legacy method
*/
handleParseResult( parseResult ) {
jQuery( '#pastecode-msg' ).empty();
switch ( parseResult.parse_message ) {
case 'pageLevelAd' :
advads_show_adsense_auto_ads_warning();
break;
case 'unknownAd' :
// Not recognized ad code.
if ( this.parseCodeBtnClicked && 'post-new.php' === gadsenseData.pagenow ) {
// do not show if just after switching to AdSense ad type on ad creation.
jQuery( '#pastecode-msg' ).append( jQuery( '<p />' ).css( 'color', 'red' ).html( gadsenseData.msg.unknownAd ) );
}
break;
default:
this.setDetailsFromAdCode( parseResult );
if ( typeof AdsenseMAPI !== 'undefined' && typeof AdsenseMAPI.hasToken !== 'undefined' && AdsenseMAPI.pubId === parseResult.pubId ) {
const content = jQuery( '#advanced-ads-ad-parameters input[name="advanced_ad[content]"]' ).val();
this.mapiSaveAdCode( content, parseResult.slotId );
this.makeReadOnly();
}
jQuery( '.advads-adsense-code' ).hide();
jQuery( '.advads-adsense-show-code' ).show();
jQuery( '.mapi-insert-code' ).show();
const customInputs = this.getCustomInputs();
customInputs.show();
}
}
/**
* Legacy method
*
* Set ad parameters fields from the result of parsing ad code
*/
setDetailsFromAdCode( theAd ) {
this.undoReadOnly();
jQuery( '#unit-code' ).val( theAd.slotId );
jQuery( '#advads-adsense-pub-id' ).val( theAd.pubId );
if ( theAd.type === 'normal' ) {
jQuery( '#unit-type' ).val( 'normal' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[width]"]' ).val( theAd.width );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[height]"]' ).val( theAd.height );
} else if ( theAd.type === 'responsive' ) {
jQuery( '#unit-type' ).val( 'responsive' );
jQuery( '#ad-resize-type' ).val( 'auto' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[width]"]' ).val( '' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[height]"]' ).val( '' );
} else if ( theAd.type === 'link') {
jQuery( '#unit-type' ).val( 'link' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[width]"]' ).val( theAd.width );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[height]"]' ).val( theAd.height );
} else if ( theAd.type === 'link-responsive' ) {
jQuery( '#unit-type' ).val( 'link-responsive' );
jQuery( '#ad-resize-type' ).val( 'auto' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[width]"]' ).val( '' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[height]"]' ).val( '' );
} else if ( theAd.type === 'matched-content' ) {
jQuery( '#unit-type' ).val( 'matched-content' );
jQuery( '#ad-resize-type' ).val( 'auto' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[width]"]' ).val( '' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[height]"]' ).val( '' );
} else if ( theAd.type === 'in-article' ) {
jQuery( '#unit-type' ).val( 'in-article' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[width]"]' ).val( '' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[height]"]' ).val( '' );
} else if ( theAd.type === 'in-feed' ) {
jQuery( '#unit-type' ).val( 'in-feed' );
jQuery( '#ad-layout-key' ).val( theAd.layout_key );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[width]"]' ).val( '' );
jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[height]"]' ).val( '' );
}
const storedPubId = gadsenseData.pubId;
if ( storedPubId !== '' && theAd.pubId !== storedPubId && theAd.slotId !== '' ) {
jQuery( '#adsense-ad-param-error' ).text( gadsenseData.msg.pubIdMismatch );
} else {
jQuery( '#adsense-ad-param-error' ).empty();
}
jQuery( document ).trigger( 'this.setDetailsFromAdCode', [theAd] );
jQuery( '#unit-type' ).trigger( 'change' );
}
/**
* Legacy method
*/
updateAdsenseType() {
const $ = jQuery;
const type = $( '#unit-type' ).val();
const layout = $( '.advads-adsense-layout' );
const layoutKey = $( '.advads-adsense-layout-key' );
const size = $( '#advanced-ads-ad-parameters-size' );
const width = $( '[name="advanced_ad\[width\]"]' );
const height = $( '[name="advanced_ad\[height\]"]' );
layout.hide().next( 'div' ).hide();
layoutKey.hide().next( 'div' ).hide();
jQuery( '.advads-ad-notice-in-feed-add-on' ).hide();
if ( type === 'responsive' || type === 'link-responsive' || type === 'matched-content' ) {
size.hide().prev( '.label' ).hide();
size.next( '.hr' ).hide();
$( '.clearfix-before' ).show();
} else if ( type === 'in-feed' ) {
layout.hide().next( 'div' ).hide();
layoutKey.show().next( 'div' ).show();
size.hide().prev( '.label' ).hide();
size.next( '.hr' ).hide();
// show add-on notice
$( '.advads-ad-notice-in-feed-add-on' ).show();
$( '.clearfix-before' ).show();
} else if ( type === 'in-article' ) {
size.hide().prev( '.label' ).hide();
size.next( '.hr' ).hide();
$( '.clearfix-before' ).show();
} else if ( type === 'normal' || type === 'link' ) {
size.show().prev( '.label' ).show();
size.next( '.hr' ).show();
$( '.clearfix-before' ).hide();
if ( ! width.val() ) {
width.val( '300' );
}
if ( ! height.val() ) {
height.val( '250' );
}
}
$( document ).trigger( 'gadsenseUnitChanged' );
AdvancedAdsNetworkAdsense.gadsenseFormatAdContent();
this.show_float_warnings( type );
}
/**
* Legacy method
*
* Show / hide position warning.
*/
show_float_warnings( unit_type ) {
const resize_type = jQuery( '#ad-resize-type' ).val();
const position = jQuery( 'input[name="advanced_ad[output][position]"]:checked' ).val();
if (
( ['link-responsive', 'matched-content', 'in-article', 'in-feed'].indexOf( unit_type ) !== - 1
|| ( unit_type === 'responsive' && resize_type !== 'manual' )
)
&& ( position.startsWith( 'left' ) || position.startsWith( 'right' ) )
) {
jQuery( '#ad-parameters-box-notices .advads-ad-notice-responsive-position' ).show();
} else {
jQuery( '#ad-parameters-box-notices .advads-ad-notice-responsive-position' ).hide();
}
}
/**
* Legacy method - adds readonly to relevant inputs
*/
makeReadOnly() {
jQuery( '#unit-type option:not(:selected)' ).prop( 'disabled', true );
}
/**
* Legacy method - removes readonly from relevant inputs (original name getSlotAndType_jq)
*/
undoReadOnly() {
jQuery( '#unit-code,#ad-layout,#ad-layout-key,[name="advanced_ad[width]"],[name="advanced_ad[height]"]' ).prop( 'readonly', false );
jQuery( '#unit-type option:not(:selected)' ).prop( 'disabled', false );
}
getCustomInputs() {
const $div1 = jQuery( '#unit-code' ).closest( 'div' );
const $label1 = $div1.prev();
const $hr1 = $div1.next();
const $label2 = $hr1.next();
const $div2 = $label2.next();
const $layoutKey = jQuery( '#ad-layout-key' ).closest( 'div' );
const $layoutKeyLabel = $layoutKey.prev( '#advads-adsense-layout-key' );
return $div1.add( $label1 ).add( $hr1 ).add( $label2 ).add( $div2 ).add( $layoutKey ).add( $layoutKeyLabel );
}
onBlur() {
}
onSelected() {
// Handle a click from the "Switch to AdSense ad" button.
if ( AdvancedAdsAdmin.AdImporter.adsenseCode ) {
this.parseCodeBtnClicked = true;
const parseResult = this.parseAdContent( AdvancedAdsAdmin.AdImporter.adsenseCode );
AdvancedAdsAdmin.AdImporter.adsenseCode = null;
this.handleParseResult( parseResult );
} else {
// When you are not connected to adsense, or if the ad was edited manually open the manual setup view.
let switchToManualSetup = ! this.vars.connected;
if ( ! switchToManualSetup ) {
const parsedAd = this.parseAdContentFailsafe( this.codes[this.getSelectedId()] );
if ( parsedAd ) {
// We need to check if the type of the ad is different from the default. this marks a manually setup ad.
if ( parsedAd.type !== jQuery( '#unit-type' ).val() ) {
// This ad was manually setup. don't open the selector, but switch to manual select.
switchToManualSetup = true;
}
}
}
if ( switchToManualSetup ) {
AdvancedAdsAdmin.AdImporter.manualSetup();
} else if ( AdvancedAdsAdmin.AdImporter.highlightSelectedRowInExternalAdsList() || ! this.getSelectedId() ) {
AdvancedAdsAdmin.AdImporter.openExternalAdsList();
}
}
}
onDomReady() {
const self = this;
jQuery( document ).on( 'click', '.advads-adsense-close-code', function ( ev ) {
ev.preventDefault();
self.onSelected();
} );
jQuery( document ).on( 'click', '.advads-adsense-submit-code', function ( ev ) {
ev.preventDefault();
self.parseCodeBtnClicked = true;
const rawContent = jQuery( '.advads-adsense-content' ).val();
const parseResult = self.parseAdContent( rawContent );
self.handleParseResult( parseResult );
if ( AdvancedAdsAdmin.AdImporter.highlightSelectedRowInExternalAdsList() ) {
AdvancedAdsAdmin.AdImporter.openExternalAdsList();
self.preventCloseAdSelector = true;
// save the manually added ad code to the AdSense settings
wp.ajax.post( 'advads-mapi-save-manual-code', {
raw_code: encodeURIComponent( rawContent ),
parsed_code: parseResult,
nonce: AdsenseMAPI.nonce
} )
.fail( function ( r ) {
const $notice = jQuery( '<div>' ).addClass( 'notice notice-error' ).html( jQuery( '<p>' ).text( r.responseJSON.data.message ) );
jQuery( '#post' ).before( $notice );
jQuery( 'body html' ).animate(
{
scrollTop: $notice.offset().top
},
200
);
} );
} else {
// No adsense ad with this slot id was found.
// Switches to manual ad setup view.
self.preventCloseAdSelector = false;
AdvancedAdsAdmin.AdImporter.manualSetup();
}
} );
jQuery( document ).on( 'gadsenseUnitChanged', function () {
const $row = jQuery( 'tr[data-slotid$="' + jQuery( '#unit-code' ).val() + '"]' );
let type = window.adsenseAdvancedAdsJS.ad_types.display;
switch ( jQuery( '#unit-type' ).val() ) {
case 'matched-content':
type = window.adsenseAdvancedAdsJS.ad_types.matched_content;
break;
case 'link':
case 'link-responsive':
type = window.adsenseAdvancedAdsJS.ad_types.link;
break;
case 'in-article':
type = window.adsenseAdvancedAdsJS.ad_types.in_article;
break;
case 'in-feed':
type = window.adsenseAdvancedAdsJS.ad_types.in_feed;
break;
}
$row.children( '.unittype' ).text( type );
} );
jQuery( document ).on( 'change', '#unit-type, #unit-code, #ad-layout-key', function () {
self.checkAdSlotId( this );
} );
const inputCode = jQuery( '#unit-code' );
if ( inputCode ) {
this.checkAdSlotId( inputCode[0] );
}
jQuery( document ).on( 'change', '#ad-resize-type', function () {
self.show_float_warnings( 'responsive' );
} );
this.updateAdsenseType();
if ( typeof AdsenseMAPI.hasToken !== 'undefined' ) {
this.mapiMayBeSaveAdCode();
}
jQuery( document ).on( 'click', '#mapi-archived-ads', function () {
self.showArchivedAds( jQuery( this ).hasClass( 'dashicons-visibility' ) );
} );
jQuery( '#wpwrap' ).on(
'advads-mapi-adlist-opened',
function () {
// Update ad unit list to v2 data the first time the ad list is opened.
if ( jQuery( '#mapi-force-v2-list-update' ).length ) {
jQuery( '#mapi-wrap i[data-mapiaction="updateList"]' ).trigger( 'click' );
return;
}
self.showArchivedAds();
}
);
this.onSelected();
}
showArchivedAds( show ) {
if ( typeof show === 'undefined' ) {
show = false;
}
const icon = jQuery( '#mapi-archived-ads' );
const title = icon.attr( 'title' );
const altTitle = icon.attr( 'data-alt-title' );
if ( show ) {
jQuery( '#mapi-table-wrap tbody tr[data-archived="1"]' ).show();
icon.removeClass( 'dashicons-visibility' ).addClass( 'dashicons-hidden' ).attr( 'title', altTitle ).attr( 'data-alt-title', title );
} else {
jQuery( '#mapi-table-wrap tbody tr[data-archived="1"]' ).not( '.selected' ).hide();
icon.removeClass( 'dashicons-hidden' ).addClass( 'dashicons-visibility' ).attr( 'title', altTitle ).attr( 'data-alt-title', title );
}
}
checkAdSlotId( elm ) {
if ( jQuery( elm ).attr( 'id' ) === 'unit-code' ) {
let val = jQuery( elm ).val();
if ( val ) {
val = val.trim();
}
if ( val.length > 0 && gadsenseData.pubId && val.indexOf( gadsenseData.pubId.substr( 4 ) ) !== -1 ) {
jQuery( '#advads-pubid-in-slot' ).css( 'display', 'block' );
jQuery( elm ).css( 'background-color', 'rgba(255, 235, 59, 0.33)' );
this.updateAdsenseType();
return;
}
}
jQuery( '#unit-code' ).css( 'background-color', '#fff' );
jQuery( '#advads-pubid-in-slot' ).css( 'display', 'none' );
this.updateAdsenseType();
}
mapiSaveAdCode( code, slot ) {
if ( typeof AdsenseMAPI.hasToken !== 'undefined' && typeof this.codes['ca-' + AdsenseMAPI.pubId + ':' + slot] === 'undefined' ) {
this.codes['ca-' + AdsenseMAPI.pubId + ':' + slot] = code;
jQuery( '#mapi-loading-overlay' ).css( 'display', 'block' );
jQuery.ajax( {
type: 'post',
url: ajaxurl,
data: {
nonce: AdsenseMAPI.nonce,
slot: slot,
code: code,
action: 'advads-mapi-reconstructed-code'
},
success: function ( resp, status, XHR ) {
jQuery( '#mapi-loading-overlay' ).css( 'display', 'none' );
},
error: function ( req, status, err ) {
jQuery( '#mapi-loading-overlay' ).css( 'display', 'none' );
}
} );
}
}
mapiMayBeSaveAdCode() {
// MAPI not set up
if ( typeof AdsenseMAPI.hasToken === 'undefined' ) {
return;
}
const slotId = jQuery( '#unit-code' ).val();
if ( ! slotId ) {
return;
}
const type = jQuery( '#unit-type' ).val();
const width = jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[width]"]' ).val().trim();
const height = jQuery( '#advanced-ads-ad-parameters-size input[name="advanced_ad[height]"]' ).val().trim();
const layout = jQuery( '#ad-layout' ).val();
const layoutKey = jQuery( '#ad-layout-key' ).val();
let code = false;
switch ( type ) {
case 'in-feed':
code = '<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>' +
'<ins class="adsbygoogle" ' +
'style="display:block;" ' +
'data-ad-client="ca-' + AdsenseMAPI.pubId + '" ' +
'data-ad-slot="' + slotId + '" ' +
'data-ad-layout-key="' + layoutKey + '" ';
code += 'data-ad-format="fluid"></ins>' +
'<script>' +
'(adsbygoogle = window.adsbygoogle || []).push({});' +
'</script>';
break;
case 'in-article':
code = '<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>' +
'<ins class="adsbygoogle" ' +
'style="display:block;text-align:center;" ' +
'data-ad-client="ca-' + AdsenseMAPI.pubId + '" ' +
'data-ad-slot="' + slotId + '" ' +
'data-ad-layout="in-article" ' +
'data-ad-format="fluid"></ins>' +
'<script>' +
'(adsbygoogle = window.adsbygoogle || []).push({});' +
'</script>';
break;
case 'matched-content':
code = '<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>' +
'<ins class="adsbygoogle" ' +
'style="display:block;" ' +
'data-ad-client="ca-' + AdsenseMAPI.pubId + '" ' +
'data-ad-slot="' + slotId + '" ' +
'data-ad-format="autorelaxed"></ins>' +
'<script>' +
'(adsbygoogle = window.adsbygoogle || []).push({});' +
'</script>';
break;
case 'link-responsive':
code = '<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>' +
'<ins class="adsbygoogle" ' +
'style="display:block;" ' +
'data-ad-client="ca-' + AdsenseMAPI.pubId + '" ' +
'data-ad-slot="' + slotId + '" ' +
'data-ad-format="link"></ins>' +
'<script>' +
'(adsbygoogle = window.adsbygoogle || []).push({});' +
'</script>';
break;
case 'link':
code = '<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>' +
'<ins class="adsbygoogle" ' +
'style="display:block;width:' + width + 'px;height:' + height + 'px" ' +
'data-ad-client="ca-' + AdsenseMAPI.pubId + '" ' +
'data-ad-slot="' + slotId + '" ' +
'data-ad-format="link"></ins>' +
'<script>' +
'(adsbygoogle = window.adsbygoogle || []).push({});' +
'</script>';
break;
case 'responsive':
code = '<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>' +
'<ins class="adsbygoogle" ' +
'style="display:block;" ' +
'data-ad-client="ca-' + AdsenseMAPI.pubId + '" ' +
'data-ad-slot="' + slotId + '" ' +
'data-ad-format="auto"></ins>' +
'<script>' +
'(adsbygoogle = window.adsbygoogle || []).push({});' +
'</script>';
break;
case 'normal':
code = '<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>' +
'<ins class="adsbygoogle" ' +
'style="display:inline-block;width:' + width + 'px;height:' + height + 'px" ' +
'data-ad-client="ca-' + AdsenseMAPI.pubId + '" ' +
'data-ad-slot="' + slotId + '"></ins>' +
'<script>' +
'(adsbygoogle = window.adsbygoogle || []).push({});' +
'</script>';
break;
default:
}
if ( code ) {
this.mapiSaveAdCode( code, slotId );
}
}
getMapiAction( action ) {
const self = this;
if ( action === 'toggleidle' ) {
return function ( ev, el ) {
self.hideIdle = ! self.hideIdle;
AdvancedAdsAdmin.AdImporter.refreshAds();
};
}
return null;
}
}
// Creates a Advanced_Ads_Adsense_Report_UI instance on the fly
window.Advanced_Ads_Adsense_Report_Helper = window.Advanced_Ads_Adsense_Report_Helper || {};
window.Advanced_Ads_Adsense_Report_Helper.init = function ( element ) {
if ( jQuery( element ).attr( 'data-arguments' ) ) {
try {
const reportArgs = JSON.parse( jQuery( element ).attr( 'data-arguments' ) );
jQuery( element ).data( 'advadsAdsenseReport', new Advanced_Ads_Adsense_Report_UI( element, reportArgs ) );
} catch ( ex ) {
console.error( 'Cannot parse report arguments' );
}
}
};
window.Advanced_Ads_Adsense_Report_Helper.getReportObject = function () {
const reportElem = jQuery( '.advanced-ads-adsense-dashboard' );
if ( reportElem.length ) {
let report = reportElem.data( 'advadsAdsenseReport' );
if ( typeof report.refresh === 'function' ) {
return report;
}
}
return false;
};
class Advanced_Ads_Adsense_Report_UI {
constructor( el, args ) {
this.$el = jQuery( el );
this.type = args.type;
this.filter = args.filter;
this.init();
this.refreshing = false;
}
// Update arguments attributes before refreshing.
updateHtmlAttr() {
this.$el.attr( 'data-arguments', JSON.stringify( {type: 'domain', filter: self.filter} ) );
}
// Get markup for the current arguments.
refresh() {
const self = this;
this.$el.html( '<p style="text-align:center;"><span class="report-need-refresh spinner advads-ad-parameters-spinner advads-spinner"></span></p>' );
jQuery.ajax( {
type: 'POST',
url: ajaxurl,
data: {
nonce: window.Advanced_Ads_Adsense_Report_Helper.nonce,
type: this.type,
filter: this.filter,
action: 'advads_adsense_report_refresh'
},
success: function ( response ) {
if ( response.success && response.data && response.data.html ) {
self.$el.html( response.data.html );
}
}, error: function ( request, status, error ) {
console.log( 'Refreshing rerpot error: ' + error );
}
} );
}
// Initialization - events binding.
init() {
if ( this.$el.find( '.report-need-refresh' ).length ) {
this.refresh();
}
const self = this;
// Hide dropdown on click on everything but the dropdown and its children.
jQuery( document ).on( 'click', '#wpwrap', function () {
const dd = jQuery( '#advads_overview_adsense_stats .advads-stats-dd-button .advads-stats-dd-items' );
if ( dd.is( ':visible' ) ) {
dd.hide();
}
} );
// Show the dropdown.
jQuery( document ).on( 'click', '#advads_overview_adsense_stats .advads-stats-dd-button', function ( ev ) {
// Stop bubbling. Prevents hiding the dropdown.
ev.stopPropagation();
const dd = jQuery( this ).find( '.advads-stats-dd-items' );
if ( ! dd.is( ':visible' ) ) {
dd.show();
}
} );
// Dropdown item clicked.
jQuery( document ).on( 'click', '.advads-stats-dd-button .advads-stats-dd-item', function () {
self.filter = jQuery( this ).attr( 'data-domain' );
self.updateHtmlAttr();
self.refresh();
} );
}
}

View File

@@ -0,0 +1,296 @@
/* eslint-disable no-console */
(function ($) {
// Unique instance of "advadsMapiConnectClass"
let INSTANCE = null;
const advadsMapiConnectClass = function (content, options) {
this.options = {};
this.modal = $('#gadsense-modal');
this.frame = null;
if ('undefined' === typeof content || !content) {
content = 'confirm-code';
}
this.setOptions(options);
this.init();
this.show(content);
return this;
};
advadsMapiConnectClass.prototype = {
constructor: advadsMapiConnectClass,
// Set options, for re-use of existing instance for a different purpose.
setOptions(options) {
const defaultOptions = {
onSuccess: false,
onError: false,
};
if ('undefined' === typeof options) {
options = defaultOptions;
}
this.options = $.extend({}, defaultOptions, options);
},
// Tasks to do after a successful connection.
exit() {
if (this.options.onSuccess) {
if ('function' === typeof this.options.onSuccess) {
this.options.onSuccess(this);
}
} else {
this.hide();
}
},
// Submit OAuth2 code for account connection.
submitOAuthCode(code) {
const self = this;
if (!code) {
return;
}
const overlay = $('.gadsense-overlay').css('display', 'block'),
codeInput = $('mapi-code');
$('#gadsense-modal-error').hide();
$.ajax({
url: ajaxurl,
type: 'post',
data: {
action: 'advads_gadsense_mapi_confirm_code',
code,
nonce: AdsenseMAPI.nonce,
},
success(response) {
codeInput.val('');
if (
response.data.status &&
true === response.data.status &&
response.data.token_data
) {
self.getAccountDetails(response.data.token_data);
} else {
// Connection error handling.
console.error(response);
overlay.css('display', 'none');
codeInput.val('');
$(
'#gadsense-modal-content-inner .dashicons-dismiss'
).trigger('click');
}
},
error() {
$('#gadsense-loading-overlay').css('display', 'none');
},
});
},
// Initialization - mostly binding events.
init() {
const that = this;
// Close the modal and hide errors.
$(document).on(
'click',
'#gadsense-modal .dashicons-dismiss',
function () {
that.hide();
}
);
// Account selection
$(document).on(
'click',
'.gadsense-modal-content-inner[data-content="account-selector"] button',
function () {
const adsenseID = $('#mapi-select-account').val();
let tokenData = false;
const tokenString = $(
'.gadsense-modal-content-inner[data-content="account-selector"] input.token-data'
).val();
let details = false;
const detailsString = $(
'.gadsense-modal-content-inner[data-content="account-selector"] input.accounts-details'
).val();
try {
tokenData = JSON.parse(tokenString);
} catch (Ex) {
console.error('Bad token data : ' + tokenString);
}
try {
details = JSON.parse(detailsString);
} catch (Ex) {
console.error('Bad account details : ' + detailsString);
}
if (details) {
$('.gadsense-overlay').css('display', 'block');
$.ajax({
url: ajaxurl,
type: 'post',
data: {
action: 'advads_gadsense_mapi_select_account',
nonce: AdsenseMAPI.nonce,
account: details[adsenseID],
token_data: tokenData,
},
success(response) {
if (
response.data.status &&
true === response.data.status
) {
INSTANCE.exit();
} else {
console.log(response);
}
},
error() {
$('#gadsense-loading-overlay').css(
'display',
'none'
);
},
});
}
}
);
},
// Get account info based on a newly obtained token.
getAccountDetails(tokenData) {
const data = {
action: 'advads_gadsense_mapi_get_details',
nonce: AdsenseMAPI.nonce,
};
data.token_data = tokenData;
$.ajax({
url: ajaxurl,
type: 'post',
data,
success(response) {
if (response.success && true === response.success) {
if (response.data && response.data.reload) {
INSTANCE.exit();
} else if (response.data && response.data.token_data) {
INSTANCE.switchContent('account-selector');
INSTANCE.frame
.find('select')
.html(response.data.html);
INSTANCE.frame
.find('input.token-data')
.val(JSON.stringify(response.data.token_data));
INSTANCE.frame
.find('input.accounts-details')
.val(JSON.stringify(response.data.details));
} else {
INSTANCE.switchContent('error');
INSTANCE.frame
.find('.error-message')
.text(JSON.stringify(response));
}
}
},
error(request) {
if (request.responseJSON) {
if (request.responseJSON.data.error) {
INSTANCE.switchContent('error');
INSTANCE.frame
.find('.error-message')
.text(request.responseJSON.data.error);
if (
typeof AdsenseMAPI.connectErrorMsg[
request.responseJSON.data.error
] !== 'undefined'
) {
INSTANCE.frame
.find('.error-description')
.html(
AdsenseMAPI.connectErrorMsg[
request.responseJSON.data.error
]
);
}
} else if (request.responseJSON.data.message) {
INSTANCE.frame
.find('.error-message')
.text(request.responseJSON.data.message);
}
return;
}
$('#gadsense-loading-overlay').css('display', 'none');
},
});
},
// Switch between frames in the modal container.
switchContent(content) {
if (
this.modal.find(
'.gadsense-modal-content-inner[data-content="' +
content +
'"]'
).length
) {
this.modal
.find('.gadsense-modal-content-inner')
.css('display', 'none');
this.frame = this.modal.find(
'.gadsense-modal-content-inner[data-content="' +
content +
'"]'
);
this.frame.css('display', 'block');
$('.gadsense-overlay').css('display', 'none');
}
},
// Show the modal frame with a given content.
show(content) {
if ('undefined' === typeof content) {
content = 'confirm-code';
}
this.switchContent(content);
if ('open-google' === content) {
window.location.href = AdsenseMAPI.oAuth2;
} else {
this.modal.css('display', 'block');
}
},
// Hide the modal frame
hide() {
window.location.href = this.modal.attr('data-return');
},
};
window.advadsMapiConnectClass = advadsMapiConnectClass;
// Shortcut function.
window.advadsMapiConnect = function (content, options) {
if ('undefined' === typeof content || !content) {
content = 'confirm-code';
}
if ('undefined' === typeof options) {
options = {};
}
if (null === INSTANCE) {
INSTANCE = new advadsMapiConnectClass(content, options);
} else {
INSTANCE.show(content, options);
}
};
$(function () {
// Move the the pop-up outside of any form.
$('#wpwrap').append($('#gadsense-modal'));
if ($('#advads-adsense-oauth-code').length) {
INSTANCE = new advadsMapiConnectClass('confirm-code', {});
INSTANCE.submitOAuthCode($('#advads-adsense-oauth-code').val());
}
});
})(window.jQuery);

View File

@@ -0,0 +1,139 @@
/**
* Advanced Ads.
*
* @author Thomas Maier <support@wpadvancedads.com>
* @license GPL-2.0+
* @link https://wpadvancedads.com
* @copyright 2013-2018 Thomas Maier, Advanced Ads GmbH
*/
;(function($){
/**
* Print Google AdSense account alerts after connecting to the API or after removing an alert.
*
* @param alerts
*/
function printAlerts( alerts ) {
var $div = $( '#mapi-account-alerts' );
$div.empty();
if ( alerts.length ) {
$div.append( $( '<h3 />' ).html( AdsenseMAPI.alertsHeadingMsg ) );
for ( var id in alerts.alerts ) {
var $alertBox = $( '<div class="card advads-notice-block advads-error"/>' );
var $dismissButton = $( ' <button type="button" class="mapi-dismiss-alert notice-dismiss" data-id="' + alerts.alerts[id]['id'] + '"><span class="screen-reader-text">' + AdsenseMAPI.alertsDismissMsg + '</span></button>' );
var msg = alerts.alerts[id].message;
if ( typeof AdsenseMAPI.alertsMsg[alerts.alerts[id]['id']] !== 'undefined' ) {
msg = AdsenseMAPI.alertsMsg[alerts.alerts[id]['id']];
}
$alertBox.append( $dismissButton );
$alertBox.append( msg );
$div.append( $alertBox );
}
}
}
$( document ).on( 'click', '.preventDefault', function( ev ) {
ev.preventDefault();
} );
$( document ).on( 'keypress', '#adsense input[type="text"]', function( ev ) {
if ( $( this ).hasClass( 'preventDefault' ) ) {
ev.preventDefault();
return;
}
if ( ev.which == 13 || ev.keyCode == 13 ) {
$( '#adsense .advads-settings-tab-main-form #submit' ).trigger( 'click' );
}
} );
$( document ).on( 'click', '#revoke-token', function(){
$( '#gadsense-freeze-all' ).css( 'display', 'block' );
var ID = $( '#adsense-id' ).val();
$.ajax({
url: ajaxurl,
type: 'post',
data: {
action: 'advads-mapi-revoke-token',
adsenseId: ID,
nonce: AdsenseMAPI.nonce,
},
success:function(response, status, XHR){
window.location.reload();
},
error:function(request, status, error){
$( '#gadsense-freeze-all' ).css( 'display', 'none' );
},
});
} );
$( document ).on( 'click', '#adsense-manual-config', function(){
$( '#adsense .form-table tr' ).css( 'display', 'table-row' );
$( '#adsense #auto-adsense-settings-div' ).css( 'display', 'none' );
$( '#adsense #full-adsense-settings-div' ).css( 'display', 'block' );
$( '#adsense-id' ).after( $( '#connect-adsense' ) );
$( '#adsense #submit' ).parent().show();
} );
// Open the code confirmation modal.
$( document ).on( 'click', '#connect-adsense', function(){
if ( $( this ).hasClass( 'disabled' ) ) return;
if ( 'undefined' != typeof window.advadsMapiConnect ) {
window.advadsMapiConnect( 'open-google' );
}
} );
$( document ).on( 'click', '.mapi-dismiss-alert', function( ev ) {
ev.preventDefault();
var pubId = $( '#adsense-id' ).val();
var alertId = $( this ).attr( 'data-id' );
$( '#gadsense-modal' ).css( 'display', 'block' );
$( '#gadsense-modal-outer' ).css( 'display', 'none' );
$.ajax({
url: ajaxurl,
type: 'post',
data: {
action: 'advads-mapi-dismiss-alert',
account: pubId,
id: alertId,
nonce: AdsenseMAPI.nonce,
},
success:function(response, status, XHR){
if ( 'undefined' != typeof response.alerts ) {
printAlerts( response );
}
$( '#gadsense-modal' ).css( 'display', 'none' );
$( '#gadsense-modal-outer' ).css( 'display', 'block' );
},
error:function(request, status, error){
$( '#gadsense-modal' ).css( 'display', 'none' );
$( '#gadsense-modal-outer' ).css( 'display', 'block' );
},
});
} );
$( document ).on( 'click', '.mapi-create-ads-txt', function( ev ) {
ev.preventDefault();
var top = jQuery( '#advads-ads-txt-wrapper' ).offset().top;
window.scrollTo( 0, top );
} );
$( document ).on( 'advadsMapiRefreshAlerts', function ( ev, response ) {
if ( 'undefined' != typeof response.status && response.status && response.alerts ) {
printAlerts( response );
}
} );
$( function(){
if ( $( '#adsense-id' ).val().trim() === '' ) {
$( '#adsense #submit' ).parent().css( 'display', 'none' );
}
} );
})(window.jQuery);

View File

@@ -0,0 +1,325 @@
<?php // phpcs:ignoreFile
/**
* View for the Settings - AdSense.
*
* @package Advanced_Ads
*/
use AdvancedAds\Utilities\Conditional;
$MAPI = Advanced_Ads_AdSense_MAPI::get_instance();
$options = $this->data->get_options();
$adsense_id = $this->data->get_adsense_id();
$mapi_options = Advanced_Ads_AdSense_MAPI::get_option();
$mapi_account_details = false;
$CID = Advanced_Ads_AdSense_MAPI::CID;
$use_user_app = Advanced_Ads_AdSense_MAPI::use_user_app();
if ( $use_user_app ) {
$CID = ADVANCED_ADS_MAPI_CID;
}
$can_connect = true;
if ( $use_user_app && !( ( defined( 'ADVANCED_ADS_MAPI_CID' ) && '' != ADVANCED_ADS_MAPI_CID ) && ( defined( 'ADVANCED_ADS_MAPI_CIS' ) && '' != ADVANCED_ADS_MAPI_CIS ) ) ) {
$can_connect = false;
}
$has_token = Advanced_Ads_AdSense_MAPI::has_token( $adsense_id );
if ( $has_token && isset( $mapi_options['accounts'][ $adsense_id ]['details'] ) ) {
$mapi_account_details = $mapi_options['accounts'][ $adsense_id ]['details'];
}
$alerts = Advanced_Ads_AdSense_MAPI::get_stored_account_alerts( $adsense_id );
/* translators: 1: opening anchor tag for link to adsense account 2: closing anchor tag for link to adsense account */
$alerts_heading = $adsense_id ? sprintf( esc_html__( 'Warning from your %1$sAdSense account%2$s', 'advanced-ads' ), '<a target="_blank" href="https://www.google.com/adsense/new/u/1/' . esc_html( $adsense_id ) . '/">', '</a>' ) : esc_html__( 'AdSense warnings', 'advanced-ads' );
$alerts_heading = $adsense_id
? wp_kses(
sprintf(
/* translators: 1: opening anchor tag for link to adsense account 2: closing anchor tag for link to adsense account */
__( 'Warning from your %1$sAdSense account%2$s', 'advanced-ads' ),
'<a target="_blank" href="https://www.google.com/adsense/new/u/1/' . $adsense_id . '/">',
'</a>'
),
[
'a' => [
'target' => true,
'href' => true,
],
]
)
: __( 'AdSense warnings', 'advanced-ads' );
$alerts_dismiss = __( 'dismiss', 'advanced-ads' );
$connection_error_messages = Advanced_Ads_AdSense_MAPI::get_connect_error_messages();
$alerts_advads_messages = Advanced_Ads_Adsense_MAPI::get_adsense_alert_messages();
?>
<div id="mapi-account-alerts">
<?php if ( is_array( $alerts ) && isset( $alerts['items'] ) && is_array( $alerts['items'] ) && $alerts['items'] ) : ?>
<h3>
<?php
//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- already escaped
echo $alerts_heading;
?>
</h3>
<?php foreach ( $alerts['items'] as $alert_id => $alert ) : ?>
<div class="card advads-notice-block advads-error">
<button type="button" class="mapi-dismiss-alert notice-dismiss" data-id="<?php echo esc_attr( $alert_id ); ?>">
<span class="screen-reader-text"><?php echo esc_html( $alerts_dismiss ); ?></span>
</button>
<?php
$internal_id = $alert['id'] ?? str_replace( '-', '_', strtoupper( $alert['type'] ) );
echo wp_kses(
$alerts_advads_messages[ $internal_id ] ?? $alert['message'],
[
'a' => [
'href' => true,
'target' => true,
'class' => true,
],
]
);
?>
</div>
<?php endforeach; ?>
<?php /* translators: %s: date and time of last check in the format set in wp_options */ ?>
<p class="description alignright"><?php printf( __( 'last checked: %s', 'advanced-ads' ), $alerts['lastCheck'] ? esc_html( ( new DateTime( '@' . $alerts['lastCheck'], Advanced_Ads_Utils::get_wp_timezone() ) )->format( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) ) ) : '-' ); ?></p>
<?php endif; ?>
<?php
if ( ! empty( $mapi_options['connect_error'] ) ) {
$message = isset( $mapi_options['connect_error']['message'] ) ? $mapi_options['connect_error']['message'] : '';
if ( isset( $connection_error_messages[ $mapi_options['connect_error']['reason'] ] ) ) {
$message = $connection_error_messages[ $mapi_options['connect_error']['reason'] ];
}
if ( ! empty( $message ) ) {
echo '<div id="mapi-connect-errors" class="notice error inline"><p class="advads-notice-inline advads-error">';
echo wp_kses( $message, [
'a' => [
'id' => [],
'class' => [],
'href' => [],
'style' => [],
],
'i' => [
'id' => [],
'class' => [],
'style' => [],
],
] );
echo '</p></div>';
}
}
?>
</div>
<div id="full-adsense-settings-div" <?php if ( empty( $adsense_id ) ) echo 'style="display:none"' ?>>
<input type="text" <?php echo $has_token ? 'readonly' : ''; ?> name="<?php echo esc_attr( GADSENSE_OPT_NAME ); ?>[adsense-id]" placeholder="pub-1234567891234567" style="margin-right:.8em" id="adsense-id" size="32" value="<?php echo esc_attr( $adsense_id ); ?>"/>
<?php if ( !empty( $adsense_id ) && !$has_token ) : ?>
<a id="connect-adsense" class="button-primary <?php echo ! Advanced_Ads_Checks::php_version_minimum() ? 'disabled ' : ''; ?>preventDefault" <?php if ( ! $can_connect || ! Advanced_Ads_Checks::php_version_minimum() ) echo 'disabled'; ?>><?php esc_attr_e( 'Connect to AdSense', 'advanced-ads' ) ?></a>
<?php endif; ?>
<?php if ( $has_token ) : ?>
<a id="revoke-token" class="button-secondary preventDefault"><?php esc_attr_e( 'Revoke API acccess', 'advanced-ads' ) ?></a>
<div id="gadsense-freeze-all" style="position:fixed;top:0;bottom:0;right:0;left:0;background-color:rgba(255,255,255,.5);text-align:center;display:none;">
<img alt="..." src="<?php echo ADVADS_BASE_URL . 'admin/assets/img/loader.gif'; ?>" style="margin-top:40vh" />
</div>
<?php endif; ?>
<?php if ( $mapi_account_details ) : ?>
<p class="description"><?php esc_html_e( 'Account holder name', 'advanced-ads' ); echo ': <strong>' . esc_html( $mapi_account_details['name'] ) . '</strong>'; ?></p>
<?php else : ?>
<?php if ( 0 !== strpos( $adsense_id, 'pub-' ) ) : ?>
<p class="advads-notice-inline advads-error"><?php esc_html_e( 'The Publisher ID has an incorrect format. (must start with "pub-")', 'advanced-ads' ); ?></p>
<?php endif; ?>
<?php endif; ?>
</div>
<?php if ( empty( $adsense_id ) ) : ?>
<div id="auto-adsense-settings-div" <?php if ( !empty( $adsense_id ) ) echo 'style="display:none;"' ?>>
<div class="widget-col">
<h3><?php _e( 'Yes, I have an AdSense account', 'advanced-ads' ) ?></h3>
<a id="connect-adsense" class="button-primary <?php echo ! Advanced_Ads_Checks::php_version_minimum() ? 'disabled ' : ''; ?>preventDefault" <?php echo ! Advanced_Ads_Checks::php_version_minimum() ? 'disabled' : ''; ?>><?php _e( 'Connect to AdSense', 'advanced-ads' ) ?></a>
<a id="adsense-manual-config" class="button-secondary preventDefault"><?php _e( 'Configure everything manually', 'advanced-ads' ) ?></a>
</div>
<div class="widget-col">
<h3><?php _e( "No, I still don't have an AdSense account", 'advanced-ads' ) ?></h3>
<a class="button button-secondary" target="_blank" href="<?php echo Advanced_Ads_AdSense_Admin::ADSENSE_NEW_ACCOUNT_LINK; ?>"><?php _e( 'Get a free AdSense account', 'advanced-ads' ); ?></a>
<p>
<?php
printf(
wp_kses(
/* translators: %1$s is an opening a tag, %2$s is the closing one */
__( 'See all %1$srecommended ad networks%2$s.', 'advanced-ads' ),
[
'a' => [
'href' => [],
'target' => [],
],
]
),
'<a href="https://wpadvancedads.com/recommended-ad-networks/?utm_source=advanced-ads&utm_medium=link&utm_campaign=recommendations" target="_blank">',
'</a>'
);
?>
</p>
</div>
</div>
<style type="text/css">
#adsense table h3 {
margin-top: 0;
margin-bottom: .2em;
}
#adsense .form-table tr {
display: none;
}
#adsense .form-table tr:first-of-type {
display: table-row;
}
#auto-adsense-settings-div .widget-col {
float: left;
margin: 0px 5px 5px 0px;
}
#auto-adsense-settings-div:after {
display: block;
content: "";
clear: left;
}
#auto-adsense-settings-div .widget-col:first-child {
margin-right: 20px;
border-right: 1px solid #cccccc;
padding: 0px 20px 0px 0px;
position: relative;
}
#auto-adsense-settings-div .widget-col:first-child:after {
position: absolute;
content: "or";
display: block;
top: 20px;
right: -10px;
background: #ffffff;
color: #cccccc;
font-size: 20px;
}
@media screen and (max-width: 1199px) {
#auto-adsense-settings-div .widget-col { float: none; margin-right: 0; }
#auto-adsense-settings-div .widget-col:first-child { margin: 0px 0px 20px 0px; padding: 0px 0px 20px 0px; border-bottom: 1px solid #cccccc; border-right: 0; }
#auto-adsense-settings-div .widget-col:first-child:after { top: auto; right: auto; bottom: -10px; left: 20px; display: inline-block; padding: 0px 5px 0px 5px; }
}
</style>
<?php
echo "<br/><br/><br/><hr>";
include ADVADS_ABSPATH . 'modules/gadsense/admin/views/auto-ads-video.php';
?><p>
<a href="https://wpadvancedads.com/place-adsense-ad-unit-manually/?utm_source=advanced-ads&utm_medium=link&utm_campaign=adsense-manually" style="text-decoration: none;" target="_blank"><span class="dashicons dashicons-welcome-learn-more"></span>
<?php
esc_attr_e( 'How to choose specific positions for AdSense ad units', 'advanced-ads' ); ?></a>
</p>
<?php
$_notice = 'nl_adsense';
if ( Advanced_Ads_Admin_Notices::get_instance()->can_display( $_notice ) && Conditional::user_can_subscribe( 'nl_first_steps' ) ) {
$box_classes = '!margin-top-4';
$text = sprintf(
/* translators: %s: number of add-ons. */
__( 'Subscribe to our free email course for Google AdSense, receive our newsletter for periodic tutorials, and get %s for Advanced Ads.', 'advanced-ads' ),
'<strong>' . __( '2 free add-ons', 'advanced-ads' ) . '</strong>'
);
include ADVADS_ABSPATH . '/admin/views/notices/inline.php';
}
?>
<?php else : ?>
<p>
<?php
printf(
wp_kses(
/* translators: %1$s is the opening link tag to our manual; %2$s is the appropriate closing link tag; %3$s is the opening link tag to our help forum; %4$s is the appropriate closing link tag */
__( 'Problems with AdSense? Check out the %1$smanual%2$s or %3$sask here%4$s.', 'advanced-ads' ),
[
'a' => [
'href' => [],
'target' => [],
],
]
),
'<a href="https://wpadvancedads.com/adsense-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=adsense-manual-check" target="_blank">',
'</a>',
'<a href="https://wordpress.org/support/plugin/advanced-ads/#new-post" target="_blank">',
'</a>'
); ?></p>
<p>
<?php
printf(
wp_kses(
/* translators: %1$s is an opening a tag, %2$s is the closing one */
__( 'See all %1$srecommended ad networks%2$s.', 'advanced-ads' ),
[
'a' => [
'href' => [],
'target' => [],
],
]
),
'<a href="https://wpadvancedads.com/recommended-ad-networks/?utm_source=advanced-ads&utm_medium=link&utm_campaign=recommendations" target="_blank">',
'</a>'
);
?>
</p><?php endif; ?>
<?php if ( ! Advanced_Ads_Checks::php_version_minimum() ) : ?>
<p class="advads-notice-inline advads-error"><?php esc_html_e( 'Can not connect AdSense account. PHP version is too low.', 'advanced-ads' ); ?></p>
<?php endif; ?>
<div id="mapi-alerts-overlay">
<div style="position:relative;text-align:center;display:table;width:100%;height:100%;">
<div style="display:table-cell;vertical-align:middle;">
<img alt="loading" src="<?php echo esc_url( ADVADS_BASE_URL . 'admin/assets/img/loader.gif' ); ?>" />
</div>
</div>
</div>
<script type="text/javascript">
if ( 'undefined' == typeof window.AdsenseMAPI ) {
AdsenseMAPI = {};
}
AdsenseMAPI = Object.assign(
AdsenseMAPI,
<?php
echo wp_json_encode(
[
'alertsMsg' => $alerts_advads_messages,
'alertsHeadingMsg' => $alerts_heading,
'alertsDismissMsg' => wp_kses( $alerts_dismiss, [] ),
]
)
?>
);
</script>
<style type="text/css">
#adsense {
position: relative;
}
#mapi-alerts-overlay {
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
background-color: rgb(255, 255, 255, .90);
display: none;
}
#mapi-account-alerts, #mapi-connect-errors {
margin-bottom: .5em;
}
#dissmiss-connect-error {
cursor: pointer;
}
#gadsense-overlay {
display:none;
background-color:rgba(255,255,255,.5);
position:absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
text-align:center;
}
</style>

View File

@@ -0,0 +1,197 @@
<?php // phpcs:ignoreFile
/**
* Renders the AdSense ad parameters metabox on the ad edit page.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
*
* @var string $unit_type The type of the AdSense unit, e.g. 'responsive'.
* @var string $unit_resize The value of the resize option.
* @var string $unit_id The client ID.
* @var string $unit_code The slot ID.
* @var string $unit_pubid The publisher ID which differs if there comes a different it from the content.
* @var string $json_content The content as JSON.
* @var string $pub_id The publisher ID.
* @var Advanced_Ads_Ad_Type_Adsense $ad The AdSense Ad type.
* @var string $pub_id_errors A string with error messages.
* @var string $content The content.
* @var array $extra_params Filterable extra params that can be passed.
*/
if ( ! defined( 'WPINC' ) ) {
die();
}
$is_responsive = 'responsive' === $unit_type;
$is_link_responsive_unit = 'link-responsive' === $unit_type;
$is_matched_content = 'matched-content' === $unit_type;
$use_manual_css = 'manual' === $unit_resize;
if ( $is_responsive || $is_link_responsive_unit || $is_matched_content ) {
echo '<style> #advanced-ads-ad-parameters-size {display: none;} </style>';
}
$MAPI = Advanced_Ads_AdSense_MAPI::get_instance();
$use_user_app = Advanced_Ads_AdSense_MAPI::use_user_app();
$use_paste_code = true;
$use_paste_code = apply_filters( 'advanced-ads-gadsense-use-pastecode', $use_paste_code );
$db = Advanced_Ads_AdSense_Data::get_instance();
$adsense_id = trim( $db->get_adsense_id() );
$sizing_array = $db->get_responsive_sizing();
$gadsense_options = $db->get_options();
$mapi_options = Advanced_Ads_AdSense_MAPI::get_option();
$mapi_nonce = wp_create_nonce( 'advads-mapi' );
$has_token = Advanced_Ads_AdSense_MAPI::has_token( $adsense_id );
$quota = $MAPI->get_quota();
$mapi_ad_codes = $mapi_options['ad_codes'];
$mapi_ad_codes['length'] = count( $mapi_ad_codes );
?>
<?php if ( $has_token ) : ?>
<script type="text/javascript">
if ( 'undefined' == typeof window.AdsenseMAPI ) {
var AdsenseMAPI = {};
}
AdsenseMAPI.hasToken = true;
AdsenseMAPI.nonce = '<?php echo $mapi_nonce ?>';
//AdsenseMAPI.codes = <?php echo json_encode( $mapi_ad_codes ) ?>;
AdsenseMAPI.quota = <?php echo json_encode( $quota ) ?>;
AdsenseMAPI.pubId = '<?php echo $pub_id ?>';
AdsenseMAPI.adStatus = '<?php echo $ad->get_status() ?>';
AdsenseMAPI.unsupportedUnits = <?php echo wp_json_encode( $mapi_options['unsupported_units'] ); ?>;
</script>
<?php endif; ?>
<script type="text/javascript">
if ( 'undefined' === typeof gadsenseData ) {
window.gadsenseData = {};
}
gadsenseData['pubId'] = '<?php echo $adsense_id; ?>';
gadsenseData['msg'] = {
unknownAd: '<?php esc_attr_e( "The ad details couldn't be retrieved from the ad code", 'advanced-ads' ); ?>',
pubIdMismatch: '<?php esc_attr_e( 'Warning: The AdSense account from this code does not match the one set in the Advanced Ads options.', 'advanced-ads' ); ?>'
};
</script>
<input type="hidden" id="advads-ad-content-adsense" name="advanced_ad[content]" value="<?php echo esc_attr( $json_content ); ?>"/>
<input type="hidden" name="unit_id" id="unit_id" value="<?php echo esc_attr( $unit_id ); ?>"/>
<?php if ( $use_paste_code ) : ?>
<div class="advads-adsense-code" style="display: none;">
<p class="description"><?php _e( 'Copy the ad code from your AdSense account, paste it into the area below and click on <em>Get details</em>.', 'advanced-ads' ); ?></p>
<textarea rows="10" cols="40" class="advads-adsense-content"></textarea>
<button class="button button-primary advads-adsense-submit-code"><?php _e( 'Get details', 'advanced-ads' ); ?></button>&nbsp;&nbsp;
<button class="button button-secondary advads-adsense-close-code"><?php _e( 'cancel', 'advanced-ads' ); ?></button>&nbsp;&nbsp;
<?php if ( ! $has_token ) : ?>
<a style="vertical-align:sub;font-weight:600;font-style:italic;" href="<?php echo admin_url( 'admin.php?page=advanced-ads-settings#top#adsense' ) ?>"><?php _e( 'connect to your AdSense account', 'advanced-ads' ) ?></a>
<?php endif; ?>
<div id="pastecode-msg"></div>
</div>
<?php if ( $has_token && Advanced_Ads_Checks::php_version_minimum() ) {
Advanced_Ads_AdSense_Admin::get_mapi_ad_selector();
}
// the network variable needs to be set for the view to work!
$network = Advanced_Ads_Network_Adsense::get_instance();
include( ADVADS_ABSPATH . '/modules/gadsense/admin/views/external-ads-links.php' );
?>
<?php endif; ?>
<p id="adsense-ad-param-error"></p>
<?php ob_start(); ?>
<label class="label"><?php _e( 'Ad Slot ID', 'advanced-ads' ); ?></label>
<div>
<input type="text" name="unit-code" id="unit-code" value="<?php echo $unit_code; ?>"/>
<input type="hidden" name="advanced_ad[output][adsense-pub-id]" id="advads-adsense-pub-id" value="<?php echo esc_attr( $unit_pubid ); ?>"/>
<?php if ( $unit_pubid ) : ?>
<?php /* translators: %s is the publisher ID. */
printf( __( 'Publisher ID: %s', 'advanced-ads' ), $unit_pubid ); ?>
<?php endif; ?>
<p id="advads-pubid-in-slot" class="advads-notice-inline advads-error"
<?php echo ! ( 0 === strpos( $pub_id, 'pub-' ) && false !== strpos( $unit_code, substr( $pub_id, 4 ) ) ) ? 'style="display:none"' : ''; ?>
><?php _e( 'The ad slot ID is either a number or empty and not the same as the publisher ID.', 'advanced-ads' ) ?></p>
</div>
<hr/>
<?php
$unit_code_markup = ob_get_clean();
echo apply_filters( 'advanced-ads-gadsense-unit-code-markup', $unit_code_markup, $unit_code );
if ( $pub_id_errors ) : ?>
<p>
<span class="advads-notice-inline advads-error">
<?php echo $pub_id_errors; ?>
</span>
<?php /* translators: %s the setting page link */
printf( __( 'Please <a href="%s" target="_blank">change it here</a>.', 'advanced-ads' ), admin_url( 'admin.php?page=advanced-ads-settings#top#adsense' ) ); ?>
</p>
<?php endif; ?>
<label class="label" id="unit-type-block"><?php _e( 'Type', 'advanced-ads' ); ?></label>
<div>
<select name="unit-type" id="unit-type">
<option value="normal" <?php selected( $unit_type, 'normal' ); ?>><?php _e( 'Fixed Size', 'advanced-ads' ); ?></option>
<option value="responsive" <?php selected( $unit_type, 'responsive' ); ?>><?php _e( 'Responsive', 'advanced-ads' ); ?></option>
<option value="matched-content" <?php selected( $unit_type, 'matched-content' ); ?>><?php esc_html_e( 'Multiplex', 'advanced-ads' ); ?></option>
<?php if ( $unit_type === 'link' ) : ?>
<option value="link" <?php selected( $unit_type, 'link' ); ?>><?php _e( 'Link ads', 'advanced-ads' ); ?></option>
<?php endif; ?>
<?php if ( $unit_type === 'link-responsive' ) : ?>
<option value="link-responsive" <?php selected( $unit_type, 'link-responsive' ); ?>><?php _e( 'Link ads (Responsive)', 'advanced-ads' ); ?></option>
<?php endif; ?>
<option value="in-article" <?php selected( $unit_type, 'in-article' ); ?>><?php _e( 'In-article', 'advanced-ads' ); ?></option>
<option value="in-feed" <?php selected( $unit_type, 'in-feed' ); ?>><?php _e( 'In-feed', 'advanced-ads' ); ?></option>
</select>
<a href="https://wpadvancedads.com/google-adsense-ad-formats/?utm_source=advanced-ads&utm_medium=link&utm_campaign=adsense-ad-types" class="advads-manual-link" target="_blank"><?php esc_html_e( 'Manual', 'advanced-ads' ); ?></a>
</div>
<?php if ( in_array( $unit_type, [ 'link', 'link-responsive' ], true ) ) : ?>
<p class="advads-message-warning"><?php esc_html_e( 'Google AdSense deprecated Link Units. Please choose another type.', 'advanced-ads' ); ?>
<a href="https://wpadvancedads.com/adsense-link-units/" target="_blank" rel="noopener">
<?php esc_html_e( 'Learn more', 'advanced-ads' ); ?>
</a>
</p>
<?php endif; ?>
<hr/>
<label class="label" <?php if ( ! $is_responsive || 2 > count( $sizing_array ) ) {
echo 'style="display: none;"';
} ?> id="resize-label"><?php _e( 'Resizing', 'advanced-ads' ); ?></label>
<div <?php if ( ! $is_responsive || 2 > count( $sizing_array ) ) {
echo 'style="display: none;"';
} ?>>
<select name="ad-resize-type" id="ad-resize-type">
<?php foreach ( $sizing_array as $key => $desc ) : ?>
<option value="<?php echo $key; ?>" <?php selected( $key, $unit_resize ); ?>><?php echo $desc; ?></option>
<?php endforeach; ?>
</select>
</div>
<hr>
<label class="label advads-adsense-layout" <?php if ( 'in-feed' !== $unit_type ) {
echo 'style="display: none;"';
} ?> id="advads-adsense-layout"><?php _e( 'Layout', 'advanced-ads' ); ?></label>
<div <?php if ( 'in-feed' !== $unit_type ) {
echo 'style="display: none;"';
} ?>>
<input name="ad-layout" id="ad-layout" value="<?php echo isset( $layout ) ? $layout : ''; ?>"/>
</div>
<hr>
<label class="label advads-adsense-layout-key" <?php if ( 'in-feed' !== $unit_type ) {
echo 'style="display: none;"';
} ?> id="advads-adsense-layout-key"><?php _e( 'Layout-Key', 'advanced-ads' ); ?></label>
<div <?php if ( 'in-feed' !== $unit_type ) {
echo 'style="display: none;"';
} ?>>
<input type="text" name="ad-layout-key" id="ad-layout-key" value="<?php echo $layout_key ?? ''; ?>"/>
</div>
<hr/>
<label class="label clearfix-before" <?php if ( ! $is_responsive ) {
echo 'style="display: none;"';
} ?>><?php _e( 'Clearfix', 'advanced-ads' ); ?></label>
<div class="clearfix-before" <?php if ( ! $is_responsive ) {
echo 'style="display: none;"';
} ?>>
<input type="checkbox" name="advanced_ad[output][clearfix_before]" value="1" <?php checked( ! empty( $options['output']['clearfix_before'] ), true ); ?> />
<p class="description">
<?php _e( 'Enable this if responsive ads cover something on your site.', 'advanced-ads' ); ?>
</p>
</div>
<hr class="clearfix-before" <?php if ( ! $is_responsive ) {
echo 'style="display: none;"';
} ?> />
<?php do_action( 'advanced-ads-gadsense-extra-ad-param', $extra_params, $content, $ad );

View File

@@ -0,0 +1,37 @@
<?php
/**
* AdSense report markup.
*
* @var Advanced_Ads_AdSense_Report $this report instance.
* @var array $report_domains domain names included in the report.
* @var string $report_filter ad unit or domain name to filter the output with.
* @var array $sums daily sums of earnings.
* @var string $earning_cells markup for each earning period.
*/
$time_zone = Advanced_Ads_Utils::get_wp_timezone();
$data_timestamp = date_create( '@' . $this->get_data()->get_timestamp() );
$data_timestamp->setTimezone( $time_zone );
?>
<div class="advads-flex">
<?php echo wp_kses_post( $earning_cells ); ?>
<div class="advads-flex1 advads-stats-box">
<?php if ( $this->type === 'domain' ) : // Adds the dropdown list of domain names. ?>
<div class="advads-stats-dd-container">
<div class="advads-stats-dd-button"><span class="dashicons dashicons-admin-multisite"></span>
<div class="advads-stats-dd-items">
<div class="advads-stats-dd-item<?php echo in_array( $report_filter, [ '*', '' ], true ) ? ' current-filter' : ''; ?>" data-domain="*">
<?php esc_html_e( 'All', 'advanced-ads' ); ?>
</div><!-- .advads-stats-dd-item -->
<?php foreach ( $report_domains as $domain_name ) : ?>
<div class="advads-stats-dd-item<?php echo ( $domain_name === $report_filter ) ? ' current-filter' : ''; ?>" data-domain="<?php echo esc_attr( $domain_name ); ?>">
<?php echo esc_html( $domain_name ); ?>
</div><!-- .advads-stats-dd-item -->
<?php endforeach; ?>
</div><!-- .advads-stats-dd-items -->
</div><!-- .advads-stats-dd-button -->
</div><!-- .advads-stats-dd-container -->
<?php endif; ?>
<div class="advads-stats-age"><?php echo esc_html( $data_timestamp->format( get_option( 'time_format' ) ) ); ?></div>
</div><!-- .advads-stats-box-->
</div><!-- .advads-flex -->

View File

@@ -0,0 +1,16 @@
<div id="advads-auto-ads-links">
<a id="advads-auto-ads-video-link" style="cursor: pointer;">
<span class="dashicons dashicons-format-video"></span>&nbsp;<?php
esc_attr_e( 'How to enable Auto ads in 30 seconds (video tutorial)', 'advanced-ads' ); ?>
</a>
</div>
<script>
(function ($) {
var $videoLink = $('#advads-auto-ads-video-link');
$videoLink.click(function () {
$('<br class="clear"/><br/><iframe src="https://player.vimeo.com/video/381874350" width="640" height="360" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>').appendTo('#advads-auto-ads-links');
$(this).remove();
})
.children('.dashicons').css('line-height', $videoLink.css('line-height'));
})(jQuery)
</script>

View File

@@ -0,0 +1,11 @@
<?php printf(
wp_kses(
/* translators: 1: the plugin name that is managing the Auto ads code. */
__( 'Advanced Ads detected that <strong>%s</strong> is managing the Auto ads code and will therefore not add it.', 'advanced-ads' ),
[
'strong' => [],
]
),
'Borlabs Cookies'
);

View File

@@ -0,0 +1,148 @@
<?php
/**
* HTML markup for AdSense connection modal frame.
*
* @package AdvancedAds
*/
use AdvancedAds\Framework\Utilities\Params;
use AdvancedAds\Utilities\Conditional;
$data_obj = Advanced_Ads_AdSense_Data::get_instance();
$options = $data_obj->get_options();
$nonce = wp_create_nonce( 'advads-mapi' );
$cid = Advanced_Ads_AdSense_MAPI::CID;
$use_user_app = Advanced_Ads_AdSense_MAPI::use_user_app();
if ( $use_user_app ) {
$cid = ADVANCED_ADS_MAPI_CID;
}
$state = [
'api' => 'adsense',
'nonce' => $nonce,
'return_url' => admin_url( 'admin.php?page=advanced-ads-settings&oauth=1#top#adsense' ),
];
$connection_error_messages = Advanced_Ads_AdSense_MAPI::get_connect_error_messages();
$auth_url = 'https://accounts.google.com/o/oauth2/v2/auth?scope=' .
rawurlencode( 'https://www.googleapis.com/auth/adsense.readonly' ) .
'&client_id=' . $cid .
'&redirect_uri=' . rawurlencode( Advanced_Ads_AdSense_MAPI::REDIRECT_URI ) .
'&state=' . rawurlencode( base64_encode( wp_json_encode( $state ) ) ) . // phpcs:ignore
'&access_type=offline&include_granted_scopes=true&prompt=consent&response_type=code';
$_get = wp_unslash( $_GET );
if ( '1' === Params::get( 'oauth' ) && 'adsense' === Params::get( 'api' ) ) : ?>
<?php if ( isset( $_get['nonce'] ) && false !== wp_verify_nonce( $_get['nonce'], 'advads-mapi' ) ) : ?>
<?php if ( isset( $_get['code'] ) && Conditional::user_can( 'advanced_ads_manage_options' ) ) : ?>
<input type="hidden" id="advads-adsense-oauth-code" value="<?php echo esc_attr( urldecode( $_get['code'] ) ); ?>" />
<?php endif; ?>
<?php endif; ?>
<?php endif; ?>
<div id="gadsense-modal" data-return="<?php echo ESC_ATTR( admin_url( 'admin.php?page=advanced-ads-settings&oauth=1#top#adsense' ) ); ?>">
<div id="gadsense-modal-outer">
<div id="gadsense-modal-inner">
<div id="gadsense-modal-content">
<div class="gadsense-modal-content-inner" data-content="confirm-code">
<i class="dashicons dashicons-dismiss"></i>
<h2><?php esc_html_e( 'Processing authorization', 'advanced-ads' ); ?></h2>
<div class="gadsense-overlay">
<img alt="..." src="<?php echo esc_url( ADVADS_BASE_URL ); ?>admin/assets/img/loader.gif" style="margin-top:3em" />
</div>
</div>
<div class="gadsense-modal-content-inner" data-content="error" style="display:none;">
<i class="dashicons dashicons-dismiss"></i>
<h3><?php esc_html_e( 'Cannot access your account information.', 'advanced-ads' ); ?></h3>
<p class="error-message advads-notice-inline advads-error"></p>
<p class="error-description" style="font-size:1.1em;"></p>
</div>
<div class="gadsense-modal-content-inner" data-content="account-selector" style="display:none;">
<i class="dashicons dashicons-dismiss"></i>
<h3><?php esc_html_e( 'Please select an account', 'advanced-ads' ); ?></h3>
<p>
<select id="mapi-select-account">
</select>
</p>
<p><button class="button-primary"><?php esc_html_e( 'Use this account', 'advanced-ads' ); ?></button></p>
<input type="hidden" class="token-data" value="" />
<input type="hidden" class="accounts-details" value="" />
<div class="gadsense-overlay">
<img alt="..." src="<?php echo esc_url( ADVADS_BASE_URL ); ?>admin/assets/img/loader.gif" style="margin-top:3em" />
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
if ( 'undefined' == typeof window.AdsenseMAPI ) {
AdsenseMAPI = {};
}
AdsenseMAPI.nonce = '<?php echo wp_strip_all_tags( $nonce ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>';
AdsenseMAPI.oAuth2 = '<?php echo wp_strip_all_tags( $auth_url ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>';
AdsenseMAPI.connectErrorMsg = <?php echo wp_json_encode( $connection_error_messages ); ?>;
</script>
<style type="text/css">
.gadsense-overlay {
display:none;
background-color:rgba(255,255,255,.5);
position:absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
text-align:center;
}
#gadsense-modal {
display: none;
background-color: rgba(0,0,0,.5);
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
}
#gadsense-modal-outer {
position: relative;
width: 60%;
height: 100%;
<?php if ( is_rtl() ) : ?>
margin-right: 20%;
<?php else : ?>
margin-left: 20%;
<?php endif; ?>
}
#gadsense-modal-inner {
display: table;
width: 100%;
height: 100%;
}
#gadsense-modal-content {
display: table-cell;
vertical-align: middle;
}
.gadsense-modal-content-inner {
padding: 1em;
background-color: #f0f0f0;
position: relative;
border: 3px solid #808b94;
}
.gadsense-modal-content-inner .dashicons-dismiss {
background-color: #fff;
border-radius: 100%;
cursor: pointer;
top: -.5em;
<?php if ( is_rtl() ) : ?>
left: -.5em;
<?php else : ?>
right: -.5em;
<?php endif; ?>
position: absolute;
z-index: 2;
}
</style>

View File

@@ -0,0 +1 @@
<?php // Silence is golden.

View File

@@ -0,0 +1,60 @@
<?php
/**
* WARNING: be careful when modifying the DOM of this document!
* there are some jquery calls that rely on this structure!
*
* @package AdvancedAds
*/
$is_account_connected = $network->is_account_connected();
?>
<p>
<span class="mapi-insert-code">
<a href="#">
<?php
printf(
/* translators: 1: The name of an ad network. */
esc_html__( 'Insert new %1$s code', 'advanced-ads' ),
esc_html( $network->get_display_name() )
);
?>
</a>
</span>
<?php if ( Advanced_Ads_Checks::php_version_minimum() ) : ?>
<?php if ( $is_account_connected ) : ?>
<span class="mapi-open-selector">
<span class="mapi-optional-or"><?php esc_html_e( 'or', 'advanced-ads' ); ?></span>
<a href="#" class="prevent-default"><?php esc_html_e( 'Get ad code from your linked account', 'advanced-ads' ); ?></a>
</span>
<?php if ( $network->supports_manual_ad_setup() ) : ?>
<span class="mapi-close-selector-link">
<?php esc_html_e( 'or', 'advanced-ads' ); ?><a href="#" class="prevent-default">
<?php
printf(
/* translators: 1: The name of an ad network. */
esc_html__( 'Set up %1$s code manually', 'advanced-ads' ),
esc_html( $network->get_display_name() )
);
?>
</a>
</span>
<?php endif; ?>
<?php else : ?>
<?php
esc_html_e( 'or', 'advanced-ads' );
$connect_link_label = sprintf(
/* translators: 1: The name of an ad network. */
esc_html__( 'Connect to %1$s', 'advanced-ads' ),
esc_html( $network->get_display_name() )
);
?>
<a href="<?php echo esc_url( $network->get_settings_href() ); ?>" style="padding:0 10px;font-weight:bold;"><?php echo esc_html( $connect_link_label ); ?></a>
<?php endif; ?>
<?php endif; ?>
</p>
<?php if ( $is_account_connected && ! Advanced_Ads_Checks::php_version_minimum() ) : ?>
<p class="advads-notice-inline advads-error"><?php esc_html_e( 'Can not connect AdSense account. PHP version is too low.', 'advanced-ads' ); ?></p>
<?php
endif;

View File

@@ -0,0 +1,138 @@
<?php
/**
* AdSense ad units table.
*
* @var bool $closeable
* @var bool $use_dashicons
* @var Advanced_Ads_Network_Adsense $network
* @var array $ad_units
* @var bool $display_slot_id
* @var string $pub_id
*
* @package AdvancedAds
*/
global $external_ad_unit_id, $closeable, $display_slot_id;
if ( ! isset( $hide_idle_ads ) ) {
$hide_idle_ads = true;
}
if ( ! isset( $ad_units ) ) {
$ad_units = [];
}
?>
<div id="mapi-wrap" class="aa-select-list">
<?php if ( $closeable ) : ?>
<button type="button" id="mapi-close-selector" class="notice-dismiss"></button>
<?php endif; ?>
<i id="mapi-archived-ads" title="<?php esc_attr_e( 'Hide archived ads', 'advanced-ads' ); ?>" data-alt-title="<?php esc_attr_e( 'Show archived ads', 'advanced-ads' ); ?>" class="dashicons dashicons-hidden"></i>
<i class="aa-select-list-update dashicons dashicons-update mapiaction" data-mapiaction="updateList" style="color:#0085ba;cursor:pointer;font-size:20px;" title="<?php esc_attr_e( 'Update the ad units list', 'advanced-ads' ); ?>"></i>
<div id="mapi-loading-overlay" class="aa-select-list-loading-overlay">
<img alt="..." src="<?php echo esc_url( ADVADS_BASE_URL . 'admin/assets/img/loader.gif' ); ?>" style="margin-top:8em;" />
</div>
<div id="mapi-table-wrap" class="aa-select-list-table-wrap">
<table class="widefat striped">
<thead>
<tr>
<th><?php esc_html_e( 'Name', 'advanced-ads' ); ?></th>
<?php if ( $display_slot_id ) : ?>
<th><?php echo esc_html_x( 'Slot ID', 'AdSense ad', 'advanced-ads' ); ?></th>
<?php endif; ?>
<th><?php echo esc_html_x( 'Type', 'AdSense ad', 'advanced-ads' ); ?></th>
<th><?php esc_html_e( 'Size', 'advanced-ads' ); ?></th>
</tr>
</thead>
<tbody>
<?php if ( empty( $ad_units ) ) : ?>
<tr id="mapi-notice-noads">
<td colspan="5" style="text-align:center;">
<?php esc_attr_e( 'No ad units found', 'advanced-ads' ); ?>
<button type="button" class="mapiaction icon-button" data-mapiaction="updateList">
<?php esc_attr_e( 'Update the ad units list', 'advanced-ads' ); ?>
<i class="dashicons dashicons-update" style="color:#0085ba;font-size:20px;"></i>
</button>
</td>
</tr>
<?php
else :
// Force a refresh the first time the ad list is opened after an update.
echo ! isset( $ad_units[0]->raw['nameV2'] ) ? '<input type="hidden" id="mapi-force-v2-list-update" value="" />' : '';
foreach ( $ad_units as $ad_unit ) {
$ad_unit->is_supported = $network->is_supported( $ad_unit );
}
$sorted_adunits = Advanced_Ads_Ad_Network_Ad_Unit::sort_ad_units( $ad_units, $external_ad_unit_id );
?>
<?php foreach ( $sorted_adunits as $unit ) : ?>
<tr <?php echo 'ARCHIVED' === $unit->raw['status'] ? 'data-archived="1"' : ''; ?> class="advads-clickable-row mapiaction" data-mapiaction="getCode" data-slotid="<?php echo esc_attr( $unit->id ); ?>" data-active="<?php echo esc_attr( $unit->active ); ?>">
<td><?php echo esc_html( $unit->name ); ?></td>
<?php if ( $display_slot_id ) : ?>
<td class="unitcode">
<?php
echo '<span>' . esc_html( $unit->slot_id ) . '</span>';
echo 'ARCHIVED' === $unit->raw['status'] ? '&nbsp;<code>' . esc_html__( 'Archived', 'advanced-ads' ) . '</code>' : '';
?>
</td>
<?php endif; ?>
<td class="unittype">
<?php if ( $unit->is_supported ) : ?>
<?php if ( ! empty( $unit->code ) ) : ?>
<?php echo esc_attr( Advanced_Ads_AdSense_MAPI::format_ad_data( $unit, 'type' ) ); ?>
<?php else : ?>
<button type="button" class="button-secondary button-small" title="<?php esc_attr_e( 'Get the code for this ad', 'advanced-ads' ); ?>">
<span style="line-height: 26px;" class="dashicons dashicons-update"></span> <?php esc_html_e( 'Load', 'advanced-ads' ); ?>
</button>
<?php endif; ?>
<?php elseif ( empty( $unit->code ) ) : ?>
<span class="dashicons dashicons-warning" title="<?php esc_attr_e( 'Ad can\'t be imported, click for details', 'advanced-ads' ); ?>"></span>
<?php endif; ?>
</td>
<td class="unitsize">
<?php echo esc_attr( Advanced_Ads_AdSense_MAPI::format_ad_data( $unit, 'size' ) ); ?>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<p class="advads-notice-inline advads-error" id="remote-ad-code-error" style="display:none;"><strong><?php esc_attr_e( 'Unrecognized ad code', 'advanced-ads' ); ?></strong></p>
<p class="advads-error-message" id="remote-ad-code-msg"></p>
</div>
<div style="display:none;" id="remote-ad-unsupported-ad-type">
<h3 class="advads-notice-inline advads-error">
<?php esc_html_e( 'This ad type can currently not be imported from AdSense.', 'advanced-ads' ); ?>
</h3>
<p>
<?php esc_html_e( 'You can proceed with one of the following solutions', 'advanced-ads' ); ?>:
</p>
<ul>
<li>
<?php
/* Translators: 1: opening tag for AdSense account link 2: opening tag for a link to insert ad code 3: closing a tag */
printf( esc_html__( '%1$sCopy the code from your AdSense account%3$s and %2$sinsert a new AdSense code here%3$s.', 'advanced-ads' ), '<a href="https://www.google.com/adsense/new/u/0/' . esc_attr( $pub_id ) . '/myads/units" target="_blank">', '<a href="#" class="mapi-insert-code prevent-default">', '</a>' );
?>
</li>
<li>
<?php
/* Translators: 1: opening tag for a link to create an ad manually 2: closing a tag */
printf(
wp_kses(
/* translators: 1: opening tag for a link to create an ad manually 2: closing tag */
__( '%1$sCreate an AdSense code manually%2$s: Select the <em>Normal</em> or <em>Responsive</em> type and the size.', 'advanced-ads' ),
[
'em' => [],
'strong' => [],
]
),
'<a href="#" class="mapi-close-selector-link prevent-default">',
'</a>'
);
?>
</li>
<li>
<?php esc_html_e( 'Choose a different ad from your AdSense account above.', 'advanced-ads' ); ?>
</li>
</ul>
</div>

View File

@@ -0,0 +1,15 @@
<?php
/**
* Option to enable AdSense Auto ads on AMP pages
* located under Advanced Ads > Settings > AdSense > Auto ads
*
* @var string $option_name name of the option.
* @var bool $auto_ads_enabled true if the AMP Auto ads option is enabled.
*/
?>
<p>
<label>
<input type="checkbox" name="<?php echo esc_attr( $option_name ); ?>[auto_ads_enabled]" value="1" <?php checked( $auto_ads_enabled ); ?>/>
<?php esc_html_e( 'Enable AMP Auto ads', 'advanced-ads' ); ?>
</label>
</p>

View File

@@ -0,0 +1,19 @@
<?php // phpcs:ignoreFile
$path = dirname( __FILE__ );
return [
'classmap' => [
'Advanced_Ads_Ad_Type_Adsense' => $path . '/includes/class-ad-type-adsense.php',
'Advanced_Ads_AdSense_Data' => $path . '/includes/class-gadsense-data.php',
'Advanced_Ads_AdSense_MAPI' => $path . '/includes/class-mapi.php',
'Advanced_Ads_AdSense_Admin' => $path . '/admin/admin.php',
'Advanced_Ads_AdSense_Public' => $path . '/public/public.php',
'Advanced_Ads_AdSense_Report' => $path . '/includes/class-adsense-report.php',
'AdSense_Report_Data' => $path . '/includes/class-adsense-report-data.php',
'Advanced_Ads_AdSense_Report_Api' => $path . '/includes/adsense-report-api.php',
'Advanced_Ads_Network_Adsense' => $path . '/includes/class-network-adsense.php',
'AdvancedAds\\Adsense\\Types\\Adsense' => $path . '/includes/types/type-adsense.php',
],
'textdomain' => null,
];

View File

@@ -0,0 +1,172 @@
<?php // phpcs:ignore WordPress.Files.FileName
/**
* Report API for AdSense.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.48.2
*/
/**
* Retrieve report data from Google.
*/
class Advanced_Ads_AdSense_Report_Api {
/**
* Version of the AdSense Management API in use (for getting fresh data).
*
* @var string
*/
const API_VERSION = '2.0';
/**
* Report API endpoint.
*
* @var string
*/
private $endpoint_url;
/**
* Report type
*
* @var string
*/
private $type;
/**
* The API access token or an error array.
*
* @var array|string
*/
private $access_token;
/**
* The current connected AdSense account.
*
* @var string
*/
private $publisher_id;
/**
* Instance constructor.
*
* @param string $type report type.
*/
public function __construct( $type ) {
$publisher_id = Advanced_Ads_AdSense_Data::get_instance()->get_adsense_id();
$this->type = $type;
$this->access_token = Advanced_Ads_AdSense_MAPI::get_access_token( $publisher_id );
$this->publisher_id = $publisher_id;
$endpoint_args = [
'startDate.year' => '%SY%', // Start date's year - integer (4 digits).
'startDate.month' => '%SM%', // Start date's month - integer.
'startDate.day' => '%SD%', // Start date's integer - integer.
'endDate.year' => '%EY%', // End date's year - integer (4 digits).
'endDate.month' => '%EM%', // End date's month - integer.
'endDate.day' => '%ED%', // End date's integer - integer.
'dimension1' => '%DIM%', // Primary reporting dimension (domain name or ad unit name).
'dimension2' => 'DATE', // Secondary reporting dimension.
'metrics' => 'ESTIMATED_EARNINGS', // Report metrics.
'reportingTimeZone' => 'ACCOUNT_TIME_ZONE', // Time zone used in report data.
];
$this->endpoint_url = str_replace( [ 'dimension1', 'dimension2' ], 'dimensions', add_query_arg( $endpoint_args, 'https://adsense.googleapis.com/v2/accounts/%pubid%/reports:generate' ) );
}
/**
* Checks if the current setup has an access token.
*
* @return bool true if there is a token.
*/
public function has_token() {
return is_string( $this->access_token );
}
/**
* Get access token related error message.
*
* @return array Array of error messages.
*/
public function get_token_error() {
return is_string( $this->access_token ) ? [] : $this->access_token;
}
/**
* Check if there is an error related to access tokens.
*
* @return bool true if any error happened when requesting an access token.
*/
public function has_token_error() {
return ! is_string( $this->access_token );
}
/**
* Perform the actual call to Google for fresh data.
*
* @return array associative array with the response or with error data in case of failure.
*/
public function call_google() {
$dimension = 'unit' === $this->type ? 'AD_UNIT_ID' : 'DOMAIN_NAME';
$today = new DateTimeImmutable();
$start_date = $today->sub( date_interval_create_from_date_string( '28 days' ) );
// Replace placeholder in the endpoint with actual arguments.
$url = str_replace(
[
'%pubid%',
'%DIM%',
'%SY%',
'%SM%',
'%SD%',
'%EY%',
'%EM%',
'%ED%',
],
[
$this->publisher_id,
$dimension,
$start_date->format( 'Y' ),
$start_date->format( 'n' ),
$start_date->format( 'j' ),
$today->format( 'Y' ),
$today->format( 'n' ),
$today->format( 'j' ),
],
$this->endpoint_url
);
$headers = [
'Authorization' => 'Bearer ' . $this->access_token,
];
$response = wp_remote_get( $url, [ 'headers' => $headers ] );
Advanced_Ads_AdSense_MAPI::log( 'Fetched AdSense Report from ' . $url );
if ( is_wp_error( $response ) ) {
return [
'status' => false,
/* translators: AdSense ID. */
'msg' => sprintf( esc_html__( 'Error while retrieving report for "%s".', 'advanced-ads' ), $this->publisher_id ),
'raw' => $response->get_error_message(),
];
}
$response_body = json_decode( $response['body'], true );
if ( ! isset( $response_body['startDate'] ) ) {
return [
'status' => false,
/* translators: AdSense ID. */
'msg' => sprintf( esc_html__( 'Invalid response while retrieving report for "%s".', 'advanced-ads' ), $this->publisher_id ),
'raw' => $response['body'],
];
}
$response_body['api_version'] = self::API_VERSION;
$response_body['timestamp'] = time();
return [
'status' => true,
'response_body' => $response_body,
];
}
}

View File

@@ -0,0 +1,397 @@
<?php // phpcs:ignore WordPress.Files.FileName
/**
* AdSense Ad Type
*
* @package Advanced_Ads
* @author Thomas Maier <support@wpadvancedads.com>
* @license GPL-2.0+
* @link https://wpadvancedads.com
* @copyright 2013-2022 Thomas Maier, Advanced Ads GmbH
*/
use AdvancedAds\Abstracts\Ad;
use AdvancedAds\Utilities\Conditional;
use AdvancedAds\Interfaces\Ad_Interface;
/**
* Adsense ad type
*
* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
*/
class Advanced_Ads_Ad_Type_Adsense extends Ad implements Ad_Interface {
/**
* Return an array with AdSense ad type keys and readable labels
*
* @return array
*/
public static function get_ad_types() {
return [
'normal' => __( 'Normal', 'advanced-ads' ),
'responsive' => __( 'Responsive', 'advanced-ads' ),
'matched-content' => __( 'Multiplex', 'advanced-ads' ),
'link' => __( 'Link ads', 'advanced-ads' ),
'link-responsive' => __( 'Link ads (Responsive)', 'advanced-ads' ),
'in-article' => __( 'In-article', 'advanced-ads' ),
'in-feed' => __( 'In-feed', 'advanced-ads' ),
];
}
/**
* Get readable names for each AdSense ad type
*
* @param string $ad_type ad type key.
* @return string
*/
public static function get_ad_type_label( $ad_type ) {
$ad_types = self::get_ad_types();
return $ad_types[ $ad_type ] ?? __( 'Normal', 'advanced-ads' );
}
/**
* Output for the ad parameters metabox
* this will be loaded using ajax when changing the ad type radio buttons
* echo the output right away here
* name parameters must be in the "advanced_ads" array
*
* @param object $ad ad object.
*
* @since 1.4
*/
public function render_parameters( $ad ) {
// TODO: THIS IS JUST A QUICK AND DIRTY HACK. Create a dedicated method to handle this properly.
?>
<script>
jQuery( function () {
<?php
$mapi_options = Advanced_Ads_AdSense_MAPI::get_option();
$json_ad_codes = wp_json_encode( $mapi_options['ad_codes'] );
?>
const adsense = new AdvancedAdsNetworkAdsense(<?php echo $json_ad_codes; // phpcs:ignore ?>)
AdvancedAdsAdmin.AdImporter.setup( adsense )
} )
</script>
<?php
$content = (string) $ad->get_content();
$unit_id = '';
$unit_pubid = '';
$unit_code = '';
$unit_type = 'responsive';
$unit_width = 0;
$unit_height = 0;
$json_content = '';
$unit_resize = '';
$extra_params = [
'default_width' => '',
'default_height' => '',
'at_media' => [],
];
$db = Advanced_Ads_AdSense_Data::get_instance();
$pub_id = trim( $db->get_adsense_id( $ad ) );
// check pub_id for errors.
$pub_id_errors = false;
if ( '' !== $pub_id && 0 !== strpos( $pub_id, 'pub-' ) ) {
$pub_id_errors = __( 'The Publisher ID has an incorrect format. (must start with "pub-")', 'advanced-ads' );
}
global $external_ad_unit_id, $use_dashicons, $closeable;
$closeable = true;
$use_dashicons = false;
$external_ad_unit_id = '';
if ( trim( $content ) !== '' ) {
$json_content = stripslashes( $content );
// get json content striped by slashes.
$content = json_decode( stripslashes( $content ) );
if ( isset( $content->unitType ) ) {
$content->json = $json_content;
$unit_type = $content->unitType;
$unit_code = $content->slotId;
$unit_pubid = ! empty( $content->pubId ) ? $content->pubId : $pub_id;
$layout = $content->layout ?? '';
$layout_key = $content->layout_key ?? '';
if ( 'responsive' !== $content->unitType && 'link-responsive' !== $content->unitType && 'matched-content' !== $content->unitType ) {
// Normal ad unit.
$unit_width = $ad->get_width();
$unit_height = $ad->get_height();
} else {
// Responsive && multiplex ads.
$unit_resize = $content->resize ?? 'auto';
if ( 'auto' !== $unit_resize ) {
$extra_params = apply_filters( 'advanced-ads-gadsense-ad-param-data', $extra_params, $content, $ad );
}
}
if ( ! empty( $unit_pubid ) ) {
$unit_id = 'ca-' . $unit_pubid . ':' . $unit_code;
}
$external_ad_unit_id = $unit_id;
}
}
if ( '' === trim( $pub_id ) && '' !== trim( $unit_code ) ) {
$pub_id_errors = __( 'Your AdSense Publisher ID is missing.', 'advanced-ads' );
}
$default_template = GADSENSE_BASE_PATH . 'admin/views/adsense-ad-parameters.php';
/**
* Inclusion of other UI template is done here. The content is passed in order to allow the inclusion of different
* templates file, depending of the ad. It's up to the developer to verify that $content is not an empty
* variable (which is the case for a new ad).
*
* Inclusion of .js and .css files for the ad creation/editon page are done by another hook. See
* 'advanced-ads-gadsense-ad-param-script' and 'advanced-ads-gadsense-ad-param-style' in "../admin/class-gadsense-admin.php".
*/
$template = apply_filters( 'advanced-ads-gadsense-ad-param-template', $default_template, $content );
require $template;
}
/**
* Render icon on the ad overview list
*
* @param Ad $ad Ad instance.
*/
public function render_icon( Ad $ad ) {
$image = 'adsense-display.svg';
$content = json_decode( wp_unslash( $ad->get_content() ), true );
if ( isset( $content['unitType'] ) ) {
switch ( $content['unitType'] ) {
case 'matched-content':
$image = 'adsense-multiplex.svg';
break;
case 'in-article':
$image = 'adsense-in-article.svg';
break;
case 'in-feed':
$image = 'adsense-in-feed.svg';
break;
}
}
echo '<img src="' . esc_url( ADVADS_BASE_URL ) . '/modules/gadsense/admin/assets/img/' . esc_attr( $image ) . '" width="50" height="50">';
}
/**
* Render additional information in the ad type tooltip on the ad overview page
*
* @param Ad $ad Ad instance.
*/
public function render_ad_type_tooltip( Ad $ad ) {
$content = json_decode( stripslashes( $ad->get_content() ), true );
if ( isset( $content['unitType'] ) ) {
echo esc_html( self::get_ad_type_label( $content['unitType'] ) );
}
}
/**
* Sanitize content field on save
*
* @param string $content ad content.
*
* @return string $content sanitized ad content
* @since 1.0.0
*/
public function sanitize_content( $content = '' ) {
$content = wp_unslash( $content );
$ad_unit = json_decode( $content, true );
if ( empty( $ad_unit ) ) {
$ad_unit = [];
}
// Remove this slotId from unsupported_ads.
$mapi_options = Advanced_Ads_AdSense_MAPI::get_option();
if ( array_key_exists( 'slotId', $ad_unit ) && array_key_exists( $ad_unit['slotId'], $mapi_options['unsupported_units'] ) ) {
unset( $mapi_options['unsupported_units'][ $ad_unit['slotId'] ] );
update_option( Advanced_Ads_AdSense_MAPI::OPTION_KEY, $mapi_options );
}
return $content;
}
/**
* Prepare output for frontend.
*
* @return string
*/
public function prepare_frontend_output(): string {
global $gadsense;
$ad_args = $this->get_prop( 'ad_args' );
$content = json_decode( stripslashes( $this->get_content() ) );
if (
isset( $ad_args['wp_the_query']['is_404'] ) &&
$ad_args['wp_the_query']['is_404'] &&
! defined( 'ADVADS_ALLOW_ADSENSE_ON_404' )
) {
return '';
}
$output = '';
$db = Advanced_Ads_AdSense_Data::get_instance();
$pub_id = $db->get_adsense_id( $this );
if ( ! isset( $content->unitType ) || empty( $pub_id ) ) {
return $output;
}
// deprecated since the adsbygoogle.js file is now always loaded.
if ( ! isset( $gadsense['google_loaded'] ) || ! $gadsense['google_loaded'] ) {
$gadsense['google_loaded'] = true;
}
// check if passive cb is used.
if ( isset( $gadsense['adsense_count'] ) ) {
++$gadsense['adsense_count'];
} else {
$gadsense['adsense_count'] = 1;
}
// "link" was a static format until AdSense stopped filling them in March 2021. Their responsive format serves as a fallback recommended by AdSense
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$is_static_normal_content = ! in_array( $content->unitType, [ 'responsive', 'link', 'link-responsive', 'matched-content', 'in-article', 'in-feed' ], true );
$output = apply_filters( 'advanced-ads-gadsense-output', false, $this, $pub_id, $content );
if ( false !== $output ) {
return $output;
}
// Prevent output on AMP pages.
if ( Conditional::is_amp() ) {
return '';
}
$output = '';
// Add notice when a link unit is used.
if ( in_array( $content->unitType, [ 'link', 'link-responsive' ], true ) ) {
Advanced_Ads_Ad_Health_Notices::get_instance()->add( 'adsense_link_units_deprecated' );
}
// build static normal content ads first.
if ( $is_static_normal_content ) {
$output .= $this->get_script_tag( $pub_id );
$output .= '<ins class="adsbygoogle" ';
$output .= 'style="display:inline-block;width:' . $this->get_width() . 'px;height:' . $this->get_height() . 'px;" ' . "\n";
$output .= 'data-ad-client="ca-' . $pub_id . '" ' . "\n";
$output .= 'data-ad-slot="' . $content->slotId . '"';
// ad type for static link unit.
if ( 'link' === $content->unitType ) {
$output .= "\n" . 'data-ad-format="link"';
}
$output .= '></ins> ' . "\n";
$output .= '<script> ' . "\n";
$output .= '(adsbygoogle = window.adsbygoogle || []).push({}); ' . "\n";
$output .= '</script>' . "\n";
} else {
/**
* The value of $ad->content->resize should be tested to format the output correctly
*/
$unmodified = $output;
$output = apply_filters( 'advanced-ads-gadsense-responsive-output', $output, $this, $pub_id );
if ( $unmodified === $output ) {
/**
* If the output has not been modified, perform a default responsive output.
* A simple did_action check isn't sufficient, some hooks may be attached and fired but didn't touch the output
*/
$this->append_defaut_responsive_content( $output, $pub_id, $content );
// Remove float setting if this is a responsive ad unit without custom sizes.
unset( $this->wrapper['style']['float'] );
}
}
return $output;
}
/**
* Check if a string looks like an AdSense ad code.
*
* @param string $content The string that need to be checked.
*
* @return boolean
*/
public static function content_is_adsense( $content = '' ) {
return false !== stripos( $content, 'googlesyndication.com' ) &&
( false !== stripos( $content, 'google_ad_client' ) || false !== stripos( $content, 'data-ad-client' ) );
}
/**
* Build AdSense script tag.
*
* @param string $pub_id AdSense publisher ID.
*
* @return string
*/
protected function get_script_tag( $pub_id ) {
return sprintf(
// phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- don't allow any changes on Google AdSense code.
'<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js%s" crossorigin="anonymous"></script>',
/**
* Filter the output of the publisher ID appended to the AdSense JavaScript Code.
*
* @param boolean
*/
apply_filters( 'advanced-ads-adsense-publisher-id', true ) ? '?client=ca-' . $pub_id : ''
);
}
/**
* Append responsive content
*
* @param string $output Current ad unit code.
* @param string $pub_id AdSense publisher ID.
* @param object $content Ad unit content with all parameters.
*/
protected function append_defaut_responsive_content( &$output, $pub_id, $content ) {
$format = '';
$style = 'display:block;';
switch ( $content->unitType ) {
case 'matched-content':
$format = 'autorelaxed';
break;
case 'link-responsive':
case 'link':
$format = 'link';
break;
case 'in-feed':
$format = 'fluid';
$layout_key = $content->layout_key;
break;
case 'in-article':
$format = 'fluid';
$layout = 'in-article';
$style = 'display:block; text-align:center;';
break;
default:
$format = 'auto';
}
$output .= $this->get_script_tag( $pub_id );
$output .= '<ins class="adsbygoogle" ';
$output .= 'style="' . $style . '" ';
$output .= 'data-ad-client="ca-' . $pub_id . '" ' . "\n";
$output .= 'data-ad-slot="' . $content->slotId . '" ' . "\n";
$output .= isset( $layout ) ? 'data-ad-layout="' . $layout . '"' . "\n" : '';
$output .= isset( $layout_key ) ? 'data-ad-layout-key="' . $layout_key . '"' . "\n" : '';
$output .= 'data-ad-format="';
$output .= $format;
$options = Advanced_Ads_AdSense_Data::get_instance()->get_options();
$fw = ! empty( $options['fullwidth-ads'] ) ? $options['fullwidth-ads'] : 'default';
if ( 'default' !== $fw ) {
$output .= 'enable' === $fw ? '" data-full-width-responsive="true' : '" data-full-width-responsive="false';
}
$output .= '"></ins>' . "\n";
$output .= '<script> ' . "\n";
$output .= apply_filters( 'advanced-ads-gadsense-responsive-adsbygoogle', '(adsbygoogle = window.adsbygoogle || []).push({}); ' . "\n" );
$output .= '</script>' . "\n";
}
}

View File

@@ -0,0 +1,333 @@
<?php
/**
* Handle all report data received from Google
*
* @package Advanced_Ads
*/
/**
* Main class
*/
class AdSense_Report_Data implements Serializable {
/**
* Cached data life span.
*
* @var integer
*/
const CACHE_DURATION = 3600;
/**
* DB option name for report by domain.
*
* @var string
*/
const DOMAIN_OPTION = 'advanced_ads_adsense_report_domain';
/**
* DB option name for report by ad unit.
*
* @var string
*/
const UNIT_OPTION = 'advanced_ads_adsense_report_unit';
/**
* Daily earnings.
*
* @var null|array
*/
private $earnings;
/**
* Report type. 'unit' or 'domain'.
*
* @var string
*/
private $type;
/**
* UNIX timestamp at which the data was obtained from Google.
*
* @var int
*/
private $timestamp = 0;
/**
* Currency used in the report.
*
* @var string
*/
private $currency = '';
/**
* Version of Google AdSense Management API used.
*
* @var string
*/
private $version = '';
/**
* List of domain names found in the report data.
*
* @var array
*/
private $domains = [];
/**
* Instance constructor.
*
* @param string $type report type.
*/
public function __construct( $type = 'unit' ) {
$this->type = $type;
}
/**
* Get all domains.
*
* @return array the domain list.
*/
public function get_domains() {
return $this->domains;
}
/**
* Get the report timestamp.
*
* @return int data timestamp.
*/
public function get_timestamp() {
return $this->timestamp;
}
/**
* Get the currency used in the report.
*
* @return string the currency code.
*/
public function get_currency() {
return $this->currency;
}
/**
* Serialize an instance of this class into a string. For PHP version >= 7.4
*
* @return array
*/
public function __serialize() {
return [
'earnings' => $this->earnings,
'type' => $this->type,
'timestamp' => $this->timestamp,
'currency' => $this->currency,
'domains' => $this->domains,
];
}
/**
* Recreate an instance of this class from a string. For PHP version >= 7.4
*
* @param array $data the array from __serialize.
*
* @return void
*/
public function __unserialize( $data ) {
$this->earnings = $data['earnings'] ?? null;
$this->type = $data['type'] ?? null;
$this->timestamp = $data['timestamp'] ?? 0;
$this->currency = $data['currency'] ?? '';
$this->domains = $data['domains'] ?? [];
}
/**
* Returns serialized object properties. For PHP version < 7.4
*
* @return string the serialized data.
*/
public function serialize() {
return serialize(
[
'earnings' => $this->earnings,
'type' => $this->type,
'timestamp' => $this->timestamp,
'currency' => $this->currency,
'domains' => $this->domains,
]
);
}
/**
* Set object properties from serialized data string. For PHP version < 7.4
*
* @param string $data serilaized data from DB.
*/
public function unserialize( $data ) {
try {
$unwrapped = unserialize( $data );
} catch ( Exception $ex ) {
$unwrapped = [];
}
$this->__unserialize( $unwrapped );
}
/**
* Update object properties and DB record from a API response.
*
* @param array $response API call response from Google.
*/
public function update_data_from_response( $response ) {
$headers = [];
$this->version = $response['api_version'];
$this->timestamp = $response['timestamp'];
foreach ( $response['headers'] as $header ) {
if ( 'METRIC_CURRENCY' === $header['type'] ) {
$this->currency = $header['currencyCode'];
}
$headers[] = $header['name'];
}
$earnings = [];
if ( ! empty( $response['rows'] ) ) {
foreach ( $response['rows'] as $row ) {
$earning = new StdClass();
foreach ( $row['cells'] as $index => $cell ) {
switch ( $headers[ $index ] ) {
case 'DATE':
$earning->date = new DateTimeImmutable( $cell['value'] );
break;
case 'ESTIMATED_EARNINGS':
$earning->estimated_earning = (float) $cell['value'];
break;
default: // "DOMAIN_NAME" or "AD_UNIT_ID".
$earning->{strtolower( $headers[ $index ] )} = $cell['value'];
if ( 'DOMAIN_NAME' === $headers[ $index ] && ! in_array( $cell['value'], $this->domains, true ) ) {
$this->domains[] = $cell['value'];
}
}
}
$earnings[] = $earning;
}
}
$this->earnings = $earnings;
$option_name = 'unit' === $this->type ? self::UNIT_OPTION : self::DOMAIN_OPTION;
// Delete old options entries.
delete_option( 'advanced_ads_adsense_report_DATE_AD_UNIT_CODE_EARNINGS_dashboard' );
delete_option( 'advanced_ads_adsense_report_DATE_DOMAIN_NAME_EARNINGS_dashboard' );
// Save the data instance in DB.
update_option( $option_name, $this->serialize() );
}
/**
* Returns a data object constructed from saved data. Constructs a new one if there is no usable data.
*
* @param string $type report type.
*
* @return AdSense_Report_Data
*/
public static function get_data_from_options( $type ) {
$option_name = 'unit' === $type ? self::UNIT_OPTION : self::DOMAIN_OPTION;
$option = get_option( $option_name, false );
if ( ! $option ) {
return new self( $type );
}
// PHP version < 7.4.
if ( $option instanceof self ) {
return $option;
}
try {
$unserialized = is_serialized( $option ) ? unserialize( $option ) : null;
if ( $unserialized instanceof self ) {
return $unserialized;
}
return new self( $type );
} catch ( Exception $ex ) {
return new self( $type );
}
}
/**
* Checks if cached data need to be updated.
*
* @return bool true if the stored data has not expired yet.
*/
public function is_valid() {
return $this->timestamp + self::CACHE_DURATION > time();
}
/**
* Get the earnings sums for display.
*
* @param string $filter filter sums by a given domain name or ad unit.
*
* @return int[]
*/
public function get_sums( $filter = '' ) {
$today = new DateTimeImmutable();
$yesterday = $today->sub( date_interval_create_from_date_string( '1 day' ) );
$prev7 = $today->sub( date_interval_create_from_date_string( '7 days' ) );
$prev28 = $today->sub( date_interval_create_from_date_string( '28 days' ) );
$sums = [
'today' => 0,
'yesterday' => 0,
'7days' => 0,
'this_month' => 0,
'28days' => 0,
];
// Unit type reports should always have the ad unit id specified.
if ( '' === $filter && 'unit' === $this->type ) {
return $sums;
}
if ( ! is_array( $this->earnings ) || empty( $this->earnings ) ) {
return $sums;
}
foreach ( $this->earnings as $value ) {
if (
( 'unit' === $this->type && false === strpos( $value->ad_unit_id, $filter ) )
|| ( ! empty( $filter ) && 'domain' === $this->type && $filter !== $value->domain_name )
) {
continue;
}
if ( $this->date_ymd( $value->date ) === $this->date_ymd( $today ) ) {
$sums['today'] += $value->estimated_earning;
}
if ( $this->date_ymd( $value->date ) === $this->date_ymd( $yesterday ) ) {
$sums['yesterday'] += $value->estimated_earning;
}
if ( $this->date_ymd( $value->date ) >= $this->date_ymd( $prev7 ) ) {
$sums['7days'] += $value->estimated_earning;
}
if ( $this->date_ymd( $value->date ) >= $this->date_ymd( $prev28 ) ) {
$sums['28days'] += $value->estimated_earning;
}
if ( $value->date->format( 'm' ) === $today->format( 'm' ) ) {
$sums['this_month'] += $value->estimated_earning;
}
}
return $sums;
}
/**
* Get an integer representation of a DateTime object to be used in date comparison.
*
* @param DateTimeInterface $date the date object.
*
* @return int
*/
private function date_ymd( $date ) {
if ( $date instanceof DateTimeInterface ) {
return (int) $date->format( 'Ymd' );
}
return 0;
}
}

View File

@@ -0,0 +1,176 @@
<?php
/**
* Class Advanced_Ads_AdSense_Report
*
* Displays AdSense earnings on the ad overview page or the ad edit page.
*/
class Advanced_Ads_AdSense_Report {
/**
* Domain name or ad unit to filter data with before display.
*
* @var string
*/
private $filter;
/**
* Report type. 'unit' or 'domain'.
*
* @var string
*/
private $type;
/**
* Object representing the current report data.
*
* @var AdSense_Report_Data
*/
private $data_object;
/**
* Error from the last attempt to call Google.
*
* @var string
*/
private $last_api_error_message;
/**
* Instance constructor.
*
* @param string $type report type.
* @param string $filter report filter.
*/
public function __construct( $type = 'unit', $filter = '' ) {
$this->type = $type;
if ( 'domain' === $type && ! empty( $filter ) ) {
update_option( 'advanced-ads-adsense-dashboard-filter', $filter );
// Backward compatibility: "*" was used to display data for all domains if API version prior to 2.0.
if ( '*' === $filter ) {
$filter = '';
}
}
$this->filter = $filter;
$this->data_object = AdSense_Report_Data::get_data_from_options( $type );
}
/**
* Tries to get fresh data from Google.
*
* @return bool true if we got fresh data.
*/
public function refresh_report() {
$api_helper = new Advanced_Ads_AdSense_Report_Api( $this->type );
$error = [];
if ( $api_helper->has_token() ) {
$response = $api_helper->call_google();
if ( true === $response['status'] ) {
$this->data_object->update_data_from_response( $response['response_body'] );
return true;
}
if ( isset( $response['msg'] ) ) {
$this->last_api_error_message = $response['msg'];
return false;
}
}
if ( $api_helper->has_token_error() ) {
$error = $api_helper->get_token_error();
}
if ( isset( $error['msg'] ) ) {
$this->last_api_error_message = $error['msg'];
return false;
}
if ( isset( $error['raw'] ) ) {
$this->last_api_error_message = $error['raw'];
return false;
}
if ( empty( $this->last_api_error_message ) ) {
$this->last_api_error_message = __( 'No valid tokens', 'advanced-ads' );
}
return false;
}
/**
* Retrieve the error message from the last API call.
*
* @return string Error message from the last API call.
*/
public function get_last_api_error() {
if ( empty( $this->last_api_error_message ) ) {
return '';
}
return $this->last_api_error_message;
}
/**
* Returns the report data object.
*
* @return AdSense_Report_Data
*/
public function get_data() {
return $this->data_object;
}
/**
* Build an return the HTML markup for display.
*
* @return string the final markup.
*/
public function get_markup() {
if ( ! $this->get_data()->is_valid() ) {
return '<p style="text-align:center;"><span class="report-need-refresh spinner advads-ad-parameters-spinner advads-spinner"></span></p>';
}
ob_start();
$report_filter = $this->filter;
$report_domains = $this->data_object->get_domains();
$sums = $this->data_object->get_sums( $this->filter );
$earning_cells = '';
foreach ( $sums as $index => $sum ) {
$earning_cells .= $this->get_earning_cell( $sum, $index );
}
require_once GADSENSE_BASE_PATH . '/admin/views/adsense-report.php';
return ob_get_clean();
}
/**
* Build and return the HTML markup for a given period.
*
* @param float $sum the earning for that period.
* @param string $index the period identifier.
*
* @return string HTML of the individual cell.
*/
private function get_earning_cell( $sum, $index ) {
$period_strings = [
'today' => esc_html__( 'Today', 'advanced-ads' ),
'yesterday' => esc_html__( 'Yesterday', 'advanced-ads' ),
/* translators: 1: The number of days. */
'7days' => sprintf( esc_html__( 'Last %1$d days', 'advanced-ads' ), 7 ),
'this_month' => esc_html__( 'This Month', 'advanced-ads' ),
/* translators: 1: The number of days. */
'28days' => sprintf( esc_html__( 'Last %1$d days', 'advanced-ads' ), 28 ),
];
$markup = '<div class="advads-flex1 advads-stats-box"><div>' . $period_strings[ $index ] . '</div>';
$markup .= '<div class="advads-stats-box-main">';
$markup .= number_format_i18n( ceil( 100 * $sum ) / 100, 2 );
$markup .= ' ' . $this->get_data()->get_currency();
$markup .= '</div></div>';
return $markup;
}
}

View File

@@ -0,0 +1,162 @@
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
use AdvancedAds\Constants;
use AdvancedAds\Entities;
/**
* Adsense data class.
*/
class Advanced_Ads_AdSense_Data {
/**
* Singleton instance
*
* @var Advanced_Ads_AdSense_Data
*/
private static $instance;
/**
* Hold options
*
* @var array
*/
private $options;
/**
* Hold resizing data
*
* @var array
*/
private $resizing;
/**
* The constructor.
*/
private function __construct() {
$options = get_option( GADSENSE_OPT_NAME, [] );
// Set defaults.
if ( ! isset( $options['adsense-id'] ) ) {
$options['adsense-id'] = '';
update_option( GADSENSE_OPT_NAME, $options );
}
$this->options = wp_parse_args(
$options,
[
'background' => false,
'page-level-enabled' => false,
]
);
// Resizing method for responsive ads.
$this->resizing = [
'auto' => __( 'Auto', 'advanced-ads' ),
];
}
/**
* GETTERS
*/
public function get_options() {
return $this->options;
}
/**
* Get adsense id
*
* @param Ad|null $ad Ad instance.
*
* @return string
*/
public function get_adsense_id( $ad = null ) {
if ( ! empty( $ad ) && $ad->is_type( 'adsense' ) ) {
$ad_content = json_decode( $ad->get_content() );
// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
if ( $ad_content && isset( $ad_content->pubId ) && ! empty( $ad_content->pubId ) ) {
return $ad_content->pubId;
}
// phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
}
return trim( $this->options['adsense-id'] );
}
/**
* Get limit per page
*
* @deprecated 1.47.0
* @deprecated The feature is deprecated by AdSense since 2019
*
* @return int
*/
public function get_limit_per_page() {
_deprecated_function( __METHOD__, '1.47.0' );
return 0;
}
/**
* Get responsive sizing
*
* @return array
*/
public function get_responsive_sizing() {
$this->resizing = apply_filters( 'advanced-ads-gadsense-responsive-sizing', $this->resizing );
return $this->resizing;
}
/**
* Get class instance
*
* @return Advanced_Ads_AdSense_Data
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new Advanced_Ads_AdSense_Data();
}
return self::$instance;
}
/**
* ISSERS/HASSERS
*/
public function is_page_level_enabled() {
return $this->options['page-level-enabled'];
}
/**
* Is setup
*
* @return boolean
*/
public function is_setup() {
if ( isset( $this->options ) && is_array( $this->options ) && isset( $this->options['adsense-id'] ) && $this->options['adsense-id'] ) {
$adsense_id = $this->get_adsense_id();
if ( $adsense_id ) {
return Advanced_Ads_AdSense_MAPI::has_token( $adsense_id );
}
}
return false;
}
/**
* Whether to hide the AdSense stats metabox.
*
* @return bool
*/
public function is_hide_stats() {
global $post;
if ( $post instanceof WP_Post && Constants::POST_TYPE_AD === $post->post_type ) {
$the_ad = wp_advads_get_ad( $post->ID );
if ( ! $the_ad->is_type( 'adsense' ) ) {
return true;
}
}
return isset( $this->options['hide-stats'] );
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,573 @@
<?php // phpcs:ignoreFile
use AdvancedAds\Abstracts\Ad;
use AdvancedAds\Utilities\WordPress;
use AdvancedAds\Utilities\Conditional;
use AdvancedAds\Compatibility\Compatibility;
/**
* Class Advanced_Ads_Network_Adsense
*/
class Advanced_Ads_Network_Adsense extends Advanced_Ads_Ad_Network {
/**
* An array containing all the AdSense status codes that flag an {$link Advanced_Ads_Ad_Network_Ad_Unit} ad unit as active
* for downward compatibility with PHP < 5.6 the const had to be changed to static field. you can revert to const when PHP5 support is FINALLY dropped
*
* @var array
*/
private static $status_codes_active = [ 'ACTIVE', 'NEW' ];
/**
* A globally usable instance, that will be created when calling {$link Advanced_Ads_Ad_Network#get_instance) for the first time
*
* @var Advanced_Ads_Ad_Type_Adsense
*/
private static $instance;
/**
* AdSense options handling class.
*
* @var Advanced_Ads_AdSense_Data
*/
private $data;
/**
* The AdSense networks settings section ID
*
* @var string
*/
protected $settings_section_id;
/**
* Instance of Advanced_Ads_Network_Adsense
*
* @return Advanced_Ads_Ad_Type_Adsense|Advanced_Ads_Network_Adsense
*/
final public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new Advanced_Ads_Network_Adsense();
}
return self::$instance;
}
/**
* Advanced_Ads_Network_Adsense constructor.
*/
public function __construct() {
parent::__construct( 'adsense', 'AdSense' );
$this->data = Advanced_Ads_AdSense_Data::get_instance();
// Adsense does not use the default generated settings section id. overwrite it with the old value.
$this->settings_section_id = 'advanced_ads_adsense_setting_section';
add_action( 'advanced_ads_settings_before_form', [ $this, 'render_before_form' ], 10, 2 );
}
/**
* Render before form.
*
* @param string $tab_id the ID of the current tab.
* @param array $tab the current tab.
*/
public function render_before_form( $tab_id, $tab ) {
if ( 'adsense' === $tab_id && ! empty( $this->data->get_adsense_id() ) ) {
$_notice = 'adsense_subscribe';
if ( Advanced_Ads_Admin_Notices::get_instance()->can_display( $_notice ) && Conditional::user_can_subscribe( 'nl_first_steps' ) ) {
$text = sprintf(
/* translators: %s: number of add-ons. */
__( 'Subscribe to our free email course for Google AdSense, receive our newsletter for periodic tutorials, and get %s for Advanced Ads.', 'advanced-ads' ),
'<strong>' . __( '2 free add-ons', 'advanced-ads' ) . '</strong>'
);
include ADVADS_ABSPATH . '/admin/views/notices/inline.php';
}
}
}
/**
* Register settings to Advanced Ads > Settings > AdSense
*
* @param string $hook settings page hook.
* @param string $section_id settings section id.
*/
protected function register_settings( $hook, $section_id ) {
// Add setting field to disable ads.
add_settings_field(
'adsense-id',
__( 'AdSense account', 'advanced-ads' ),
[ $this, 'render_settings_adsense_id' ],
$hook,
$section_id
);
// Activate AdSense verification code and Auto ads (previously Page-Level ads).
add_settings_field(
'adsense-page-level',
__( 'Auto ads', 'advanced-ads' ),
[ $this, 'render_settings_adsense_page_level' ],
$hook,
$section_id
);
// AdSense anchor ad on top of pages.
// Only show this field if selected, otherwise use new auto ads code.
if ( isset( $this->data->get_options()['top-anchor-ad'] ) ) {
add_settings_field(
'top_anchor_ad',
__( 'Auto ads', 'advanced-ads' ) . ':&nbsp;' . __( 'Disable top anchor ad', 'advanced-ads' ),
[ $this, 'render_settings_adsense_top_anchor_ad' ],
$hook,
$section_id
);
}
// Hide AdSense stats in the backend.
add_settings_field(
'hide_stats',
__( 'Disable stats', 'advanced-ads' ),
[ $this, 'render_settings_adsense_hide_stats' ],
$hook,
$section_id
);
// Disable AdSense violation warnings.
add_settings_field(
'adsense-warnings-disable',
__( 'Disable violation warnings', 'advanced-ads' ),
[ $this, 'render_settings_adsense_warnings_disable' ],
$hook,
$section_id
);
// Show AdSense widget on WP Dashboard.
add_settings_field(
'adsense_wp_dashboard',
__( 'Show AdSense Earnings', 'advanced-ads' ),
[ $this, 'render_settings_adsense_wp_dashboard' ],
$hook,
$section_id
);
add_settings_field(
'adsense-background',
__( 'Transparent background', 'advanced-ads' ),
[ $this, 'render_settings_adsense_background' ],
$hook,
$section_id
);
add_settings_field(
'adsense-full-width',
__( 'Full width responsive ads on mobile', 'advanced-ads' ),
[ $this, 'render_settings_adsense_fullwidth' ],
$hook,
'advanced_ads_adsense_setting_section'
);
}
/**
* Render AdSense settings section
*/
public function render_settings_section_callback() {
// For whatever purpose there might come.
}
/**
* Render AdSense management api setting
*/
public function render_settings_management_api() {
require_once GADSENSE_BASE_PATH . 'admin/views/mapi-settings.php';
}
/**
* Render AdSense id setting
*/
public function render_settings_adsense_id() {
require_once GADSENSE_BASE_PATH . 'admin/views/adsense-account.php';
}
/**
* Render top anchor ad setting
*/
public function render_settings_adsense_top_anchor_ad() {
$options = $this->data->get_options();
$anchor_ad = isset( $options['top-anchor-ad'] ) ? $options['top-anchor-ad'] : '';
?>
<label>
<input type="checkbox" name="<?php echo esc_attr( GADSENSE_OPT_NAME ); ?>[top-anchor-ad]" value="1" <?php checked( $anchor_ad ); ?> />
<?php esc_html_e( 'Enable this box if you dont want Google Auto ads to place anchor ads at the top of your page.', 'advanced-ads' ); ?>
<?php WordPress::show_deprecated_notice('top Anchor Ad'); ?>
</label>
<?php
}
/**
* Render setting to hide AdSense stats showing in the backend
*/
public function render_settings_adsense_hide_stats() {
$options = $this->data->get_options();
$hide_stats = isset( $options['hide-stats'] );
?>
<label>
<input type="checkbox" name="<?php echo esc_attr( GADSENSE_OPT_NAME ); ?>[hide-stats]" value="1" <?php checked( $hide_stats ); ?> />
<?php esc_html_e( 'Enable this option to stop loading stats from AdSense into your WordPress backend.', 'advanced-ads' ); ?>
</label>
<?php
}
/**
* Render setting to hide AdSense stats showing in the backend
*/
public function render_settings_adsense_wp_dashboard() {
$options = $this->data->get_options();
$show_widget = isset( $options['adsense-wp-widget'] );
?>
<label>
<input type="checkbox" name="<?php echo esc_attr( GADSENSE_OPT_NAME ); ?>[adsense-wp-widget]" value="1" <?php checked( $show_widget ); ?> />
<?php esc_html_e( 'Show Earnings widget on the WordPress dashboard.', 'advanced-ads' ); ?>
</label>
<?php
}
/**
* Render page-level ads setting
*
* @since 1.6.9
*/
public function render_settings_adsense_page_level() {
$options = $this->data->get_options();
$page_level = $options['page-level-enabled'];
?>
<label><input type="checkbox" name="<?php echo esc_attr( GADSENSE_OPT_NAME ); ?>[page-level-enabled]" value="1" <?php checked( $page_level ); ?> />
<?php esc_attr_e( 'Insert the AdSense header code to enable Auto ads and verify your website.', 'advanced-ads' ); ?>
</label>
<ul>
<li><a href="https://wpadvancedads.com/adsense-auto-ads-wordpress/?utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-adsense-specific-pages#Display_AdSense_Auto_Ads_only_on_specific_pages" target="_blank"><?php esc_attr_e( 'Display Auto ads only on specific pages', 'advanced-ads' ); ?></a></li>
<li><a href="https://wpadvancedads.com/adsense-in-random-positions-auto-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=backend-autoads-ads" target="_blank"><?php esc_attr_e( 'Why are ads appearing in random positions?', 'advanced-ads' ); ?></a></li>
<?php
if ( ! empty( $options['adsense-id'] ) ) :
?>
<li><a href="https://www.google.com/adsense/new/u/0/<?php echo esc_attr( $options['adsense-id'] ); ?>/myads/auto-ads" target="_blank">
<?php
/* translators: this is the text for a link to a sub-page in an AdSense account */
esc_attr_e( 'Adjust Auto ads options', 'advanced-ads' );
?>
</a></li>
<?php
endif;
?>
</ul>
<?php if ( Compatibility::borlabs_cookie_adsense_auto_ads_code_exists() ) : ?>
<p class="advads-notice-inline advads-error">
<?php require GADSENSE_BASE_PATH . 'admin/views/borlabs-cookie-auto-ads-warning.php'; ?>
</p>
<?php endif; ?>
<?php
self::render_settings_adsense_amp();
do_action( 'advanced-ads-settings-adsense-below-auto-ads-option' );
}
/**
* Render Adsense AMP setting fields.
*/
public function render_settings_adsense_amp() {
// AMP Auto ads was removed from Responsive add-on version 1.10.0
if ( defined( 'AAR_VERSION' ) && 1 === version_compare( '1.10.0', AAR_VERSION ) ) {
return;
}
$adsense_options = Advanced_Ads_AdSense_Data::get_instance()->get_options();
$auto_ads_enabled = ! empty( $adsense_options['amp']['auto_ads_enabled'] );
$option_name = GADSENSE_OPT_NAME . '[amp]';
include GADSENSE_BASE_PATH . 'admin/views/settings/amp-auto-ads.php';
}
/**
* Render AdSense violation warnings setting
*
* @since 1.6.9
*/
public function render_settings_adsense_warnings_disable() {
$options = $this->data->get_options();
$disable_violation_warnings = isset( $options['violation-warnings-disable'] ) ? 1 : 0;
?>
<label><input type="checkbox" name="<?php echo esc_attr( GADSENSE_OPT_NAME ); ?>[violation-warnings-disable]" value="1" <?php checked( 1, $disable_violation_warnings ); ?> />
<?php esc_html_e( 'Disable warnings about potential violations of the AdSense terms.', 'advanced-ads' ); ?></label>
<p class="description">
<?php
printf(
wp_kses(
/* translators: %s is a URL. */
__( 'Our <a href="%s" target="_blank">Ad Health</a> feature monitors if AdSense is implemented correctly on your site. It also considers ads not managed with Advanced Ads. Enable this option to remove these checks', 'advanced-ads' ),
[
'a' => [
'href' => true,
'target' => true,
],
]
),
'https://wpadvancedads.com/manual/ad-health/?utm_source=advanced-ads&utm_medium=link&utm_campaign=backend-autoads-ads'
);
?>
</p>
<?php
}
/**
* Render transparent background setting.
*/
public function render_settings_adsense_background() {
$options = $this->data->get_options();
$background = $options['background'];
?>
<label>
<input type="checkbox" name="<?php echo esc_attr( GADSENSE_OPT_NAME ); ?>[background]" value="1" <?php checked( $background ); ?> />
<?php esc_html_e( 'Enable this option in case your theme adds an unfortunate background color to AdSense ads.', 'advanced-ads' ); ?>
</label>
<?php
}
/**
* Render full width ads setting.
*/
public function render_settings_adsense_fullwidth() {
$options = $this->data->get_options();
$fw = ! empty( $options['fullwidth-ads'] ) ? $options['fullwidth-ads'] : 'default';
?>
<select name="<?php echo esc_attr( GADSENSE_OPT_NAME ); ?>[fullwidth-ads]">
<option value="default" <?php selected( $fw, 'default' ); ?>><?php esc_html_e( 'default', 'advanced-ads' ); ?></option>
<option value="enable" <?php selected( $fw, 'enable' ); ?>><?php esc_html_e( 'enable', 'advanced-ads' ); ?></option>
<option value="disable" <?php selected( $fw, 'disable' ); ?>><?php esc_html_e( 'disable', 'advanced-ads' ); ?></option>
</select>
<p class="description">
<?php
echo wp_kses(
sprintf(
/* translators: %s is a URL. */
__( "Whether your responsive ad unit may expand to <a href='%s' target='blank'>use the full width</a> of your visitor's mobile device screen", 'advanced-ads' ),
esc_url( 'https://support.google.com/adsense/answer/7445870' )
),
[
'a' => [
'href' => true,
'target' => true,
],
]
);
?>
</p>
<?php
}
/**
* Sanitize AdSense settings
*
* @param array $options all the options.
*/
protected function sanitize_settings( $options ) {
// Sanitize whatever option one wants to sanitize.
if ( isset( $options['adsense-id'] ) && '' !== $options['adsense-id'] ) {
// Remove "ca-" prefix if it was added by the user.
if ( 0 === strpos( $options['adsense-id'], 'ca-' ) ) {
$options['adsense-id'] = str_replace( 'ca-', '', $options['adsense-id'] );
}
// Trim publisher id.
$options['adsense-id'] = trim( $options['adsense-id'] );
}
return $options;
}
/**
* Save publisher id from new ad unit if not given in main options
*
* @param Ad $ad Ad instance.
* @param array $post_data Post data array.
*
* @return void
*/
public function sanitize_ad_settings( Ad $ad, $post_data ): void {
if ( ! $ad->is_type( 'adsense' ) ) {
return;
}
// Save AdSense publisher ID if there is no one stored yet.
if ( ! empty( $post_data['adsense-pub-id'] ) ) {
$adsense_options = get_option( 'advanced-ads-adsense', [] );
if ( empty( $adsense_options['adsense-id'] ) ) {
$adsense_options['adsense-id'] = $post_data['adsense-pub-id'];
update_option( 'advanced-ads-adsense', $adsense_options );
}
}
$ad->unset_prop( 'adsense-pub-id' );
}
/**
* Return ad units loaded through the API.
*
* @return array
*/
public function get_external_ad_units() {
$db = Advanced_Ads_AdSense_Data::get_instance();
$adsense_id = trim( $db->get_adsense_id() );
$units = [];
$mapi_options = Advanced_Ads_AdSense_MAPI::get_option();
if (
isset( $mapi_options['ad_codes'] )
&& isset( $mapi_options['accounts'] )
&& isset( $mapi_options['accounts'][ $adsense_id ] )
&& isset( $mapi_options['accounts'][ $adsense_id ]['ad_units'] )
) {
$ad_codes = $mapi_options['ad_codes'];
foreach ( $mapi_options['accounts'][ $adsense_id ]['ad_units'] as $id => $raw ) {
$ad_unit = new Advanced_Ads_Ad_Network_Ad_Unit( $raw );
$ad_unit->id = $id;
$ad_unit->slot_id = isset( $raw['code'] ) ? $raw['code'] : '-';
$ad_unit->name = isset( $raw['name'] ) ? $raw['name'] : '-';
// phpcs:ignore
$ad_unit->active = isset( $raw['status'] ) && in_array( $raw['status'], self::$status_codes_active );
if ( isset( $ad_codes[ $id ] ) ) {
$ad_unit->code = $ad_codes[ $id ];
}
if ( isset( $raw['contentAdsSettings'] ) ) {
if ( isset( $raw['contentAdsSettings']['type'] ) ) {
$ad_unit->display_type = $raw['contentAdsSettings']['type'];
$ad_unit->display_type = Advanced_Ads_AdSense_MAPI::format_ad_data( $ad_unit, 'type' );
}
if ( isset( $raw['contentAdsSettings']['size'] ) ) {
$ad_unit->display_size = $raw['contentAdsSettings']['size'];
$ad_unit->display_size = Advanced_Ads_AdSense_MAPI::format_ad_data( $ad_unit, 'size' );
}
}
$units[] = $ad_unit;
}
}
return $units;
}
/**
* Render the list of ads loaded through the API.
*
* @param bool $hide_idle_ads true to hide inactive ads.
* @param null $ad_unit_id ID of the ad unit.
*
* @return mixed|void
*/
public function print_external_ads_list( $hide_idle_ads = true, $ad_unit_id = null ) {
Advanced_Ads_AdSense_Admin::get_mapi_ad_selector( $hide_idle_ads );
}
/**
* Whether the loaded AdSense ad is supported through the API.
* at the time we wrote this, native ad formats like In-article, In-feed and Matched Content are not supported.
*
* @param object $ad_unit ad unit object.
*
* @return bool
*/
public function is_supported( $ad_unit ) {
$mapi_options = Advanced_Ads_AdSense_MAPI::get_option();
$supported = ! array_key_exists( $ad_unit->id, $mapi_options['unsupported_units'] );
if ( ! $supported ) {
$supported = array_key_exists( $ad_unit->id, $mapi_options['ad_codes'] );
}
return $supported;
}
/**
* Update the list of external ad units.
*/
public function update_external_ad_units() {
Advanced_Ads_AdSense_MAPI::get_instance()->ajax_get_adUnits();
}
/**
* If the AdSense account is connected.
*
* @return bool
*/
public function is_account_connected() {
return Advanced_Ads_AdSense_Data::get_instance()->is_setup();
}
/**
* Return path to module-specific JavaScript.
*
* @return string
*/
public function get_javascript_base_path() {
return GADSENSE_BASE_URL . 'admin/assets/js/adsense.js';
}
/**
* JavaScript data to print in the source code.
*
* @inheritDoc
*
* @param array $data data to be printed.
* @return array
*/
public function append_javascript_data( &$data ) {
$pub_id = Advanced_Ads_AdSense_Data::get_instance()->get_adsense_id();
$data['pubId'] = $pub_id;
$data['connected'] = $this->is_account_connected();
$data['ad_types'] = [
'matched_content' => _x( 'Multiplex', 'AdSense ad type', 'advanced-ads' ),
'in_article' => _x( 'In-article', 'AdSense ad type', 'advanced-ads' ),
'in_feed' => _x( 'In-feed', 'AdSense ad type', 'advanced-ads' ),
'display' => _x( 'Display', 'AdSense ad type', 'advanced-ads' ),
'link' => _x( 'Link', 'AdSense ad type', 'advanced-ads' ),
];
return $data;
}
/**
* If the ad also has a manual ad setup option.
*
* @return bool
*/
public function supports_manual_ad_setup() {
return true;
}
/**
* Get the ad unit associated with a given ad ID.
*
* @param int $ad_id The ID of the ad.
* @return object|null The ad unit object associated with the given ad ID, or null if not found.
*/
function get_ad_unit( $ad_id ){
$adense_ad = wp_advads_get_ad( $ad_id );
// Early bail!!
if ( ! $adense_ad || ! $adense_ad->is_type( 'adsense' ) || empty( $adense_ad->get_content() ) ) {
return null;
}
$ad_units = $this->get_external_ad_units();
if ( empty( $ad_units ) ) {
return null;
}
$json_content = json_decode( $adense_ad->get_content() );
$unit_code = $json_content->slotId ?? null;
foreach( $ad_units as $ad_unit ) {
if( $ad_unit->slot_id === $unit_code){
return $ad_unit;
}
}
return null;
}
}

View File

@@ -0,0 +1,200 @@
<?php
/**
* This class represents the "Adsense" ad type.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 2.4.0
*/
namespace AdvancedAds\Adsense\Types;
use Advanced_Ads_Ad_Type_Adsense;
use Advanced_Ads_AdSense_Data;
use Advanced_Ads_AdSense_MAPI;
use AdvancedAds\Interfaces\Ad_Type;
defined( 'ABSPATH' ) || exit;
/**
* Type Adsense.
*/
class Adsense implements Ad_Type {
/**
* Get the unique identifier (ID) of the ad type.
*
* @return string The unique ID of the ad type.
*/
public function get_id(): string {
return 'adsense';
}
/**
* Get the class name of the object as a string.
*
* @return string
*/
public function get_classname(): string {
return Advanced_Ads_Ad_Type_Adsense::class;
}
/**
* Get the title or name of the ad type.
*
* @return string The title of the ad type.
*/
public function get_title(): string {
return __( 'AdSense ad', 'advanced-ads' );
}
/**
* Get a description of the ad type.
*
* @return string The description of the ad type.
*/
public function get_description(): string {
return __( 'Use ads from your Google AdSense account', 'advanced-ads' );
}
/**
* Check if this ad type requires premium.
*
* @return bool True if premium is required; otherwise, false.
*/
public function is_premium(): bool {
return false;
}
/**
* Get the URL for upgrading to this ad type.
*
* @return string The upgrade URL for the ad type.
*/
public function get_upgrade_url(): string {
return '';
}
/**
* Get the URL for upgrading to this ad type.
*
* @return string The upgrade URL for the ad type.
*/
public function get_image(): string {
return ADVADS_BASE_URL . 'assets/img/ad-types/adsense.svg';
}
/**
* Check if this ad type has size parameters.
*
* @return bool True if has size parameters; otherwise, false.
*/
public function has_size(): bool {
return true;
}
/**
* Output for the ad parameters metabox
*
* @since 1.4
* @param Ad $ad Ad instance.
*
* @return void
*/
public function render_parameters( $ad ): void {
// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
// TODO: THIS IS JUST A QUICK AND DIRTY HACK. Create a dedicated method to handle this properly.
?>
<script>
jQuery( function () {
<?php
$mapi_options = Advanced_Ads_AdSense_MAPI::get_option();
$json_ad_codes = wp_json_encode( $mapi_options['ad_codes'] );
?>
const adsense = new AdvancedAdsNetworkAdsense(<?php echo $json_ad_codes; // phpcs:ignore ?>)
AdvancedAdsAdmin.AdImporter.setup( adsense )
} )
</script>
<?php
$options = $ad->get_data();
$content = $ad->get_content() ?? '';
$unit_id = '';
$unit_pubid = '';
$unit_code = '';
$unit_type = 'responsive';
$unit_width = 0;
$unit_height = 0;
$json_content = '';
$unit_resize = '';
$extra_params = [
'default_width' => '',
'default_height' => '',
'at_media' => [],
];
$db = Advanced_Ads_AdSense_Data::get_instance();
$pub_id = trim( $db->get_adsense_id( $ad ) );
// check pub_id for errors.
$pub_id_errors = false;
if ( '' !== $pub_id && 0 !== strpos( $pub_id, 'pub-' ) ) {
$pub_id_errors = __( 'The Publisher ID has an incorrect format. (must start with "pub-")', 'advanced-ads' );
}
global $external_ad_unit_id, $use_dashicons, $closeable;
$closeable = true;
$use_dashicons = false;
$external_ad_unit_id = '';
if ( trim( $content ) !== '' ) {
$json_content = stripslashes( $content );
// get json content striped by slashes.
$content = json_decode( stripslashes( $content ) );
if ( isset( $content->unitType ) ) {
$content->json = $json_content;
$unit_type = $content->unitType;
$unit_code = $content->slotId;
$unit_pubid = ! empty( $content->pubId ) ? $content->pubId : $pub_id;
$layout = isset( $content->layout ) ? $content->layout : '';
$layout_key = isset( $content->layout_key ) ? $content->layout_key : '';
if ( 'responsive' !== $content->unitType && 'link-responsive' !== $content->unitType && 'matched-content' !== $content->unitType ) {
// Normal ad unit.
$unit_width = $ad->get_width();
$unit_height = $ad->get_height();
} else {
// Responsive && multiplex ads.
$unit_resize = ( isset( $content->resize ) ) ? $content->resize : 'auto';
if ( 'auto' !== $unit_resize ) {
$extra_params = apply_filters( 'advanced-ads-gadsense-ad-param-data', $extra_params, $content, $ad );
}
}
if ( ! empty( $unit_pubid ) ) {
$unit_id = 'ca-' . $unit_pubid . ':' . $unit_code;
}
$external_ad_unit_id = $unit_id;
}
}
if ( '' === trim( $pub_id ) && '' !== trim( $unit_code ) ) {
$pub_id_errors = __( 'Your AdSense Publisher ID is missing.', 'advanced-ads' );
}
$default_template = GADSENSE_BASE_PATH . 'admin/views/adsense-ad-parameters.php';
/**
* Inclusion of other UI template is done here. The content is passed in order to allow the inclusion of different
* templates file, depending of the ad. It's up to the developer to verify that $content is not an empty
* variable (which is the case for a new ad).
*
* Inclusion of .js and .css files for the ad creation/editon page are done by another hook. See
* 'advanced-ads-gadsense-ad-param-script' and 'advanced-ads-gadsense-ad-param-style' in "../admin/class-gadsense-admin.php".
*/
$template = apply_filters( 'advanced-ads-gadsense-ad-param-template', $default_template, $content );
require $template;
// phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
}
}

View File

@@ -0,0 +1,32 @@
<?php // phpcs:ignoreFile
if ( class_exists( 'Advanced_Ads', false ) ) {
define( 'GADSENSE_BASE_PATH', plugin_dir_path( __FILE__ ) );
define( 'GADSENSE_BASE_URL', plugins_url( basename( ADVADS_ABSPATH ) . '/modules/' . basename( GADSENSE_BASE_PATH ) . '/' ) );
define( 'GADSENSE_OPT_NAME', ADVADS_SLUG . '-adsense' );
function gadsense_init() {
Advanced_Ads_AdSense_Data::get_instance();
if ( is_admin() ) {
Advanced_Ads_AdSense_MAPI::get_instance();
}
if ( ! wp_doing_ajax() && is_admin() ) {
Advanced_Ads_AdSense_Admin::get_instance();
} else {
Advanced_Ads_AdSense_Public::get_instance();
}
$network = Advanced_Ads_Network_Adsense::get_instance();
$network->register();
add_action(
'advanced-ads-ad-types-manager',
function ( $manager ) {
$manager->register_type( \AdvancedAds\Adsense\Types\Adsense::class );
}
);
}
add_action( 'advanced-ads-plugin-loaded', 'gadsense_init' );
}

View File

@@ -0,0 +1,214 @@
<?php // phpcs:ignore WordPress.Files.FileName
use AdvancedAds\Utilities\Conditional;
/**
* Class Advanced_Ads_AdSense_Public.
*/
class Advanced_Ads_AdSense_Public {
/**
* AdSense account related data
*
* @var Advanced_Ads_AdSense_Data
*/
private $data;
/**
* Instance of Advanced_Ads_AdSense_Public
*
* @var Advanced_Ads_AdSense_Public
*/
private static $instance;
/**
* Advanced_Ads_AdSense_Public constructor.
*/
private function __construct() {
$this->data = Advanced_Ads_AdSense_Data::get_instance();
add_action( 'wp_head', [ $this, 'inject_header' ], 20 );
// Fires before cache-busting frontend is initialized and tracking method is set.
add_action( 'wp', [ $this, 'inject_amp_code' ], 20 );
}
/**
* Get singleton instance.
*
* @return self
*/
public static function get_instance() {
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Print data in the head tag on the front end.
*/
public function inject_header() {
$options = $this->data->get_options();
// Inject CSS to make AdSense background transparent.
if ( ! empty( $options['background'] ) ) {
// Some themes not only get the background wrong, but also add some padding to ins element.
echo '<style>ins.adsbygoogle { background-color: transparent; padding: 0; }</style>';
}
if ( Conditional::is_ad_disabled() || Conditional::is_amp() ) {
return;
}
$privacy = Advanced_Ads_Privacy::get_instance();
$privacy_options = $privacy->options();
$privacy_enabled = $privacy->get_state() !== 'not_needed';
$npa_enabled = ( ! empty( $privacy_options['enabled'] ) && 'custom' === $privacy_options['consent-method'] ) && ! empty( $privacy_options['show-non-personalized-adsense'] );
// Show non-personalized Adsense ads if non-personalized ads are enabled and consent was not given.
if ( $privacy_enabled && $npa_enabled ) {
echo '<script>';
// If the page is not from a cache.
if ( $privacy->get_state() === 'unknown' ) {
echo '(adsbygoogle=window.adsbygoogle||[]).requestNonPersonalizedAds=1;';
}
// If the page is from a cache, wait until 'advads.privacy' is available. Execute before cache-busting.
echo '( window.advanced_ads_ready || jQuery( document ).ready ).call( null, function() {
var state = ( advads.privacy ) ? advads.privacy.get_state() : "";
var use_npa = ( state === "unknown" ) ? 1 : 0;
(adsbygoogle=window.adsbygoogle||[]).requestNonPersonalizedAds=use_npa;
} )';
echo '</script>';
}
if ( ! apply_filters( 'advanced-ads-can-display-ads-in-header', true ) ) {
return;
}
$pub_id = trim( $this->data->get_adsense_id() );
if ( $pub_id && isset( $options['page-level-enabled'] ) && $options['page-level-enabled'] ) {
$pub_id = $this->data->get_adsense_id();
$client_id = 'ca-' . $pub_id;
$top_anchor = isset( $options['top-anchor-ad'] ) && $options['top-anchor-ad'];
$top_anchor_code = sprintf(
'(adsbygoogle = window.adsbygoogle || []).push({
google_ad_client: "%s",
enable_page_level_ads: true,
overlays: {bottom: true}
});',
esc_attr( $client_id )
);
/**
* Filter the output of the publisher ID appended to the AdSense JavaScript Code.
*
* @param boolean
*/
$add_publisher_id = apply_filters( 'advanced-ads-adsense-publisher-id', true );
$script_src = add_query_arg(
[ 'client' => $add_publisher_id ? esc_attr( $client_id ) : false ],
'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'
);
/**
* Allows to override the page-level code.
*
* The Pro add-on uses this filter to inject a drop-in replacement for the page-level header code.
*
* @param string $code Existing page level code.
* @param array $parameters {
* Parameters of the AdSense code.
*
* @type string $client_id The Google AdSense client ID.
* @type bool $top_anchor AdSense anchor ad on top of pages.
* @type string $top_anchor_code The code for top anchor ads.
* @type string $script_src AdSense script url.
* }
*/
$custom_code = apply_filters(
'advanced-ads-gadsense-page-level-code',
'',
compact( [ 'client_id', 'top_anchor', 'top_anchor_code', 'script_src' ] )
);
if ( $custom_code ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- the snippet has already been escaped.
echo $custom_code;
return;
}
// inject page-level header code.
include GADSENSE_BASE_PATH . 'public/templates/page-level.php';
}
}
/**
* Handle AdSense AMP code
*/
public function inject_amp_code() {
// for non-AMP pages we do this on the `template_redirect` hook, this has not fired yet.
wp_advads()->frontend->run_checks();
if (
Conditional::is_ad_disabled()
// check if this an AMP page, we're inside `wp` action so it's safe to use.
|| ! Conditional::is_amp()
) {
return;
}
// The is_amp_endpoint function is used for multiple plugins.
if ( function_exists( 'is_amp_endpoint' ) ) {
$adsense_data = Advanced_Ads_AdSense_Data::get_instance();
$adsense_options = $adsense_data->get_options();
// AMP Auto ads was removed from Responsive add-on version 1.10.0.
if (
( defined( 'AAR_VERSION' ) && 1 === version_compare( '1.10.0', AAR_VERSION ) ) ||
empty( $adsense_options['amp']['auto_ads_enabled'] )
) {
return;
}
// Adds the AdSense Auto ads AMP code to the page (head) in "Reader" mode.
add_action( 'amp_post_template_data', [ $this, 'add_auto_ads_amp_head_script' ] );
// SmartMag theme (http://theme-sphere.com/smart-mag/documentation/).
add_action( 'bunyad_amp_pre_main', [ $this, 'add_auto_ads_amp_body_script' ] );
/**
* Add AMP Auto ads body code to footer for `AMP` plugin ( https://wordpress.org/plugins/amp/ )
*
* Adds the Auto ads `body` tag to `wp_footer` because there is no WordPress right hook after `body`
* The AdSense Auto ads code is added automatically to the `head` section using the amp_post_template_data hook above.
*
* use `wp_footer` in Transition and Standard mode
* use `amp_post_template_footer` in Reader mode
*/
add_action( 'wp_footer', [ $this, 'add_auto_ads_amp_body_script' ] );
add_action( 'amp_post_template_footer', [ $this, 'add_auto_ads_amp_body_script' ] );
// Other AMP plugins.
}
}
/**
* Add AdSense AMP Auto ads code to the header.
*
* @param array $data AMP components.
*/
public function add_auto_ads_amp_head_script( $data ) {
$data['amp_component_scripts']['amp-auto-ads'] = 'https://cdn.ampproject.org/v0/amp-auto-ads-0.1.js';
return $data;
}
/**
* Add Adsense Auto Ads body script.
*/
public function add_auto_ads_amp_body_script() {
$pub_id = $this->data->get_adsense_id();
if ( $pub_id ) {
printf( '<amp-auto-ads type="adsense" data-ad-client="ca-%s"></amp-auto-ads>', esc_attr( $pub_id ) );
}
}
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* Output auto ads enabled code in head
*
* @var bool $privacy_enabled Whether to wait for user consent.
* @var bool $npa_enabled Whether to show non-personalized ads.
* @var string $client_id The Google AdSense client ID.
* @var bool $top_anchor AdSense anchor ad on top of pages.
* @var string $top_anchor_code The code for top anchor ads.
* @var string $script_src AdSense script url.
* @var bool $add_publisher_id Whether to add the publisher ID to the AdSense JavaScript URL.
*/
if ( $privacy_enabled ) : ?>
<script>
(function () {
var scriptDone = false;
document.addEventListener('advanced_ads_privacy', function (event) {
if (
(event.detail.state !== 'accepted' && event.detail.state !== 'not_needed' && !advads.privacy.is_adsense_npa_enabled())
|| scriptDone
) {
return;
}
// google adsense script can only be added once.
scriptDone = true;
var script = document.createElement('script'),
first = document.getElementsByTagName('script')[0];
script.async = true;
script.crossOrigin = 'anonymous';
script.src = '<?php echo esc_url( $script_src ); ?>';
<?php
if ( $top_anchor ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- relevant user input has already been escaped.
echo $top_anchor_code;
} elseif ( ! $add_publisher_id ) {
printf( 'script.dataset.adClient = "%s";', esc_attr( $client_id ) );
}
?>
first.parentNode.insertBefore(script, first);
});
})();
</script>
<?php
return;
endif;
// Privacy not enabled.
// phpcs:disable WordPress.WP.EnqueuedResources
if ( $top_anchor ) {
printf(
'<script async src="%s"></script><script>%s</script>',
esc_attr( $script_src ),
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- the snippet has already been escaped.
$top_anchor_code
);
} else {
// Don't add the data-ad-client attribute when the publisher ID is appended to the script URL.
printf(
'<script %s async src="%s" crossorigin="anonymous"></script>',
! $add_publisher_id ? 'data-ad-client="' . esc_attr( $client_id ) . '"' : '',
esc_url( $script_src )
);
}
// phpcs:enable