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,503 @@
<?php
/**
* Array with ad health messages
*
* Attribute: type
* - "notice" (default, recommendation, etc.)
* - "problem" (critical)
*
* attribute: can_hide
* (user can see a button to hide this warning, default: true)
*
* attribute: hide
* (how to handle click on "hide" button)
* - true (default, hide the item)
* - false (remove the item completely from list of notifications)
*
* attribute: timeout
* (for how long to hide/ignore the message in seconds.)
* - default: empty
*
* attribute: get_help_link
* (enter URL, if exists, will add a link after the message)
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.x.x
*/
$advanced_ads_ad_health_notices = apply_filters(
'advanced-ads-ad-health-notices',
[
// old PHP version
// checked using Advanced_Ads_Checks::php_version_minimum().
'old_php' => [
'text' => sprintf(
/* translators: %1$s is a version number */
__( 'Your <strong>PHP version (%1$s) is too low</strong>. Advanced Ads is built for PHP %2$s and higher. It might work, but updating PHP is highly recommended. Please ask your hosting provider for more information.', 'advanced-ads' ),
phpversion(),
Advanced_Ads_Checks::MINIMUM_PHP_VERSION
),
'type' => 'problem',
],
// conflicting plugins found
// Advanced_Ads_Checks::conflicting_plugins().
'conflicting_plugins' => [
'text' => sprintf(
/* translators: %1$s is a list of plugin names; %2$s is a target URL */
__( 'Plugins that are known to cause (partial) problems: <strong>%1$s</strong>. <a href="%2$s" target="_blank">Learn more</a>.', 'advanced-ads' ),
implode( ', ', Advanced_Ads_Checks::conflicting_plugins() ),
'https://wpadvancedads.com/manual/known-plugin-conflicts/?utm_source=advanced-ads&utm_medium=link&utm_campaign=error-plugin-conflicts'
),
'type' => 'problem',
],
// PHP extensions missing
// Advanced_Ads_Checks::php_extensions().
'php_extensions_missing' => [
'text' => sprintf(
/* translators: %s is a list of PHP extensions */
__( 'Missing PHP extensions could cause issues. Please ask your hosting provider to enable them: %s', 'advanced-ads' ),
implode( ', ', Advanced_Ads_Checks::php_extensions() )
),
'type' => 'problem',
],
// ads are disabled
// Advanced_Ads_Checks::ads_disabled().
'ads_disabled' => [
'text' => sprintf(
/* translators: %s is a target URL */
__( 'Ads are disabled for all or some pages. See "disabled ads" in <a href="%s">settings</a>.', 'advanced-ads' ),
admin_url( 'admin.php?page=advanced-ads-settings#top#general' )
),
'type' => 'problem',
],
// check if Advanced Ads related constants are enabled
// Advanced_Ads_Checks::get_defined_constants().
'constants_enabled' => [
'text' => '<a href="' . admin_url( 'admin.php?page=advanced-ads-settings#top#support' ) . '">' . esc_html__( 'Advanced Ads related constants enabled', 'advanced-ads' ) . '</a>',
'type' => 'notice',
],
// adblocker assets expired
// Advanced_Ads_Checks::assets_expired().
'assets_expired' => [
'text' => sprintf(
/* translators: %s is a target URL */
__( 'Some assets were changed. Please <strong>rebuild the asset folder</strong> in the <a href="%s">Advanced Ads settings</a> to update the ad blocker disguise.', 'advanced-ads' ),
admin_url( 'admin.php?page=advanced-ads-settings' )
),
'type' => 'problem',
'hide' => true,
],
// missing license codes
// Advanced_Ads_Checks::license_invalid().
'license_invalid' => [
'text' => __( 'One or more license keys for <strong>Advanced Ads add-ons are invalid or missing</strong>.', 'advanced-ads' ) . ' '
. sprintf(
/* translators: %s is a target URL. */
__( 'Please add valid license keys <a href="%s">here</a>.', 'advanced-ads' ),
get_admin_url( null, 'admin.php?page=advanced-ads-settings#top#licenses' )
),
'type' => 'problem',
'hide' => false,
'timeout' => WEEK_IN_SECONDS,
],
// an individual ad expired.
'ad_expired' => [
'text' => __( 'Ad expired', 'advanced-ads' ) . ': ',
'type' => 'notice',
'hide' => false,
],
// a visible ad is used in <head> tags
// is checked in the frontend by Ad Health in Advanced_Ads_Frontend_Checks::can_use_head_placement().
'ad_with_output_in_head' => [
// we keep the %s here and replace it with an empty string, because we use it somewhere else and dont want to create a new string that is basically the same.
'text' => sprintf(
/* translators: %s is empty here, but the string will be followed by a name of an ad unit. */
__( 'Visible ads should not use the Header placement: %s', 'advanced-ads' ),
''
),
'type' => 'notice',
'hide' => false,
'get_help_link' => 'https://wpadvancedads.com/manual/ad-health/?utm_source=advanced-ads&utm_medium=link&utm_campaign=error-visible-ad-in-header#header-ads',
'timeout' => YEAR_IN_SECONDS,
],
// Ad has HTTP, but site uses HTTPS
// check in Ad Health in frontend.
'ad_has_http' => [
'text' => __( 'Your website is using HTTPS, but the ad code contains HTTP and might not work.', 'advanced-ads' ),
'type' => 'notice',
'hide' => false,
'get_help_link' => 'https://wpadvancedads.com/manual/ad-health/?utm_source=advanced-ads&utm_medium=link&utm_campaign=error-https-ads#https-ads',
],
// dummy text for general AdSense issue.
'adsense_issue' => [
// we keep the %s here and replace it with an empty string, because we use it somewhere else and dont want to create a new string that is basically the same.
'text' => __( 'AdSense issue', 'advanced-ads' ),
'type' => 'problem',
],
// AdSense connection error: disapproved account.
'adsense_connect_disapprovedAccount' => [
'text' => __( 'Last AdSense account connection attempt failed.', 'advanced-ads' ) . '&nbsp;' . __( 'Your account was not approved by AdSense.', 'advanced-ads' ) . ' ' . Advanced_Ads_Ad_Health_Notices::get_adsense_error_link( 'disapprovedAccount' ),
'type' => 'problem',
'hide' => false,
],
// AdSense connection error: no adsense account.
'adsense_connect_noAdSenseAccount' => [
'text' => sprintf(
__( 'Last AdSense account connection attempt failed.', 'advanced-ads' ) . '&nbsp;' .
/* translators: %1$s is the opening a tag and %2$s the closing one. */
__( 'Create a new AdSense account %1$shere%2$s.', 'advanced-ads' ) . ' ' . Advanced_Ads_Ad_Health_Notices::get_adsense_error_link( 'noAdSenseAccount' ),
'<a href="https://www.google.com/adsense/start/?utm_source=AdvancedAdsPlugIn&utm_medium=partnerships&utm_campaign=AdvancedAdsPartner1" target="_blank">',
'</a>'
),
'type' => 'problem',
'hide' => false,
],
// AdSense account alert. Missing ads.txt version 1.
'adsense_alert_ALERT_TYPE_ADS_TXT_UNAUTHORIZED' => [
'text' => sprintf(
__( 'One of your sites is missing the AdSense publisher ID in the ads.txt file.', 'advanced-ads' )
. ' <a class="advads-settings-link" href="%s">'
. _x( 'Create one now.', 'related to ads.txt file', 'advanced-ads' ) . '</a>',
admin_url( 'admin.php?page=advanced-ads-settings#general__advads-ads-txt' )
) . ' ' . Advanced_Ads_Ad_Health_Notices::get_adsense_error_link( 'ALERT_TYPE_ADS_TXT_UNAUTHORIZED' ),
'type' => 'problem',
],
// AdSense account alert. . Missing ads.txt version 2.
'adsense_alert_ADS_TXT_MISSING' => [
'text' => sprintf(
__( 'One of your sites is missing the AdSense publisher ID in the ads.txt file.', 'advanced-ads' )
. ' <a class="advads-settings-link" href="%s">'
. _x( 'Create one now.', 'related to ads.txt file', 'advanced-ads' ) . '</a>',
admin_url( 'admin.php?page=advanced-ads-settings#general__advads-ads-txt' )
) . ' ' . Advanced_Ads_Ad_Health_Notices::get_adsense_error_link( 'ADS_TXT_MISSING' ),
'type' => 'problem',
],
// AdSense account alert. . Missing ads.txt version 3.
'adsense_alert_ADS_TXT_ISSUES' => [
'text' => sprintf(
__( 'One of your sites is missing the AdSense publisher ID in the ads.txt file.', 'advanced-ads' )
. ' <a class="advads-settings-link" href="%s">'
. _x( 'Create one now.', 'related to ads.txt file', 'advanced-ads' ) . '</a>',
admin_url( 'admin.php?page=advanced-ads-settings#general__advads-ads-txt' )
) . ' ' . Advanced_Ads_Ad_Health_Notices::get_adsense_error_link( 'ADS_TXT_ISSUES' ),
'type' => 'problem',
],
// AdSense deprecated link units.
'adsense_link_units_deprecated' => [
'text' => __( 'Google AdSense deprecated Link Units. Please choose another format.', 'advanced-ads' )
. ' <a href="https://wpadvancedads.com/adsense-link-units/" target="_blank" rel="noopener">'
. esc_html__( 'Learn more', 'advanced-ads' )
. '</a>',
'type' => 'problem',
],
'nested_the_content_filters' => [
'text' => sprintf(
/* translators: %s is a filter hook, here `the_content`. */
__( '<strong>%s</strong> filter found multiple times.', 'advanced-ads' ),
'the_content'
) . '&nbsp;' . __( 'Advanced Ads uses the outermost of them.', 'advanced-ads' ),
'get_help_link' => 'https://wpadvancedads.com/manual/ad-health/?utm_source=advanced-ads&utm_medium=link&utm_campaign=error-multiple-the-content#the_content_filter_found_multiple_times',
'type' => 'notice',
'hide' => false,
],
// BuddyPress installed.
'buddypress_no_pro' => [
'text' => sprintf(
/* translators: %1$s is a plugin name, %2$s is the opening a tag and %3$s the closing one. */
__( 'Learn how to integrate %1$s with Advanced Ads %2$shere%3$s.', 'advanced-ads' ),
'<strong>BuddyPress</strong>',
'<a href="https://wpadvancedads.com/ads-on-buddypress-pages/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-buddypress" target="_blank">',
'</a>'
),
'type' => 'notice',
],
// BuddyBoss installed.
'buddyboss_no_pro' => [
'text' => sprintf(
/* translators: %1$s is a plugin name, %2$s is the opening a tag and %3$s the closing one. */
__( 'Learn how to integrate %1$s with Advanced Ads %2$shere%3$s.', 'advanced-ads' ),
'<strong>BuddyBoss</strong>',
'<a href="https://wpadvancedads.com/manual/buddyboss-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-buddyboss" target="_blank">',
'</a>'
),
'type' => 'pitch',
],
// bbPress installed.
'bbpress_no_pro' => [
'text' => sprintf(
/* translators: %1$s is a plugin name, %2$s is the opening a tag and %3$s the closing one. */
__( 'Learn how to integrate %1$s with Advanced Ads %2$shere%3$s.', 'advanced-ads' ),
'<strong>bbPress</strong>',
'<a href="https://wpadvancedads.com/ads-in-bbpress/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-bbpress" target="_blank">',
'</a>'
),
'type' => 'notice',
],
// WPML plugin activated.
'WPML_active' => [
'text' => sprintf(
/* translators: %1$s is a plugin name, %2$s is the opening a tag and %3$s the closing one. */
__( 'Learn how to integrate %1$s with Advanced Ads %2$shere%3$s.', 'advanced-ads' ),
'<strong>WPML</strong>',
'<a href="https://wpadvancedads.com/translating-ads-wpml/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-WPML" target="_blank">',
'</a>'
),
'type' => 'notice',
'hide' => false,
'timeout' => YEAR_IN_SECONDS,
],
// AMP and Accelerated Mobile Pages plugins.
'AMP_active' => [
'text' => sprintf(
/* translators: %1$s is a plugin name, %2$s is the opening a tag and %3$s the closing one. */
__( 'Learn how to integrate %1$s with Advanced Ads %2$shere%3$s.', 'advanced-ads' ),
'<strong>AMP</strong>',
'<a href="https://wpadvancedads.com/manual/ads-on-amp-pages/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-amp" target="_blank">',
'</a>'
),
'type' => 'notice',
'hide' => false,
'timeout' => YEAR_IN_SECONDS,
],
// Hosting on WP Engine
// Advanced_Ads_Checks::wp_engine_hosting().
'wpengine' => [
'text' => sprintf(
/* translators: %s is a service or plugin name */
'<strong>' . __( '%s detected.', 'advanced-ads' ) . '</strong>'
. ' <a href="https://wpadvancedads.com/wp-engine-and-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-wpengine">' . __( 'Learn how this might impact your ad setup.', 'advanced-ads' ) . '</a>',
'WP Engine'
),
'type' => 'notice',
'hide' => false,
'timeout' => YEAR_IN_SECONDS,
],
// Notice about existing ads.txt plugins.
// Advanced_Ads_Checks::ads_txt_plugins().
'ads_txt_plugins_enabled' => [
'text' => sprintf(
/* translators: %s removable ads.txt plugins */
__( 'Advanced Ads handles your ads.txt file automatically. You might be able to <strong>remove %1$s</strong>.', 'advanced-ads' ),
implode( ', ', Advanced_Ads_Checks::ads_txt_plugins() )
),
'type' => 'notice',
'hide' => false,
'timeout' => YEAR_IN_SECONDS,
],
// Notice about plugins that add header or footer code.
// Advanced_Ads_Checks::header_footer_plugins().
'header_footer_plugins_enabled' => [
'text' =>
__( 'Advanced Ads handles header and footer codes.', 'advanced-ads' ) . '&nbsp;' .
sprintf(
/* translators: %s removable header and footer plugins */
__( 'You might be able to <strong>remove %1$s</strong>.', 'advanced-ads' ),
implode( ', ', Advanced_Ads_Checks::header_footer_plugins() )
) . '&nbsp;' .
'<a href="https://wpadvancedads.com/add-header-and-footer-code-wordpress/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-header-footer" target="_blank">' . __( 'Learn how.', 'advanced-ads' ) . '</a>',
'type' => 'notice',
'hide' => false,
'timeout' => YEAR_IN_SECONDS,
],
// GamiPress.
'gamipress_no_pro' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to target ads on GamiPress websites %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/manual/gamipress-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-gamipres" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Paid Membership Pro.
'pmp_no_pro' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to manage ads on membership sites running Paid Memberships Pro %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/paid-memberships-pro/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-pmp" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Members plugin.
'members_no_pro' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to target ads to specific user roles created with the Members plugin %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/members-plugin-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-members" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Members plugin.
'translatepress_no_pro' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to target ads to multiple languages in TranslatePress %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/translatepress/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-translatepress" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Weglot.
'weglot_no_pro' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to target ads to multiple languages in Weglot %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/weglot/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-weglot" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// LearnDash.
'learndash' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to integrate ads into LearnDash %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/learndash-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-learndash" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// AAWP.
'aawp' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to auto-inject Amazon Ads with AAWP and Advanced Ads %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/aawp-amazon/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-aawp" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Polylang.
'polylang' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to target ads to multiple languages in Polylang %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/polylang/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-polylang" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// MailPoet.
'mailpoet' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to integrate Advanced Ads in MailPoet Newsletters %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/mailpoet-newsletters/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-mailpoet" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// WP Rocket.
'wp_rocket' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to use WP Rocket with Advanced Ads %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/wp-rocket-adsense/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-wprocket" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Quiz plugins.
'quiz_plugins_no_pro' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to embed Ads into a Quiz %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/quiz-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-quiz" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Elementor.
'elementor' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to create and implement ads in Elementor %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/elementor-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-elementor" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// SiteOrigin.
'siteorigin' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to embed ads into a website built with the SiteOrigin page builder %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/siteorigin-page-builder/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-siteorigin" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Divi Theme or Divi builder plugin.
'divi_no_pro' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to integrate ads into the Divi theme and Divi builder %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/divi-theme-builder/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-divi" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Divi Theme or Divi builder plugin.
'beaver_builder' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to embed ads into your Beaver Builder website %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/beaver-builder-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-beaverbuilder" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Pagelayer plugin.
'pagelayer' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to embed ads into a website built with Pagelayer %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/pagelayer/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-pagelayer" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// WPBakery Page Builder.
'wpb' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn more about displaying Ads with WPBakery Page Builder %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/visual-composer-ads/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-wpbakery" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
// Newspaper theme.
'newspaper' => [
'text' => sprintf(
/* translators: 1 opening anchor tag, 2 closing tag, 3 icon */
__( 'Learn how to integrate ads into the tagDiv Newspaper theme %1$shere%2$s %3$s', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/tagdiv-newspaper-theme/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-newspaper" target="_blank">',
'</a>',
'<i class="dashicons dashicons-external"></i>'
),
'type' => 'pitch',
],
]
);

View File

@@ -0,0 +1,108 @@
<?php // phpcs:ignore WordPress.Files.FileName
/**
* This represents an external ad unit. Will be used for importing external ads from various ad networks.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.x.x
*/
/**
* Class Advanced_Ads_Ad_Network_Ad_Unit
*/
class Advanced_Ads_Ad_Network_Ad_Unit {
/**
* Contains the raw data (typically from a JSON response) for this ad unit
*
* @var string
*/
public $raw;
/**
* The (external) id of this ad unit (e.g. pub-ca... for adsense)
*
* @var string
*/
public $id;
/**
* The display name of the ad
*
* @var string
*/
public $name;
/**
* The type of this ad unit (displayed in list)
*
* @var string
*/
public $display_type;
/**
* The size of this ad unit (displayed in list)
*
* @var string
*/
public $display_size;
/**
* In case of an AdSense ad, this is the id of the ad without the publisher id
* the value will be displayed in the ads list
*
* @var string
*/
public $slot_id;
/**
* A bool that indicates whether an ad is active (inactives will be hidden by default)
*
* @var bool
*/
public $active;
/**
* Advanced_Ads_Ad_Network_Ad_Unit constructor.
*
* @param string $raw raw ad data.
*/
public function __construct( $raw ) {
$this->raw = $raw;
}
/**
* Sort multiple ad units.
*
* @param array $ad_units array of ad units.
* @param string $selected_id ID of the selected ad. Can be taken from the ad network and therefore also a string.
*
* @return array
*/
public static function sort_ad_units( array &$ad_units, $selected_id ) {
$selected_id = absint( $selected_id );
usort(
$ad_units,
function ( $a, $b ) use ( $selected_id ) {
if ( absint( $a->id ) === $selected_id ) {
return - 1;
}
if ( absint( $b->id ) === $selected_id ) {
return 1;
}
if ( $a->is_supported ) {
if ( ! $b->is_supported ) {
return - 1;
}
} elseif ( $b->is_supported ) {
return 1;
}
return strcasecmp( $a->name, $b->name );
}
);
return $ad_units;
}
}

View File

@@ -0,0 +1,468 @@
<?php // phpcs:ignore WordPress.Files.FileName
/**
* This class represents an ad network. It is used to manage the settings and the ad units of an ad network.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.x.x
*/
use AdvancedAds\Abstracts\Ad;
use AdvancedAds\Utilities\Conditional;
use AdvancedAds\Framework\Utilities\Params;
/**
* Class Advanced_Ads_Ad_Network
*/
abstract class Advanced_Ads_Ad_Network {
/**
* The identifier will be used for generated ids, names etc.
*
* @var string
*/
protected $identifier;
/**
* The name of the ad network
*
* @var string
*/
protected $name;
/**
* The name of the hook for the advanced ads settings page
*
* @var string
*/
protected $settings_page_hook;
/**
* The WordPress nonce (retrieve with the get_nonce method)
*
* @var string
*/
protected $nonce;
/**
* The networks settings section ID
*
* @var string
*/
protected $settings_section_id;
/**
* The networks settings init hook.
*
* @var string
*/
private $settings_init_hook;
/**
* Advanced_Ads_Ad_Network constructor.
*
* @param string $identifier an identifier that will be used for hooks, settings, ids and much more - MAKE SURE IT IS UNIQUE.
* @param string $name - the (translateable) display name for this ad network.
*/
public function __construct( $identifier, $name ) {
$this->identifier = $identifier;
$this->name = $name;
$this->settings_page_hook = ADVADS_SLUG . '-' . $this->identifier . '-settings-page';
$this->settings_section_id = ADVADS_SLUG . '-' . $this->identifier . '-settings-section';
$this->settings_init_hook = ADVADS_SLUG . '-' . $this->identifier . '-settings-init';
}
/**
* The identifier for this network
*
* @return string
*/
public function get_identifier() {
return $this->identifier;
}
/**
* The display name for this network
*
* @return string
*/
public function get_display_name() {
return $this->name;
}
/**
* The display value for the settings tab
*
* @return string
*/
public function get_settings_tab_name() {
return $this->get_display_name();
}
/**
* URL for the settings page (admin)
*
* @return string
*/
public function get_settings_href() {
return admin_url( 'admin.php?page=advanced-ads-settings#top#' . $this->identifier );
}
/**
* The identifier / name for the javascript file that will be injected.
*
* @return string
*/
public function get_js_library_name() {
return 'advanced-ads-network' . $this->identifier;
}
/**
* Registers this ad network
*/
public function register() {
if ( is_admin() ) {
if ( wp_doing_ajax() ) {
// we need add all the actions for our ajax calls here.
// our ajax method that will trigger an update of the ad units of this network.
add_action( 'wp_ajax_advanced_ads_get_ad_units_' . $this->identifier, [ $this, 'update_external_ad_units' ] );
add_action( 'wp_ajax_advanced_ads_toggle_idle_ads_' . $this->identifier, [ $this, 'toggle_idle_ads' ] );
} else {
// find out if we need to register the settings. this is necessary
// 1) when viewing the settings (admin.php with page="advanced-ads-settings")
// 2) when posting the settings to options.php
// in all other cases, there is nothing to do.
global $pagenow;
$requires_settings = false;
$requires_javascript = false;
if ( 'admin.php' === $pagenow ) {
$page = Params::request( 'page', null );
switch ( $page ) {
case 'advanced-ads-settings':
$requires_settings = true;
$requires_javascript = true;
break;
case 'advanced-ads':
$requires_javascript = true;
break;
default:
break;
}
} elseif ( 'options.php' === $pagenow ) {
$requires_settings = true;
} elseif ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) {
add_action( 'advanced-ads-ad-pre-save', [ $this, 'sanitize_ad_settings' ], 10, 2 );
if ( 'edit' === Params::get( 'action' ) ) {
$requires_javascript = true;
} elseif ( 'advanced_ads' === Params::request( 'post_type', '' ) ) {
$requires_javascript = true;
}
}
if ( $requires_settings ) {
// register the settings.
add_action( 'advanced-ads-settings-init', [ $this, 'register_settings_callback' ] );
add_filter( 'advanced-ads-setting-tabs', [ $this, 'register_settings_tabs_callback' ] );
}
if ( $requires_javascript ) {
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts_callback' ] );
}
}
}
}
/**
* This method will be called for the wp action "advanced-ads-settings-init" and therefore has to be public.
*/
public function register_settings_callback() {
// register new settings.
register_setting(
ADVADS_SLUG . '-' . $this->identifier,
ADVADS_SLUG . '-' . $this->identifier,
[ $this, 'sanitize_settings_callback' ]
);
/**
* Allow Ad Admin to save AdSense options.
*
* @param array $settings Array with allowed options.
*
* @return array
*/
add_filter(
'advanced-ads-ad-admin-options',
function ( $options ) {
$options[] = ADVADS_SLUG . '-' . $this->identifier;
return $options;
}
);
// add a new section.
add_settings_section(
$this->settings_section_id,
'',
'__return_empty_string',
$this->settings_page_hook
);
// register all the custom settings.
$this->register_settings( $this->settings_page_hook, $this->settings_section_id );
do_action( $this->settings_init_hook, $this->settings_page_hook );
}
/**
* Create name of the object used for localized data
*
* @return string
*/
protected function get_localized_script_object_name() {
return $this->identifier . 'AdvancedAdsJS';
}
/**
* Engueue scripts
*/
public function enqueue_scripts_callback() {
if ( ! Conditional::is_screen_advanced_ads() ) {
return;
}
$js_path = $this->get_javascript_base_path();
if ( $js_path ) {
$id = $this->get_js_library_name();
wp_enqueue_script( $id, $js_path, [ 'jquery' ], '1.7.3' ); // phpcs:ignore
// next we have to pass the data.
$data = [
'nonce' => $this->get_nonce(),
];
$data = $this->append_javascript_data( $data );
wp_localize_script( $id, $this->get_localized_script_object_name(), $data );
}
}
/**
* Get a nonce
*
* @return string
*/
public function get_nonce() {
if ( ! $this->nonce ) {
$this->nonce = wp_create_nonce( $this->get_nonce_action() );
}
return $this->nonce;
}
/**
* Returns the action (name) of the nonce for this network
* in some cases you may want to override this method to faciliate
* integration with existing code
*
* @return string
*/
public function get_nonce_action() {
return 'advads-network-' . $this->identifier;
}
/**
* This method will be called for the wp action "advanced-ads-settings-tabs" and therefore has to be public.
* it simply adds a tab for this ad type. if you don't want that just override this method with an empty one.
*
* @param array $tabs tabs on Advanced Ads settings page.
*
* @return array
*/
public function register_settings_tabs_callback( $tabs ) {
$tab_id = $this->identifier;
$tabs[ $tab_id ] = [
'page' => $this->settings_page_hook,
'group' => ADVADS_SLUG . '-' . $this->identifier,
'tabid' => $tab_id,
'title' => $this->get_settings_tab_name(),
];
return $tabs;
}
/**
* Callback to sanitize settings
*
* @param array $options options to be sanitized.
*
* @return mixed
*/
public function sanitize_settings_callback( $options ) {
$options = $this->sanitize_settings( $options );
return $options;
}
/**
* Performs basic security checks for wp ajax requests (nonce, capabilities)
* dies, when a problem was detected
*/
protected function ajax_security_checks() {
if ( ! Conditional::user_can( 'advanced_ads_manage_options' ) ) {
$this->send_ajax_error_response_and_die( __( 'You don\'t have the permission to manage ads.', 'advanced-ads' ) );
}
$nonce = Params::request( 'nonce', '' );
if ( ! wp_verify_nonce( $nonce, $this->get_nonce_action() ) ) {
$this->send_ajax_error_response_and_die( __( 'You sent an invalid request.', 'advanced-ads' ) );
}
}
/**
* Send data via AJAX but dont react on it.
*
* @param bool $json_serializable_response true if data can be serialized.
*/
protected function send_ajax_response_and_die( $json_serializable_response = false ) {
if ( ! $json_serializable_response ) {
$json_serializable_response = new stdClass();
}
header( 'Content-Type: application/json' );
echo wp_json_encode( $json_serializable_response );
die();
}
/**
* Send message via AJAX but dont react on it.
*
* @param string $message message string.
*/
protected function send_ajax_error_response_and_die( $message ) {
header( 'Content-Type: application/json' );
$r = new stdClass();
$r->error = $message;
echo wp_json_encode( $r );
die();
}
/**
* Toggle ad IDs
*/
public function toggle_idle_ads() {
$this->ajax_security_checks();
global $external_ad_unit_id;
$hide_idle_ads = Params::post( 'hide' );
$external_ad_unit_id = Params::post( 'ad_unit_id', '' );
if ( ! $external_ad_unit_id ) {
$external_ad_unit_id = '';
}
ob_start();
$this->print_external_ads_list( $hide_idle_ads );
$ad_selector = ob_get_clean();
$response = [
'status' => true,
'html' => $ad_selector,
];
$this->send_ajax_response_and_die( $response );
}
/**
* When you need some kind of manual ad setup (meaning you can edit the custom inputs of this ad type)
* you should override this method to return true. this results in an additional link (Setup code manually)
*
* @return bool
*/
public function supports_manual_ad_setup() {
return false;
}
/**
* Print a list of ads.
*
* @param bool $hide_idle_ads true to hide idle ids.
*
* @return mixed
*/
abstract public function print_external_ads_list( $hide_idle_ads = true );
/**
* This method will be called via wp AJAX.
* it has to retrieve the list of ads from the ad network and store it as an option
* does not return ad units - use "get_external_ad_units" if you're looking for an array of ad units
*/
abstract public function update_external_ad_units();
/**
* Adds the custom wp settings to the tab for this ad unit
*
* @param string $hook hook for the settings page.
* @param string $section_id settings section ID.
*/
abstract protected function register_settings( $hook, $section_id );
/**
* Sanitize the network specific options
*
* @param array $options the options to sanitize.
*
* @return mixed the sanitizzed options
*/
abstract protected function sanitize_settings( $options );
/**
* Sanitize the settings for this ad network
*
* @param Ad $ad Ad instance.
* @param array $post_data Post data array.
*
* @return void
*/
abstract public function sanitize_ad_settings( Ad $ad, $post_data );
/**
* Get external ad units from the given network.
*
* @return array of ad units (Advanced_Ads_Ad_Network_Ad_Unit)
*/
abstract public function get_external_ad_units();
/**
* Checks if the ad_unit is supported by Advanced Ads.
* this determines wheter it can be imported or not.
*
* @param object $ad_unit ad unit.
*
* @return boolean
*/
abstract public function is_supported( $ad_unit );
/**
* There is no common way to connect to an external account. you will have to implement it somehow, just
* like the whole setup process (usually done in the settings tab of this network). this method provides
* a way to return this account connection
*
* @return boolean true, when an account was successfully connected
*/
abstract public function is_account_connected();
/**
* External ad networks rely on the same javascript base code. however you still have to provide
* a javascript class that inherits from the AdvancedAdsAdNetwork js class
* this has to point to that file, or return false,
* if you don't have to include it in another way (NOT RECOMMENDED!)
*
* @return string path to the javascript file containing the javascriot class for this ad type
*/
abstract public function get_javascript_base_path();
/**
* Our script might need translations or other variables (llike a nonce, which is included automatically)
* add anything you need in this method and return the array
*
* @param array $data holding the data.
*
* @return array the data, that will be passed to the base javascript file containing the AdvancedAdsAdNetwork class
*/
abstract public function append_javascript_data( &$data );
}

View File

@@ -0,0 +1,683 @@
<?php // phpcs:ignoreFile
/**
* Handle add-on licenses
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.x.x
*/
use AdvancedAds\Constants;
use AdvancedAds\Utilities\Data;
defined( 'ABSPATH' ) || exit;
/**
* Handle add-on licenses
*/
class Advanced_Ads_Admin_Licenses {
/**
* Advanced_Ads_Admin_Licenses constructor.
*/
private function __construct() {
add_action( 'plugins_loaded', [ $this, 'wp_plugins_loaded' ] );
// todo: check if this is loaded late enough and all add-ons are registered already.
add_filter( 'upgrader_pre_download', [ $this, 'addon_upgrade_filter' ], 10, 3 );
}
/**
* Actions and filter available after all plugins are initialized
*/
public function wp_plugins_loaded() {
add_action( 'http_api_debug', [ $this, 'update_license_after_version_info' ], 10, 5 );
}
/**
* Return an instance of this class.
*
* @return self object A single instance of this class.
*/
public static function get_instance() {
static $instance;
// If the single instance hasn't been set, set it now.
if ( null === $instance ) {
$instance = new self();
}
return $instance;
}
/**
* Save license key
*
* @param string $addon string with add-on identifier.
* @param string $plugin_name name of the add-on.
* @param string $options_slug slug of the option in the database.
* @param string $license_key license key.
*
* @return string
* @since 1.2.0
*/
public function activate_license( $addon = '', $plugin_name = '', $options_slug = '', $license_key = '' ) {
if ( '' === $addon || '' === $plugin_name || '' === $options_slug ) {
return __( 'Error while trying to register the license. Please contact support.', 'advanced-ads' );
}
$license_key = esc_attr( trim( $license_key ) );
if ( '' === $license_key ) {
return __( 'Please enter a valid license key', 'advanced-ads' );
}
if ( has_filter( 'advanced_ads_license_' . $options_slug ) ) {
return apply_filters( 'advanced_ads_license_' . $options_slug, false, __METHOD__, $plugin_name, $options_slug, $license_key );
}
/**
* We need to remove the mltlngg_get_url_translated filter added by Multilanguage by BestWebSoft, https://wordpress.org/plugins/multilanguage/
* it causes the URL to look much different than it originally is
* we are adding it again later
*/
remove_filter( 'home_url', 'mltlngg_get_url_translated' );
$api_params = [
'edd_action' => 'activate_license',
'license' => $license_key,
'item_id' => Constants::ADDON_SLUGS_ID[ $options_slug ] ?? false,
'item_name' => rawurlencode( $plugin_name ),
'url' => home_url(),
];
/**
* Re-add the filter removed from above
*/
if ( function_exists( 'mltlngg_get_url_translated' ) ) {
add_filter( 'home_url', 'mltlngg_get_url_translated' );
}
// Call the custom API.
$response = wp_remote_post(
Constants::API_ENDPOINT,
[
'timeout' => 15,
'sslverify' => false,
'body' => $api_params,
]
);
// show license debug output if constant is set.
if ( defined( 'ADVANCED_ADS_SHOW_LICENSE_RESPONSE' ) ) {
return '<p><strong>' . esc_html__( 'The license status does not change as long as ADVANCED_ADS_SHOW_LICENSE_RESPONSE is enabled in wp-config.php.', 'advanced-ads' ) . '</strong></p>' .
'<pre>' . print_r( $response, true ) . '</pre>'; // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
}
/**
* Send the user to our support when his request is blocked by our firewall
*/
$error = $this->blocked_by_firewall( $response );
if ( $error ) {
return $error;
}
if ( is_wp_error( $response ) ) {
$body = wp_remote_retrieve_body( $response );
if ( $body ) {
return $body;
} else {
$curl = curl_version();
return __( 'License couldnt be activated. Please try again later.', 'advanced-ads' ) . " (cURL {$curl['version']})";
}
}
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
// save license status.
if ( ! empty( $license_data->license ) ) {
$this->clear_license_cache();
update_option( $options_slug . '-license-status', $license_data->license, false );
}
if ( ! empty( $license_data->expires ) ) {
$this->clear_license_cache();
update_option( $options_slug . '-license-expires', $license_data->expires, false );
}
// display activation problem.
if ( ! empty( $license_data->error ) ) {
// user friendly texts for errors.
$errors = [
'license_not_activable' => __( 'This is the bundle license key.', 'advanced-ads' ),
'item_name_mismatch' => __( 'This is not the correct key for this add-on.', 'advanced-ads' ),
'no_activations_left' => __( 'There are no activations left.', 'advanced-ads' )
. '&nbsp;'
. sprintf(
/* translators: %1$s is a starting link tag, %2$s is the closing one. */
__( 'You can manage activations in %1$syour account%2$s.', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/account/?utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-licenses-activations-left" target="_blank">',
'</a>'
) . '&nbsp;'
. sprintf(
/* translators: %1$s is a starting link tag, %2$s is the closing one. */
__( '%1$sUpgrade%2$s for more activations.', 'advanced-ads' ),
'<a href="https://wpadvancedads.com/account/upgrades/?utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-licenses-activations-left" target="_blank">',
'</a>'
),
];
$error = isset( $errors[ $license_data->error ] ) ? $errors[ $license_data->error ] : $license_data->error;
if ( 'expired' === $license_data->error ) {
return 'ex';
} else { // phpcs:ignore
if ( isset( $errors[ $license_data->error ] ) ) {
return $error;
} else {
return sprintf(
/* translators: %s is a string containing information about the issue. */
__( 'License is invalid. Reason: %s', 'advanced-ads' ),
$error
);
}
}
} else {
// reset license_expires admin notification.
Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( 'license_expires' ); // this one is no longer added, but we keep the check here in case it is still in the queue for some users.
Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( 'license_expired' ); // this one is no longer added, but we keep the check here in case it is still in the queue for some users.
Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( 'license_invalid' );
// save license key.
$licenses = $this->get_licenses();
$licenses[ $addon ] = $license_key;
$this->save_licenses( $licenses );
}
return 1;
}
/**
* Check if a request was blocked by our firewall
*
* @param array $response response from license call.
*
* @return mixed message or false
*/
public function blocked_by_firewall( $response ) {
$response_code = wp_remote_retrieve_response_code( $response );
if ( 403 === $response_code ) {
$blocked_information = '';
if ( isset( $response['body'] ) ) {
// look for the IP address in this line: `<td><span>95.90.238.103</span></td>`.
$pattern = '/<span>([.0-9]*)<\/span>/';
$matches = [];
preg_match( $pattern, $response['body'], $matches );
$ip = isset( $matches[1] ) ? $matches[1] : '';
$blocked_information = 'IP: ' . $ip;
}
/* translators: %s is a list of server information like IP address. Just keep it as is. */
return sprintf( __( 'Your request was blocked by our firewall. Please send us the following information to unblock you: %s.', 'advanced-ads' ), $blocked_information );
}
return false;
}
/**
* Check if a specific license key was already activated for the current page
*
* @param string $license_key license key.
* @param string $plugin_name name of the add-on.
* @param string $options_slug slug of the option in the database.
*
* @return bool true if already activated
* @since 1.6.17
* @deprecated since version 1.7.2 because it only checks if a key is valid, not if the url registered with that key
*/
public function check_license( $license_key = '', $plugin_name = '', $options_slug = '' ) {
if ( has_filter( 'advanced_ads_license_' . $options_slug ) ) {
return apply_filters( 'advanced_ads_license_' . $options_slug, false, __METHOD__, $plugin_name, $options_slug, $license_key );
}
$api_params = [
'edd_action' => 'check_license',
'license' => $license_key,
'item_id' => Constants::ADDON_SLUGS_ID[ $options_slug ] ?? false,
'item_name' => rawurlencode( $plugin_name ),
];
$response = wp_remote_get(
add_query_arg( $api_params, 'https://wpadvancedads.com/' ),
[
'timeout' => 15,
'sslverify' => false,
]
);
if ( is_wp_error( $response ) ) {
return false;
}
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
// if this license is still valid.
if ( 'valid' === $license_data->license ) {
update_option( $options_slug . '-license-expires', $license_data->expires, false );
update_option( $options_slug . '-license-status', $license_data->license, false );
return true;
}
return false;
}
/**
* Deactivate license key
*
* @param string $addon string with add-on identifier.
* @param string $plugin_name name of the add-on.
* @param string $options_slug slug of the option in the database.
*
* @return string
* @since 1.6.11
*/
public function deactivate_license( $addon = '', $plugin_name = '', $options_slug = '' ) {
if ( '' === $addon || '' === $plugin_name || '' === $options_slug ) {
return __( 'Error while trying to disable the license. Please contact support.', 'advanced-ads' );
}
$licenses = $this->get_licenses();
$license_key = isset( $licenses[ $addon ] ) ? $licenses[ $addon ] : '';
$short_circuit = $this->shortcuit_deactivation( $addon, $options_slug );
if ( false !== $short_circuit ) {
return true;
}
if ( has_filter( 'advanced_ads_license_' . $options_slug ) ) {
return apply_filters( 'advanced_ads_license_' . $options_slug, false, __METHOD__, $plugin_name, $options_slug, $license_key );
}
$api_params = [
'edd_action' => 'deactivate_license',
'license' => $license_key,
'item_id' => Constants::ADDON_SLUGS_ID[ $options_slug ] ?? false,
'item_name' => rawurlencode( $plugin_name ),
];
// Send the remote request.
$response = wp_remote_post(
Constants::API_ENDPOINT,
[
'body' => $api_params,
'timeout' => 15,
'sslverify' => false,
]
);
// show license debug output if constant is set.
if ( defined( 'ADVANCED_ADS_SHOW_LICENSE_RESPONSE' ) ) {
return '<p><strong>' . esc_html__( 'The license status does not change as long as ADVANCED_ADS_SHOW_LICENSE_RESPONSE is enabled in wp-config.php.', 'advanced-ads' ) . '</strong></p>' .
'<pre>' . print_r( $response, true ) . '</pre>'; // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
}
if ( is_wp_error( $response ) ) {
$body = wp_remote_retrieve_body( $response );
if ( $body ) {
return $body;
} else {
return __( 'License couldnt be deactivated. Please try again later.', 'advanced-ads' );
}
}
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
/**
* Send the user to our support when his request is blocked by our firewall
*/
$error = $this->blocked_by_firewall( $response );
if ( $error ) {
return $error;
}
// remove data.
if ( 'deactivated' === $license_data->license ) {
delete_option( $options_slug . '-license-status' );
delete_option( $options_slug . '-license-expires' );
} elseif ( 'failed' === $license_data->license ) {
update_option( $options_slug . '-license-expires', $license_data->expires, false );
update_option( $options_slug . '-license-status', $license_data->license, false );
return 'ex';
} else {
return __( 'License couldnt be deactivated. Please try again later.', 'advanced-ads' );
}
return 1;
}
/**
* Get license keys for all add-ons
*
* @return string[]
*/
public function get_licenses() {
$licenses = get_option( ADVADS_SLUG . '-licenses', [] );
if ( empty( $licenses ) || ! is_array( $licenses ) ) {
$licenses = [];
}
return $licenses;
}
/**
* Save license keys for all add-ons
*
* @param array $licenses licenses.
*/
public function save_licenses( $licenses = [] ) {
update_option( ADVADS_SLUG . '-licenses', $licenses );
}
/**
* Get license status of an add-on
*
* @param string $slug slug of the add-on.
*
* @return string|false license status, "valid", "invalid" or false if option doesn't exist.
*/
public function get_license_status( $slug = '' ) {
return get_option( $slug . '-license-status', false );
}
/**
* If two or more add-ons use the same valid license this is probably an all-access customer
*
* @return bool
*/
public function get_probably_all_access() {
$valid = array_filter(
$this->get_licenses(),
function ( $key ) {
return $this->get_license_status( ADVADS_SLUG . '-' . $key );
},
ARRAY_FILTER_USE_KEY
);
return [] !== $valid && max( array_count_values( $valid ) ) > 1;
}
/**
* Return the licence expiry time if it is equal for more than one add-on. That indicates it is likely an All Access license
*
* @return string|null
*/
public function get_probably_all_access_expiry() {
/**
* Get expiry dates of all add-ons.
*
* @param string $key Add-on key.
*
* @return string|false the expiration date or false.
*/
$expiry_counts = array_count_values(
array_map(
function ( $key ) {
return $this->get_license_expires( ADVADS_SLUG . '-' . $key );
},
array_keys( array_filter( $this->get_licenses() ) )
)
);
/**
* Remove all licenses that are used only once.
*
* @param int $count the count from array_count_values_above
*
* @return bool whether the count is greater 1
*/
$all_access = array_filter(
$expiry_counts,
function ( $count ) {
return $count > 1;
}
);
// if there is an item in $all_access we can assume this is from All Access and return the expiry date.
return empty( $all_access ) ? null : key( $all_access );
}
/**
* Get license expired value of an add-on
*
* @param string $slug slug of the add-on.
*
* @return string $date expiry date of an add-on, empty string if no option exists
*/
public function get_license_expires( $slug = '' ) {
return get_option( $slug . '-license-expires', '' );
}
/**
* Add custom messages to plugin updater
*
* @param bool $reply Whether to bail without returning the package. Default false.
* @param string $package The package file name.
* @param WP_Upgrader $updater The WP_Upgrader instance.
*
* @return string
*
* @todo check if this is still working.
*/
public function addon_upgrade_filter( $reply, $package, $updater ) {
$key = null;
$value = null;
if ( isset( $updater->skin->plugin ) ) {
$key = 'path';
$value = $updater->skin->plugin;
} elseif ( isset( $updater->skin->plugin_info['Name'] ) ) {
$key = 'name';
$value = $updater->skin->plugin_info['Name'];
}
$add_on = $this->get_installed_add_on_by_key( $key, $value );
if ( ! $add_on || ! isset( $add_on['path'] ) ) {
return $reply;
}
$plugin_file = plugin_basename( $add_on['path'] );
if ( wp_doing_ajax() ) {
$update_link = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $plugin_file, 'upgrade-plugin_' . $plugin_file );
/* translators: %s plugin update link */
$updater->strings['download_failed'] = sprintf( __( 'Download failed. <a href="%s">Click here to try another method</a>.', 'advanced-ads' ), $update_link );
} else {
/* translators: %s download failed knowledgebase link */
$updater->strings['download_failed'] = sprintf( __( 'Download failed. <a href="%s" target="_blank">Click here to learn why</a>.', 'advanced-ads' ), 'https://wpadvancedads.com/manual/download-failed-updating-add-ons/#utm_source=advanced-ads&utm_medium=link&utm_campaign=download-failed' );
}
return $reply;
}
/**
* Search if a name is in the add-on array and return the add-on data of it
*
* @param string $key key to search for.
* @param string $value value to search for.
*
* @return array array with the add-on data
*/
private function get_installed_add_on_by_key( $key, $value ) {
// Early bail!!
if ( empty( $key ) || empty( $value ) ) {
return null;
}
$add_ons = Data::get_addons();
if ( is_array( $add_ons ) ) {
foreach ( $add_ons as $add_on ) {
if ( $add_on[ $key ] === $value ) {
return $add_on;
}
}
}
return null;
}
/**
* Check if any license is valid
* can be used to display information for any Pro user only, like link to direct support
*/
public static function any_license_valid() {
$add_ons = Data::get_addons();
if ( [] === $add_ons ) {
return false;
}
foreach ( $add_ons as $_add_on ) {
$status = self::get_instance()->get_license_status( $_add_on['options_slug'] );
// check expiry date.
$expiry_date = self::get_instance()->get_license_expires( $_add_on['options_slug'] );
if (
( $expiry_date && strtotime( $expiry_date ) > time() )
|| 'valid' === $status || 'lifetime' === $expiry_date
) {
return true;
}
}
return false;
}
/**
* Update the license status based on information retrieved from the version info check
*
* @param array|WP_Error $response HTTP response or WP_Error object.
* @param string $context Context under which the hook is fired.
* @param string $http HTTP transport used.
* @param array $parsed_args HTTP request arguments.
* @param string $url The request URL.
* @return array|WP_Error
*/
public function update_license_after_version_info( $response, $context, $http, $parsed_args, $url ) {
// Early bail!!
if (
Constants::API_ENDPOINT !== $url
|| (
empty( $parsed_args['body']['edd_action'] )
|| 'get_version' !== $parsed_args['body']['edd_action']
)
|| is_wp_error( $response )
) {
return $response;
}
$params = json_decode( wp_remote_retrieve_body( $response ) );
if ( empty( $params->name ) ) {
return $response;
}
$new_license_status = null;
$new_expiry_date = null;
// Some of the conditions could happen at the same time,
// though due to different conditions in EDD we are safer to have multiple checks.
if ( isset( $params->valid_until ) ) {
if ( 'invalid' === $params->valid_until ) {
$new_license_status = 'invalid';
}
if ( 'lifetime' === $params->valid_until ) {
$new_license_status = 'valid';
$new_expiry_date = 'lifetime';
}
if ( is_int( $params->valid_until ) ) {
$new_expiry_date = (int) $params->valid_until;
if ( time() < $params->valid_until ) {
$new_license_status = 'valid';
}
}
} elseif ( empty( $params->download_link ) || empty( $params->package ) || isset( $params->msg ) ) {
// If either of these two parameters is missing then the user does not have a valid license according to our store
// If there is a "msg" parameter then the license did also not work for another reason.
$new_license_status = 'invalid';
}
if ( ! $new_license_status && ! $new_expiry_date ) {
return $response;
}
$add_ons = Data::get_addons();
// Look for the add-on with the appropriate license key.
foreach ( $add_ons as $_add_on ) {
if ( ! isset( $_add_on['name'] ) || $params->name !== $_add_on['name'] ) {
continue;
}
$options_slug = $_add_on['options_slug'];
if ( $new_license_status ) {
update_option( $options_slug . '-license-status', $new_license_status, false );
}
if ( $new_expiry_date ) {
if ( 'lifetime' !== $new_expiry_date ) {
$new_expiry_date = gmdate( 'Y-m-d 23:59:49', $new_expiry_date );
}
update_option( $options_slug . '-license-expires', $new_expiry_date, false );
}
// Return with the first match since there should only be one plugin per name.
return $response;
}
return $response;
}
/**
* Shortcuit deactivation
*
* @param string $addon string with add-on identifier.
* @param string $options_slug slug of the option in the database.
*
* @return false
*/
private function shortcuit_deactivation( $addon, $options_slug ) {
$licenses = $this->get_filtered_licenses();
$license_key = isset( $licenses[ $addon ] ) ? $licenses[ $addon ] : '';
$counts = array_count_values( $licenses );
if ( $counts[ $license_key ] > 1 ) {
delete_option( $options_slug . '-license-status' );
delete_option( $options_slug . '-license-expires' );
return __( 'License deactivated. Please try again later.', 'advanced-ads' );
}
return false;
}
/**
* If two or more add-ons use the same valid license this is probably an all-access customer
*
* @return array
*/
private function get_filtered_licenses() {
$filtered = array_filter(
$this->get_licenses(),
function ( $key ) {
return $this->get_license_status( ADVADS_SLUG . '-' . $key );
},
ARRAY_FILTER_USE_KEY
);
return ! is_array( $filtered ) ? [] : $filtered;
}
/**
* Clear the license cache
*
* @param string $slug slug of the add-on.
* @param string $license_key license key.
*/
private function clear_license_cache() {
global $wpdb;
$wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'advads_edd_sl_%'" );
}
}

View File

@@ -0,0 +1,557 @@
<?php // phpcs:ignore WordPress.Files.FileName
/**
* Container class for admin notices
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.x.x
*/
use AdvancedAds\Abstracts\Ad;
use AdvancedAds\Utilities\WordPress;
use AdvancedAds\Utilities\Conditional;
use AdvancedAds\Framework\Utilities\Arr;
/**
* Container class for admin notices
*
* @package WordPress
* @subpackage Advanced Ads Plugin
*/
class Advanced_Ads_Admin_Notices {
/**
* Maximum number of notices to show at once
*/
const MAX_NOTICES = 2;
/**
* Options
*
* @var array
*/
protected $options;
/**
* Notices to be displayed
*
* @var array
*/
public $notices = [];
/**
* Advanced_Ads_Admin_Notices constructor to load notices
*/
public function __construct() {
$this->load_notices();
}
/**
* Return an instance of this class.
*
* @return object A single instance of this class.
*/
public static function get_instance() {
static $instance;
// if the single instance hasn't been set, set it now.
if ( null === $instance ) {
$instance = new self();
}
return $instance;
}
/**
* Determines if a notice can be displayed.
*
* @param string $notice The notice identifier.
*
* @return bool Returns true if the notice can be displayed, false otherwise.
*/
public function can_display( $notice ) {
$options = $this->options();
$closed = $options['closed'] ?? [];
return ! array_key_exists( $notice, $closed );
}
/**
* Load admin notices
*/
public function load_notices() {
$options = $this->options();
$plugin_options = Advanced_Ads::get_instance()->options();
// load notices from queue.
$this->notices = isset( $options['queue'] ) ? $options['queue'] : [];
$notices_before = $this->notices;
// check license notices.
$this->register_license_notices();
// check wizard notice.
$this->register_wizard_notice();
// check non org plugins update.
$this->check_non_org_plugins();
// dont check non-critical notices if they are disabled.
if ( ! isset( $plugin_options['disable-notices'] ) ) {
// check other notices.
$this->check_notices();
}
// register notices in db so they get displayed until closed for good.
if ( $this->notices !== $notices_before ) {
$this->add_to_queue( $this->notices );
}
}
/**
* Check various notices conditions
*/
public function check_notices() {
$internal_options = Advanced_Ads::get_instance()->internal_options();
$now = time();
$activation = ( isset( $internal_options['installed'] ) ) ? $internal_options['installed'] : $now; // activation time.
$options = $this->options();
$closed = isset( $options['closed'] ) ? $options['closed'] : [];
$queue = isset( $options['queue'] ) ? $options['queue'] : [];
$paused = isset( $options['paused'] ) ? $options['paused'] : [];
// offer free add-ons if not yet subscribed.
if ( Conditional::user_can_subscribe( 'nl_free_addons' ) && ! in_array( 'nl_free_addons', $queue, true ) && ! isset( $closed['nl_free_addons'] ) ) {
// get number of ads.
if ( WordPress::get_count_ads() ) {
$this->notices[] = 'nl_free_addons';
}
}
$number_of_ads = 0;
// needed error handling due to a weird bug in the piklist plugin.
try {
$number_of_ads = WordPress::get_count_ads();
} catch ( Exception $e ) { // phpcs:ignore
// no need to catch anything since we just use TRY/CATCH to prevent an issue caused by another plugin.
}
// ask for a review after 2 days and when 3 ads were created and when not paused.
if (
! in_array( 'review', $queue, true )
&& ! isset( $closed['review'] )
&& ( ! isset( $paused['review'] ) || $paused['review'] <= time() )
&& 172800 < ( time() - $activation )
&& 3 <= $number_of_ads
) {
$this->notices[] = 'review';
} elseif ( in_array( 'review', $queue, true ) && 3 > $number_of_ads ) {
$review_key = array_search( 'review', $this->notices, true );
if ( false !== $review_key ) {
unset( $this->notices[ $review_key ] );
}
}
}
/**
* Register license key notices
*/
public function register_license_notices() {
if ( ! Conditional::is_screen_advanced_ads() ) {
return;
}
$options = $this->options();
$queue = isset( $options['queue'] ) ? $options['queue'] : [];
// check license keys.
if ( Advanced_Ads_Checks::licenses_invalid() ) {
if ( ! in_array( 'license_invalid', $queue, true ) ) {
$this->notices[] = 'license_invalid';
}
} else {
$this->remove_from_queue( 'license_invalid' );
}
}
/**
* Register wizard notice.
*/
public function register_wizard_notice() {
if ( ! Conditional::is_screen_advanced_ads() ) {
return;
}
$options = $this->options();
$queue = isset( $options['queue'] ) ? $options['queue'] : [];
if ( Advanced_Ads_Checks::can_launch_wizard() ) {
if ( ! in_array( 'monetize_wizard', $queue, true ) ) {
$this->notices[] = 'monetize_wizard';
}
} else {
$this->remove_from_queue( 'monetize_wizard' );
}
}
/**
* Check for updates of non wp.org plugins
*/
public function check_non_org_plugins() {
if ( ! Conditional::is_screen_advanced_ads() ) {
return;
}
$addons = \AdvancedAds\Constants::ADDONS_NON_COMPATIBLE_VERSIONS;
$plugins = WordPress::get_wp_plugins();
$options = $this->options();
$queue = isset( $options['queue'] ) ? $options['queue'] : [];
$closed = isset( $options['closed'] ) ? $options['closed'] : [];
foreach ( $addons as $version => $slug ) {
$addon = $plugins[ $slug ] ?? null;
if ( ! $addon ) {
continue;
}
$notice = $slug . '_upgrade';
if ( version_compare( $addon['version'], $version, '<=' ) ) {
if ( ! in_array( $notice, $queue, true ) && ! array_key_exists( $notice, $closed ) ) {
$this->notices[] = $notice;
}
} else {
$this->remove_from_queue( $notice );
}
}
}
/**
* Add update notices to the queue of all notices that still needs to be closed
*
* @param mixed $notices one or more notices to be added to the queue.
*
* @since 1.5.3
*/
public function add_to_queue( $notices = 0 ) {
if ( ! $notices ) {
return;
}
// get queue from options.
$options = $this->options();
$queue = isset( $options['queue'] ) ? $options['queue'] : [];
if ( is_array( $notices ) ) {
$queue = array_merge( $queue, $notices );
} else {
$queue[] = $notices;
}
// remove possible duplicated.
$queue = array_unique( $queue );
// update db.
$options['queue'] = $queue;
$this->update_options( $options );
}
/**
* Remove update notice from queue
* move notice into "closed"
*
* @param string $notice notice to be removed from the queue.
*
* @since 1.5.3
*/
public function remove_from_queue( $notice ) {
if ( ! isset( $notice ) ) {
return;
}
// get queue from options.
$options = $this->options();
$options_before = $options;
if ( ! isset( $options['queue'] ) ) {
return;
}
$queue = (array) $options['queue'];
$closed = isset( $options['closed'] ) ? $options['closed'] : [];
$paused = isset( $options['paused'] ) ? $options['paused'] : [];
$key = array_search( $notice, $queue, true );
if ( false !== $key ) {
unset( $queue[ $key ] );
// close message with timestamp.
}
// dont close again twice.
if ( ! isset( $closed[ $notice ] ) ) {
$closed[ $notice ] = time();
}
// remove from pause.
if ( isset( $paused[ $notice ] ) ) {
unset( $paused[ $notice ] );
}
// update db.
$options['queue'] = $queue;
$options['closed'] = $closed;
$options['paused'] = $paused;
// only update if changed.
if ( $options_before !== $options ) {
$this->update_options( $options );
// update already registered notices.
$this->load_notices();
}
}
/**
* Hide any notice for a given time
* move notice into "paused" with notice as key and timestamp as value
*
* @param string $notice notice to be paused.
*/
public function hide_notice( $notice ) {
if ( ! isset( $notice ) ) {
return;
}
// get queue from options.
$options = $this->options();
$options_before = $options;
if ( ! isset( $options['queue'] ) ) {
return;
}
$queue = (array) $options['queue'];
$paused = isset( $options['paused'] ) ? $options['paused'] : [];
$key = array_search( $notice, $queue, true );
if ( false !== $key ) {
unset( $queue[ $key ] );
}
// close message with timestamp in 7 days
// dont close again twice.
if ( ! isset( $paused[ $notice ] ) ) {
$paused[ $notice ] = time() + WEEK_IN_SECONDS;
}
// update db.
$options['queue'] = $queue;
$options['paused'] = $paused;
// only update if changed.
if ( $options_before !== $options ) {
$this->update_options( $options );
// update already registered notices.
$this->load_notices();
}
}
/**
* Display notices
*/
public function display_notices() {
if ( wp_doing_ajax() ) {
return;
}
// register Black Friday 2023 deals.
if ( time() > 1700654400 &&
time() <= 1701172800 && Conditional::is_screen_advanced_ads() ) {
$options = $this->options();
$closed = isset( $options['closed'] ) ? $options['closed'] : [];
if ( ! isset( $closed['bfcm23'] ) ) {
$this->notices[] = 'bfcm23';
}
}
if ( [] === $this->notices ) {
return;
}
include_once ADVADS_ABSPATH . '/admin/includes/notices.php';
// Iterate through notices.
$count = 0;
foreach ( $this->notices as $_notice ) {
if ( isset( $advanced_ads_admin_notices[ $_notice ] ) ) {
$notice = $advanced_ads_admin_notices[ $_notice ];
$text = $advanced_ads_admin_notices[ $_notice ]['text'];
$type = isset( $advanced_ads_admin_notices[ $_notice ]['type'] ) ? $advanced_ads_admin_notices[ $_notice ]['type'] : '';
} else {
continue;
}
// dont display non-global notices on other than plugin related pages.
if (
( ! isset( $advanced_ads_admin_notices[ $_notice ]['global'] ) || ! $advanced_ads_admin_notices[ $_notice ]['global'] )
&& ! Conditional::is_screen_advanced_ads()
) {
continue;
}
// don't display license nag if ADVANCED_ADS_SUPPRESS_PLUGIN_ERROR_NOTICES is defined.
if ( defined( 'ADVANCED_ADS_SUPPRESS_PLUGIN_ERROR_NOTICES' ) && 'plugin_error' === $advanced_ads_admin_notices[ $_notice ]['type'] ) {
continue;
}
$hash = [
'info' => '/admin/views/notices/info.php',
'subscribe' => '/admin/views/notices/subscribe.php',
'plugin_error' => '/admin/views/notices/plugin_error.php',
'promo' => '/admin/views/notices/promo.php',
];
$locate_tempalte = isset( $hash[ $type ] ) ? $hash[ $type ] : '/admin/views/notices/error.php';
include ADVADS_ABSPATH . $locate_tempalte;
// phpcs:disable
// if ( self::MAX_NOTICES === ++$count ) {
// break;
// }
// phpcs:enable
}
}
/**
* Return notices options
*
* @return array $options
*/
public function options() {
if ( ! isset( $this->options ) ) {
$this->options = get_option( ADVADS_SLUG . '-notices', [] );
}
return $this->options;
}
/**
* Update notices options
*
* @param array $options new options.
*/
public function update_options( array $options ) {
// do not allow to clear options.
if ( [] === $options ) {
return;
}
$this->options = $options;
update_option( ADVADS_SLUG . '-notices', $options );
}
/**
* Subscribe to newsletter and autoresponder
*
* @param string $notice slug of the subscription notice to send the correct reply.
*
* @return string
*/
public function subscribe( $notice ) {
if ( ! isset( $notice ) ) {
return '';
}
$user = wp_get_current_user();
if ( '' === $user->user_email ) {
/* translators: %s: is a URL. */
return sprintf( __( 'You dont seem to have an email address. Please use <a href="%s" target="_blank">this form</a> to sign up.', 'advanced-ads' ), 'http://eepurl.com/bk4z4P' );
}
$data = [
'email' => $user->user_email,
'notice' => $notice,
];
$result = wp_remote_post(
'https://wpadvancedads.com/remote/subscribe.php?source=plugin',
[
'method' => 'POST',
'timeout' => 20,
'redirection' => 5,
'httpversion' => '1.1',
'blocking' => true,
'body' => $data,
]
);
if ( is_wp_error( $result ) ) {
return __( 'How embarrassing. The email server seems to be down. Please try again later.', 'advanced-ads' );
}
// Mark as subscribed and move notice from queue.
$this->mark_as_subscribed( $notice );
$this->remove_from_queue( $notice );
/* translators: the first %s is an email address, the seconds %s is a URL. */
return sprintf( __( 'Please check your email (%1$s) for the confirmation message. If you didnt receive one or want to use another email address then please use <a href="%2$s" target="_blank">this form</a> to sign up.', 'advanced-ads' ), $user->user_email, 'http://eepurl.com/bk4z4P' );
}
/**
* Update information that the current user is subscribed
*
* @param string $notice notice slug.
*/
private function mark_as_subscribed( $notice ) {
// Early bail!!
if ( empty( $notice ) || ! Conditional::user_can_subscribe( $notice ) ) {
return;
}
$user_id = get_current_user_id();
$subscribed_notices = get_user_meta( $user_id, 'advanced-ads-subscribed', true );
// backward compatibility.
if ( ! is_array( $subscribed_notices ) ) {
$subscribed_notices = [];
}
$subscribed_notices[ $notice ] = true;
update_user_meta( $user_id, 'advanced-ads-subscribed', $subscribed_notices );
}
/**
* Check if a usesr can be subscribed to our newsletter
* check if is already subscribed or email is invalid
*
* @deprecated version 2.0 use Conditional::user_can_subscribe() instead
*
* @return bool true if user can subscribe
*/
public function user_can_subscribe() {
_deprecated_function( __METHOD__, '2.0', '\AdvancedAds\Utilities\Conditional::user_can_subscribe()' );
return Conditional::user_can_subscribe( 'nl_first_steps' );
}
/**
* Add AdSense tutorial notice
*
* @param Ad $ad ad object.
*/
public function adsense_tutorial( $ad ) {
$options = $this->options();
$_notice = 'nl_adsense';
if ( 'adsense' !== $ad->get_type() || isset( $options['closed'][ $_notice ] ) ) {
return;
}
include ADVADS_ABSPATH . '/admin/includes/notices.php';
if ( ! isset( $advanced_ads_admin_notices[ $_notice ] ) ) {
return;
}
$notice = $advanced_ads_admin_notices[ $_notice ];
$text = $notice['text'];
include ADVADS_ABSPATH . '/admin/views/notices/inline.php';
}
}

View File

@@ -0,0 +1,271 @@
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
use AdvancedAds\Admin\Translation_Promo;
/**
* Container class for callbacks for overview widgets
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.x.x
*/
class Advanced_Ads_Overview_Widgets_Callbacks {
/**
* In case one wants to inject several dashboards into a page, we will prevent executing redundant javascript
* with the help of this little bool
*
* @var mixed
*/
private static $processed_adsense_stats_js = false;
/**
* When doing ajax request (refreshing the dashboard), we need to have a nonce.
* one is enough, that's why we need to remember it.
*
* @var mixed
*/
private static $gadsense_dashboard_nonce = false;
/**
* Register the plugin overview widgets
*/
public static function setup_overview_widgets() {
// initiate i18n notice.
( new Translation_Promo(
[
'textdomain' => 'advanced-ads',
'plugin_name' => 'Advanced Ads',
'hook' => 'advanced-ads-overview-below-support',
'glotpress_logo' => false, // disables the plugin icon so we dont need to keep up with potential changes.
]
) );
// show errors.
if ( Advanced_Ads_Ad_Health_Notices::notices_enabled() ) {
self::add_meta_box( 'advads_overview_notices', __( 'Notifications', 'advanced-ads' ), 'right', 'render_notices' );
}
self::add_meta_box(
'advads_overview_news',
__( 'Next Steps', 'advanced-ads' ),
'left',
'render_next_steps'
);
self::add_meta_box(
'advads_overview_support',
__( 'Manual & Support', 'advanced-ads' ),
'right',
'render_support'
);
if (
Advanced_Ads_AdSense_Data::get_instance()->is_setup() &&
! Advanced_Ads_AdSense_Data::get_instance()->is_hide_stats()
) {
$disable_link_markup = '<span class="advads-hndlelinks hndle"><a href="' . esc_url( admin_url( 'admin.php?page=advanced-ads-settings#top#adsense' ) ) . '" target="_blank">' . esc_attr__( 'Disable', 'advanced-ads' ) . '</a></span>';
self::add_meta_box(
'advads_overview_adsense_stats',
__( 'AdSense Earnings', 'advanced-ads' ) . $disable_link_markup,
'full',
'render_adsense_stats'
);
}
// add widgets for pro add ons.
self::add_meta_box( 'advads_overview_addons', __( 'Add-Ons', 'advanced-ads' ), 'full', 'render_addons' );
do_action( 'advanced-ads-overview-widgets-after' );
}
/**
* Loads a meta box into output
*
* @param string $id meta box ID.
* @param string $title title of the meta box.
* @param string $position context in which to show the box.
* @param callable $callback function that fills the box with the desired content.
*/
public static function add_meta_box( $id, $title, $position, $callback ) {
ob_start();
call_user_func( [ 'Advanced_Ads_Overview_Widgets_Callbacks', $callback ] );
do_action( 'advanced-ads-overview-widget-content-' . $id, $id );
$content = ob_get_clean();
include ADVADS_ABSPATH . 'admin/views/overview-widget.php';
}
/**
* Render Ad Health notices widget
*/
public static function render_notices() {
Advanced_Ads_Ad_Health_Notices::get_instance()->render_widget();
?>
<script>jQuery( document ).ready( function(){ advads_ad_health_maybe_remove_list(); });</script>
<?php
}
/**
* Render next steps widget
*/
public static function render_next_steps() {
include ADVADS_ABSPATH . 'views/admin/widgets/aa-dashboard/next-steps/widget.php';
}
/**
* Support widget
*/
public static function render_support() {
include ADVADS_ABSPATH . 'views/admin/widgets/aa-dashboard/support.php';
do_action( 'advanced-ads-overview-below-support' );
}
/**
* Adsense stats widget
*/
public static function render_adsense_stats() {
$report_type = 'domain';
$report_filter = get_option( 'advanced-ads-adsense-dashboard-filter', '' );
if ( ! $report_filter ) {
$report_filter = self::get_site_domain();
}
if ( '*' === $report_filter ) {
$report_filter = '';
}
include ADVADS_ABSPATH . 'views/admin/metaboxes/ads/ad-gadsense-dashboard.php';
}
/**
* JavaScript loaded in AdSense stats widget.
*
* @param string $pub_id AdSense publisher ID.
*
* @return string
* @todo move to JS file.
*/
final public static function adsense_stats_js( $pub_id ) {
if ( self::$processed_adsense_stats_js ) {
return;
}
self::$processed_adsense_stats_js = true;
$nonce = self::get_adsense_dashboard_nonce();
?>
<script>
window.gadsenseData = window.gadsenseData || {};
window.Advanced_Ads_Adsense_Report_Helper = window.Advanced_Ads_Adsense_Report_Helper || {};
window.Advanced_Ads_Adsense_Report_Helper.nonce = '<?php echo esc_html( $nonce ); ?>';
gadsenseData['pubId'] = '<?php echo esc_html( $pub_id ); ?>';
</script>
<?php
}
/**
* Return a nonce used in the AdSense stats widget.
*
* @return false|mixed|string
*/
final public static function get_adsense_dashboard_nonce() {
if ( ! self::$gadsense_dashboard_nonce ) {
self::$gadsense_dashboard_nonce = wp_create_nonce( 'advads-gadsense-dashboard' );
}
return self::$gadsense_dashboard_nonce;
}
/**
* Extracts the domain from the site url
*
* @return string the domain, that was extracted from get_site_url()
*/
public static function get_site_domain() {
$site = get_site_url();
preg_match( '|^([\d\w]+://)?([^/]+)|', $site, $matches );
return count( $matches ) > 1 ? $matches[2] : null;
}
/**
* This method is called when the dashboard data is requested via ajax
* it prints the relevant data as json, then dies.
*/
public static function ajax_gadsense_dashboard() {
$post_data = wp_unslash( $_POST );
if ( wp_verify_nonce( $post_data['nonce'], 'advads-gadsense-dashboard' ) === false ) {
wp_send_json_error( 'Unauthorized request', 401 );
}
$report_type = in_array( $post_data['type'], [ 'domain', 'unit' ], true ) ? $post_data['type'] : false;
if ( ! $report_type ) {
wp_send_json_error( 'Invalid arguments', 400 );
}
$report_filter = wp_strip_all_tags( $post_data['filter'] );
$report = new Advanced_Ads_AdSense_Report( $report_type, $report_filter );
if ( $report->get_data()->is_valid() ) {
wp_send_json_success( [ 'html' => $report->get_markup() ] );
}
if ( $report->refresh_report() ) {
wp_send_json_success( [ 'html' => $report->get_markup() ] );
}
$error_message = $report->get_last_api_error();
// Send markup with error info.
wp_send_json_success( [ 'html' => '<div class="error"><p>' . wp_kses_post( $error_message ) . '</p></div>' ] );
}
/**
* Render stats box
*
* @param string $title title of the box.
* @param string $main main content.
* @param string $footer footer content.
*
* @deprecated ?
*/
final public static function render_stats_box( $title, $main, $footer ) {
?>
<div class="advanced-ads-stats-box flex1">
<?php echo $title; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div class="advanced-ads-stats-box-main">
<?php
// phpcs:ignore
echo $main;
?>
</div>
<?php echo $footer; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<?php
}
/**
* Add-ons box
*
* @param bool $hide_activated if true, hide activated add-ons.
* @param bool $is_dashboard whether it is used in the AA dashboard.
*
* @return void
*/
public static function render_addons( $hide_activated = false, $is_dashboard = true ) {
$box = new \AdvancedAds\Admin\Addon_Box( $hide_activated );
$box->display( $is_dashboard );
}
/**
* Sort by installed add-ons
*
* @param array $a argument a.
* @param array $b argument b.
*
* @return int
*/
protected static function sort_by_order( $a, $b ) {
return $a['order'] - $b['order'];
}
}

View File

@@ -0,0 +1,156 @@
<?php
/**
* Array with admin notices
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
*/
use AdvancedAds\Utilities\WordPress;
if ( ! defined( 'NOTICE_TYPES' ) ) {
define(
'NOTICE_TYPES',
[
'info' => 'info',
'subscribe' => 'subscribe',
'error' => 'plugin_error',
'promo' => 'promo',
]
);
}
// These add-on names correspond to the names in the class of constants from ADDONS_NON_COMPATIBLE_VERSIONS.
$manual_addons = [
'advanced-ads-page-peel' => [
'title' => 'Advanced Ads Page Peel',
'zip' => esc_url( 'https://wpadvancedads.com/wp-content/uploads/advanced-ads-page-peel.zip' ),
'link' => esc_url( 'https://wpadvancedads.com/manual/how-to-install-an-add-on/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-update-pagepeel-a220' ),
],
'advanced-ads-browser-language' => [
'title' => 'Advanced Ads Browser Language Visitor Condition',
'zip' => esc_url( 'https://wpadvancedads.com/wp-content/uploads/advanced-ads-browser-language.zip' ),
'link' => esc_url( 'https://wpadvancedads.com/manual/how-to-install-an-add-on/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-update-browserlang-a220' ),
],
'slider-ads' => [
'title' => 'Advanced Ads Ad Slider',
'zip' => esc_url( 'https://wpadvancedads.com/wp-content/uploads/advanced-ads-slider.zip' ),
'link' => esc_url( 'https://wpadvancedads.com/manual/how-to-install-an-add-on/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-update-adslider-a220' ),
],
];
$advanced_ads_admin_notices = [
// email tutorial.
'nl_first_steps' => [
'type' => NOTICE_TYPES['subscribe'],
'text' => __( 'Thank you for activating <strong>Advanced Ads</strong>. Would you like to receive the first steps via email?', 'advanced-ads' ),
'confirm_text' => __( 'Yes, send it', 'advanced-ads' ),
'global' => true,
],
// free add-ons.
'nl_free_addons' => [
'type' => NOTICE_TYPES['subscribe'],
'text' => __( 'Hey, welcome to Advanced Ads! Join our newsletter and snag <strong>2 free add-ons</strong> plus our email intro course. Its the perfect way to get started smoothly!', 'advanced-ads' ),
'confirm_text' => __( 'Subscribe me now', 'advanced-ads' ),
'global' => false,
],
// adsense newsletter group.
'nl_adsense' => [
'type' => NOTICE_TYPES['subscribe'],
'text' => __( 'Learn more about how and <strong>how much you can earn with AdSense</strong> and Advanced Ads from my dedicated newsletter.', 'advanced-ads' ),
'global' => true,
],
// missing license codes.
'license_invalid' => [
'type' => NOTICE_TYPES['error'],
'text' => __( 'One or more license keys for <strong>Advanced Ads add-ons are invalid or missing</strong>.', 'advanced-ads' ) . ' '
/* translators: %s is a target URL. */
. sprintf( __( 'Please add valid license keys <a href="%s">here</a>.', 'advanced-ads' ), get_admin_url( null, 'admin.php?page=advanced-ads-settings#top#licenses' ) ),
],
// please review.
'review' => [
'type' => NOTICE_TYPES['info'],
// 'text' => '<img src="' . ADVADS_BASE_URL . 'admin/assets/img/thomas.png" alt="Thomas" width="80" height="115" class="advads-review-image"/>'
'text' => '<div style="float: left; font-size: 4em; line-height: 1em; margin-right: 0.5em;">' . WordPress::get_count_ads() . '</div>'
. '<div style="float:left;">'
. '<p>' . __( '… ads created using <strong>Advanced Ads</strong>.', 'advanced-ads' ) . '</p>'
. '<p>' . __( 'Do you find the plugin useful and would like to thank us for updates, fixing bugs and improving your ad setup?', 'advanced-ads' ) . '</p>'
. '<p>' .
/* translators: this belongs to our message asking the user for a review. You can find a nice equivalent in your own language. */
__( 'When you give 5-stars, an actual person does a little happy dance!', 'advanced-ads' ) . '</p>'
. '<p>'
. '<span class="dashicons dashicons-external"></span>&nbsp;<strong><a href="https://wordpress.org/support/plugin/advanced-ads/reviews/?rate=5#new-post" target=_"blank">' . __( 'Sure, I appreciate your work', 'advanced-ads' ) . '</a></strong>'
. ' &nbsp;&nbsp;<span class="dashicons dashicons-sos"></span>&nbsp;<a href="https://wpadvancedads.com/support/?utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-review" target=_"blank">' . __( 'Yes, but help me first to solve a problem, please', 'advanced-ads' ) . '</a>'
. '</p></div>',
'global' => false,
],
// Black Friday 2023 promotion.
'bfcm23' => [
'type' => NOTICE_TYPES['promo'],
'text' => sprintf(
/* translators: %1$s is the markup for the discount value, %2$s starts a button link, %3$s closes the button link. */
__( 'Save %1$s on all products with our Black Friday / Cyber Monday offer! %2$sGet this deal%3$s', 'advanced-ads' ),
'<span style="font-weight: bold; font-size: 1.6em; vertical-align: sub;">30%</span>',
'<a class="button button-primary" target="_blank" href="https://wpadvancedads.com/pricing/?utm_source=advanced-ads&utm_medium=link&utm_campaign=bfcm-2023">',
'</a>'
),
'global' => true,
],
'monetize_wizard' => [
'type' => NOTICE_TYPES['info'],
'text' => sprintf(
wp_kses_post(
/* translators: %s: URL to the Advanced Ads onboarding wizard. */
__( 'Quickly set up Advanced Ads and monetize your website with just a few clicks. <a class="button button-primary" href="%s">Launch the wizard</a>', 'advanced-ads' )
),
admin_url( 'admin.php?page=advanced-ads-onboarding' )
),
],
];
// Add specific notifications for plugins that are incompatible with Advanced Ads 2.0.
foreach ( \AdvancedAds\Constants::ADDONS_NON_COMPATIBLE_VERSIONS as $version => $addon ) {
if ( isset( $manual_addons[ $addon ] ) ) {
$advanced_ads_admin_notices[ $addon . '_upgrade' ] = [
'type' => NOTICE_TYPES['info'],
'text' => sprintf(
wp_kses(
/* translators: %1$s: URL to the plugin file, %2$s: URL to the guide */
__( 'Your automatically deactivated version of <strong>%1$s needs to be updated manually</strong>. Please <a href="%2$s" target="_blank">download the newest plugin file</a> and follow our guide on <a href="%3$s" target="_blank">How to install an add-on</a>.', 'advanced-ads' ),
[
'strong' => [],
'a' => [
'href' => [],
'target' => [],
],
]
),
$manual_addons[ $addon ]['title'],
$manual_addons[ $addon ]['zip'],
$manual_addons[ $addon ]['link'],
),
'global' => true,
];
} else {
$advanced_ads_admin_notices[ $addon . '_upgrade' ] = [
'type' => NOTICE_TYPES['info'],
'text' => sprintf(
wp_kses(
/* translators: %1$s: URL to the plugin file, %2$s: URL to the guide */
__( 'Your version of <strong>%1$s</strong> is incompatible with <strong>Advanced Ads %2$s</strong> and has been deactivated. Please update the plugin to the latest version.', 'advanced-ads' ),
[
'strong' => [],
]
),
ucwords( str_replace( '-', ' ', $addon ) ),
ADVADS_VERSION,
),
'global' => true,
];
}
}
$advanced_ads_admin_notices = apply_filters(
'advanced-ads-notices',
$advanced_ads_admin_notices
);