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,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
}
}