Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WordAds]: Ad formats migration to WATL #40308

Open
wants to merge 20 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion projects/plugins/jetpack/.phan/baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,6 @@
'modules/shortcodes/ustream.php' => ['PhanTypeMismatchArgument'],
'modules/shortcodes/vimeo.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanTypeMismatchArgument'],
'modules/shortcodes/vr.php' => ['PhanPluginDuplicateConditionalNullCoalescing'],
'modules/shortcodes/wordads.php' => ['PhanNoopNew'],
'modules/shortcodes/youtube.php' => ['PhanRedefineFunction'],
'modules/shortlinks.php' => ['PhanPluginDuplicateExpressionAssignmentOperation', 'PhanTypeMismatchArgumentInternal', 'PhanTypeMismatchArgumentProbablyReal'],
'modules/simple-payments/simple-payments.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchReturn'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: other

Migration of ad formats from IPONWEB to WATL

45 changes: 41 additions & 4 deletions projects/plugins/jetpack/extensions/blocks/wordads/wordads.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@
* @since 7.1.0
*/
class WordAds {
/**
* Mapping array of gutenberg ad snippet with the WordAds_Smart formats.
*
* @var array
*/
private static $gutenberg_ad_snippet_x_smart_format = array(
'gutenberg_300x250' => 'gutenberg_rectangle',
'gutenberg_728x90' => 'gutenberg_leaderboard',
'gutenberg_320x50' => 'gutenberg_mobile_leaderboard',
'gutenberg_160x600' => 'gutenberg_skyscraper',
);

/**
* Check if site is on WP.com Simple.
*
Expand Down Expand Up @@ -127,10 +139,35 @@ public static function gutenblock_render( $attr ) {
$format = $attr['format'];
}

$height = $ad_tag_ids[ $format ]['height'];
$width = $ad_tag_ids[ $format ]['width'];
$snippet = $wordads->get_ad_snippet( $section_id, $height, $width, 'gutenberg', $wordads->get_solo_unit_css() );
return $wordads->get_ad_div( 'inline', $snippet, array( $align ) );
$height = $ad_tag_ids[ $format ]['height'];
$width = $ad_tag_ids[ $format ]['width'];
$location = 'gutenberg';
$snippet = $wordads->get_ad_snippet( $section_id, $height, $width, $location, $wordads->get_solo_unit_css() );

$key = "{$location}_{$width}x{$height}";
$smart_format = self::$gutenberg_ad_snippet_x_smart_format[ $key ] ?? null;
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$is_watl_enabled = $smart_format && ( isset( $_GET[ $smart_format ] ) && 'true' === $_GET[ $smart_format ] );
$ad_div = $wordads->get_ad_div( 'inline', $snippet, array( $align ) );
// Render IPW div if WATL is not enabled.
if ( ! $is_watl_enabled ) {
return $ad_div;
}

// Remove linebreaks and sanitize.
$snippet = esc_js( str_replace( array( "\n", "\t", "\r" ), '', $ad_div ) );

// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
$fallback_snippet = <<<HTML
<script>
var sas_fallback = sas_fallback || [];
sas_fallback.push(
{ tag: "$snippet", type: '$smart_format' }
);
</script>
HTML;

return $fallback_snippet . $wordads->get_watl_ad_html_tag( $smart_format );
}
}

Expand Down
116 changes: 110 additions & 6 deletions projects/plugins/jetpack/modules/wordads/class-wordads.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
require_once WORDADS_ROOT . '/php/class-wordads-ccpa-do-not-sell-link-widget.php';
require_once WORDADS_ROOT . '/php/class-wordads-consent-management-provider.php';
require_once WORDADS_ROOT . '/php/class-wordads-smart.php';
require_once WORDADS_ROOT . '/php/class-wordads-shortcode.php';

/**
* Primary WordAds class.
Expand Down Expand Up @@ -215,6 +216,9 @@ public function init() {
WordAds_Consent_Management_Provider::init();
}

// Initialize [wordads] shortcode.
WordAds_Shortcode::init();

// Initialize Smart.
WordAds_Smart::instance()->init( $this->params );

Expand Down Expand Up @@ -371,28 +375,78 @@ public function insert_head_meta() {
$site_id = $this->params->blog_id;
$consent = (int) isset( $_COOKIE['personalized-ads-consent'] );
$is_logged_in = is_user_logged_in() ? '1' : '0';

$disabled_slot_formats = apply_filters( 'wordads_disabled_slot_formats', array() );

if ( apply_filters( 'wordads_iponweb_bottom_sticky_ad_disable', false ) ) {
$disabled_slot_formats[] = 'MTS';
}

if ( apply_filters( 'wordads_iponweb_sidebar_sticky_right_ad_disable', false ) ) {
$disabled_slot_formats[] = 'DPR';
}

$config = array(
'pt' => $pagetype,
'ht' => $hosting_type,
'tn' => get_stylesheet(),
'uloggedin' => $is_logged_in,
'amp' => false,
'siteid' => $site_id,
'consent' => $consent,
'ad' => array(
'label' => array(
'text' => __( 'Advertisements', 'jetpack' ),
),
'reportAd' => array(
'text' => __( 'Report this ad', 'jetpack' ),
),
'privacySettings' => array(
'text' => __( 'Privacy', 'jetpack' ),
'onClick' => 'js:function() { window.__tcfapi && window.__tcfapi(\'showUi\'); }',
),
),
'disabled_slot_formats' => $disabled_slot_formats,
);
$js_config = WordAds_Array_Utils::array_to_js_object( $config );
?>
<script<?php echo esc_attr( $data_tags ); ?> type="text/javascript">
var __ATA_PP = { pt: <?php echo esc_js( $pagetype ); ?>, ht: <?php echo esc_js( $hosting_type ); ?>, tn: '<?php echo esc_js( get_stylesheet() ); ?>', uloggedin: <?php echo esc_js( $is_logged_in ); ?>, amp: false, siteid: <?php echo esc_js( $site_id ); ?>, consent: <?php echo esc_js( $consent ); ?>, ad: { label: { text: '<?php echo esc_js( __( 'Advertisements', 'jetpack' ) ); ?>' }, reportAd: { text: '<?php echo esc_js( __( 'Report this ad', 'jetpack' ) ); ?>' }, privacySettings: { text: '<?php echo esc_js( __( 'Privacy', 'jetpack' ) ); ?>', onClick: function() { window.__tcfapi && window.__tcfapi('showUi'); } } } };
var __ATA_PP = <?php echo $js_config; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>;
var __ATA = __ATA || {};
__ATA.cmd = __ATA.cmd || [];
__ATA.criteo = __ATA.criteo || {};
__ATA.criteo.cmd = __ATA.criteo.cmd || [];
</script>
<?php

$section_id = $this->params->blog_id . 5;

// Get below post tag.
$tag_belowpost = $this->get_fallback_ad_snippet( $section_id, 'square', 'belowpost', '', '{{unique_id}}' );

// Remove linebreaks and sanitize.
$tag_belowpost = esc_js( str_replace( array( "\n", "\t", "\r" ), '', $tag_belowpost ) );

// Get an inline tag with a macro as id handled on JS side to use as a fallback.
$tag_inline = $this->get_dynamic_ad_snippet( $this->params->blog_id . 5, 'square', 'inline', '', '{{unique_id}}' );
$tag_inline = $this->get_fallback_ad_snippet( $section_id, 'square', 'inline', '', '{{unique_id}}' );

// Remove linebreaks and sanitize.
$tag_inline = esc_js( str_replace( array( "\n", "\t", "\r" ), '', $tag_inline ) );

// Get top tag.
$tag_top = $this->get_fallback_ad_snippet( $section_id, 'leaderboard', 'top', '', '{{unique_id}}' );

// Remove linebreaks and sanitize.
$tag_top = esc_js( str_replace( array( "\n", "\t", "\r" ), '', $tag_top ) );

// phpcs:disable WordPress.Security.EscapeOutput.HeredocOutputNotEscaped
echo <<<HTML
<script>
<script type="text/javascript">
var sas_fallback = sas_fallback || [];
sas_fallback.push(
{ tag: "$tag_inline", type: 'inline' }
{ tag: "$tag_inline", type: 'inline' },
{ tag: "$tag_belowpost", type: 'belowpost' },
{ tag: "$tag_top", type: 'top' }
);
</script>
HTML;
Expand Down Expand Up @@ -477,8 +531,17 @@ public function insert_inline_ad( $content ) {
}

$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
$content .= $this->get_ad( 'inline', $ad_type );
return $content;
$location = 'shortcode';
// not house ad and watl enabled
// phpcs:disable WordPress.Security.NonceVerification.Recommended
if ( 'house' !== $ad_type && ( isset( $_GET['wordads-logging'] ) && isset( $_GET[ $location ] ) && 'true' === $_GET[ $location ] ) ) {
return $content . $this->get_watl_ad_html_tag( $location );
}

return $content .= sprintf(
'<div class="jetpack-wordad" itemscope itemtype="https://schema.org/WPAdBlock">%s</div>',
$this->get_ad( 'inline', $ad_type )
);
}

/**
Expand Down Expand Up @@ -703,6 +766,7 @@ public function get_ad_snippet( $section_id, $height, $width, $location = '', $c
$form_factor = 'leaderboard';
}

// TODO: Still investigating required change. Potentially update with respect with what get_ad_div on WPCOM for gutenberg
return $this->get_dynamic_ad_snippet( $section_id, $form_factor, $location );
}

Expand All @@ -720,6 +784,33 @@ public function get_ad_snippet( $section_id, $height, $width, $location = '', $c
* @since 8.7
*/
public function get_dynamic_ad_snippet( $section_id, $form_factor = 'square', $location = '', $relocate = '', $id = null ) {

// Allow overriding and printing of the tag parsed by the WATL.
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$is_location_enabled = isset( $_GET['wordads-logging'] ) && isset( $_GET[ $location ] ) && 'true' === $_GET[ $location ];

if ( ( 'top' === $location || 'belowpost' === $location ) && $is_location_enabled ) {
// TODO: Confirm if it's best here or there is a way to get it via the adflow config endpoint
return self::get_watl_ad_html_tag( $location );
}

return $this->get_fallback_ad_snippet( $section_id, $form_factor, $location, $relocate, $id );
}

/**
* Returns the fallback dynamic snippet to be inserted into the ad unit
*
* @param int $section_id section_id.
* @param string $form_factor form_factor.
* @param string $location location.
* @param string $relocate location to be moved after the fact for themes without required hook.
* @param string | null $id A unique string ID or placeholder.
*
* @return string
*
* @since 8.7
*/
public function get_fallback_ad_snippet( $section_id, $form_factor = 'square', $location = '', $relocate = '', $id = null ) {
$div_id = 'atatags-' . $section_id . '-' . ( $id ?? uniqid() );
$div_id = esc_attr( $div_id );

Expand Down Expand Up @@ -868,6 +959,19 @@ public function get_house_ad( $unit = 'mrec' ) {
HTML;
}

/**
* Returns the html ad tag used by WordAds Tag Library
*
* @param string $slot_type e.g belowpost, gutenberg_rectangle.
*
* @return string
*
* @since 8.7
*/
public static function get_watl_ad_html_tag( string $slot_type ): string {
return "<div class=\"wordads-tag\" data-slot-type=\"$slot_type\" style=\"display: none;\"></div>";
}

/**
* Activation hook actions
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ class WordAds_Params {
*/
public $page_type_ipw;

/**
* Is this an AMP request?
*
* @var bool
*/
public $is_amp;

/**
* Setup parameters for serving the ads
*
Expand All @@ -79,22 +86,24 @@ class WordAds_Params {
public function __construct() {
// WordAds setting => default.
$settings = array(
'wordads_approved' => false,
'wordads_active' => false,
'wordads_house' => true,
'wordads_unsafe' => false,
'enable_header_ad' => true,
'wordads_second_belowpost' => true,
'wordads_inline_enabled' => true,
'wordads_display_front_page' => true,
'wordads_display_post' => true,
'wordads_display_page' => true,
'wordads_display_archive' => true,
'wordads_custom_adstxt' => '',
'wordads_custom_adstxt_enabled' => false,
'wordads_ccpa_enabled' => false,
'wordads_ccpa_privacy_policy_url' => get_option( 'wp_page_for_privacy_policy' ) ? get_permalink( (int) get_option( 'wp_page_for_privacy_policy' ) ) : '',
'wordads_cmp_enabled' => false,
'wordads_approved' => false,
'wordads_active' => false,
'wordads_house' => true,
'wordads_unsafe' => false,
'enable_header_ad' => true,
'wordads_second_belowpost' => true,
'wordads_inline_enabled' => true,
'wordads_bottom_sticky_enabled' => false,
'wordads_sidebar_sticky_right_enabled' => false,
'wordads_display_front_page' => true,
'wordads_display_post' => true,
'wordads_display_page' => true,
'wordads_display_archive' => true,
'wordads_custom_adstxt' => '',
'wordads_custom_adstxt_enabled' => false,
'wordads_ccpa_enabled' => false,
'wordads_ccpa_privacy_policy_url' => get_option( 'wp_page_for_privacy_policy' ) ? get_permalink( (int) get_option( 'wp_page_for_privacy_policy' ) ) : '',
'wordads_cmp_enabled' => false,
);

// Grab settings, or set as default if it doesn't exist.
Expand Down Expand Up @@ -136,6 +145,7 @@ public function __construct() {
'LangId' => str_contains( get_bloginfo( 'language' ), 'en' ) ? 1 : 0, // TODO something else?
'AdSafe' => 1, // TODO.
);
$this->is_amp = function_exists( 'amp_is_request' ) && amp_is_request();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
<?php
/**
* Wordads shortcode.
*
Expand All @@ -9,35 +9,23 @@
*/

/**
* Embed WordAds 'ad' in post
* Class WordAds_Shortcode
*
* Handles the [wordads] shortcode.
*/
class Jetpack_WordAds_Shortcode {

/**
* Used to determine whether scripts and styles have been enqueued already.
*
* @var bool false Should we enqueue scripts and styles.
*/
private $scripts_and_style_included = false;

/**
* Initialize.
*/
public function __construct() {
add_action( 'init', array( $this, 'action_init' ) );
}
class WordAds_Shortcode {

/**
* Register our shortcode and enqueue necessary files.
*/
public function action_init() {
public static function init() {
global $wordads;

if ( empty( $wordads ) ) {
return null;
}

add_shortcode( 'wordads', array( $this, 'wordads_shortcode' ) );
add_shortcode( 'wordads', array( self::class, 'handle_wordads_shortcode' ) );
}

/**
Expand All @@ -49,7 +37,7 @@ public function action_init() {
*
* @return string HTML for WordAds shortcode.
*/
public static function wordads_shortcode( $atts, $content = '' ) {
public static function handle_wordads_shortcode( $atts, $content = '' ) {
$atts = shortcode_atts( array(), $atts, 'wordads' );

return self::wordads_shortcode_html( $atts, $content );
Expand All @@ -70,11 +58,8 @@ private static function wordads_shortcode_html( $atts, $content = '' ) { // phpc
return '<div>' . __( 'The WordAds module is not active', 'jetpack' ) . '</div>';
}

$html = '<div class="jetpack-wordad" itemscope itemtype="https://schema.org/WPAdBlock"></div>';
$html = $wordads->insert_inline_ad( $html );
$html = $wordads->insert_inline_ad( '' );

return $html;
}
}

new Jetpack_WordAds_Shortcode();
Loading
Loading