PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | modules/wordads/php/class-wordads-smart.php +346 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,346 @@
1 +<?php
2 +/**
3 + * An implementation for ads served through Equativ Smart Ad Server.
4 + *
5 + * @package automattic/jetpack
6 + */
7 +
8 +use Automattic\Jetpack\Assets;
9 +
10 +if ( ! defined( 'ABSPATH' ) ) {
11 + exit( 0 );
12 +}
13 +
14 +require_once WORDADS_ROOT . '/php/class-wordads-array-utils.php';
15 +
16 +/**
17 + * Contains all the implementation details for Smart ads
18 + */
19 +class WordAds_Smart {
20 +
21 + /**
22 + * The single instance of the class.
23 + *
24 + * @var WordAds_Smart
25 + */
26 + protected static $instance = null;
27 +
28 + /**
29 + * The parameters for WordAds.
30 + *
31 + * @var WordAds_Params
32 + */
33 + private $params;
34 +
35 + /**
36 + * Has Smart asset been enqueued?
37 + *
38 + * @var bool True if Smart asset has been enqueued.
39 + */
40 + private $is_asset_enqueued = false;
41 +
42 + /**
43 + * Supported formats.
44 + * sidebar_widget formats represents the legacy Jetpack sidebar widget.
45 + *
46 + * @var array
47 + */
48 + private $formats = array(
49 + 'top' => array(
50 + 'enabled' => false,
51 + ),
52 + 'inline' => array(
53 + 'enabled' => false,
54 + ),
55 + 'belowpost' => array(
56 + 'enabled' => false,
57 + ),
58 + 'bottom_sticky' => array(
59 + 'enabled' => false,
60 + ),
61 + 'sidebar_sticky_right' => array(
62 + 'enabled' => false,
63 + ),
64 + 'gutenberg_rectangle' => array(
65 + 'enabled' => false,
66 + ),
67 + 'gutenberg_leaderboard' => array(
68 + 'enabled' => false,
69 + ),
70 + 'gutenberg_mobile_leaderboard' => array(
71 + 'enabled' => false,
72 + ),
73 + 'gutenberg_skyscraper' => array(
74 + 'enabled' => false,
75 + ),
76 + 'sidebar_widget_mediumrectangle' => array(
77 + 'enabled' => false,
78 + ),
79 + 'sidebar_widget_leaderboard' => array(
80 + 'enabled' => false,
81 + ),
82 + 'sidebar_widget_wideskyscraper' => array(
83 + 'enabled' => false,
84 + ),
85 + 'shortcode' => array(
86 + 'enabled' => false,
87 + ),
88 + );
89 +
90 + /**
91 + * Private constructor.
92 + */
93 + private function __construct() {
94 + }
95 +
96 + /**
97 + * Main Class Instance.
98 + *
99 + * Ensures only one instance of WordAds_Smart is loaded or can be loaded.
100 + *
101 + * @return WordAds_Smart
102 + */
103 + public static function instance(): self {
104 + if ( null === self::$instance ) {
105 + self::$instance = new self();
106 + }
107 + return self::$instance;
108 + }
109 +
110 + /**
111 + * Initialize the ads.
112 + *
113 + * @param WordAds_Params $params Object containing WordAds settings.
114 + *
115 + * @return void
116 + */
117 + public function init( WordAds_Params $params ) {
118 + $this->params = $params;
119 +
120 + $this->enable_formats();
121 + $this->override_formats_from_query_string();
122 +
123 + if ( $this->has_any_format_enabled() ) {
124 + $this->insert_ads();
125 + }
126 + }
127 +
128 + /**
129 + * Enqueue any front-end CSS and JS.
130 + *
131 + * @return void
132 + */
133 + public function enqueue_assets() {
134 +
135 + if ( $this->is_asset_enqueued ) {
136 + return;
137 + }
138 +
139 + add_action( 'wp_head', array( $this, 'insert_config' ) );
140 +
141 + Assets::register_script(
142 + 'adflow_script_loader',
143 + '_inc/build/wordads/js/adflow-loader.min.js',
144 + JETPACK__PLUGIN_FILE,
145 + array(
146 + 'nonmin_path' => 'modules/wordads/js/adflow-loader.js',
147 + 'dependencies' => array(),
148 + 'enqueue' => true,
149 + 'version' => JETPACK__VERSION,
150 + )
151 + );
152 +
153 + wp_enqueue_script(
154 + 'adflow_config',
155 + esc_url( $this->get_config_url() ),
156 + array( 'adflow_script_loader' ),
157 + JETPACK__VERSION,
158 + false
159 + );
160 +
161 + $this->is_asset_enqueued = true;
162 + }
163 +
164 + /**
165 + * Inserts ad tags on the page.
166 + *
167 + * @return void
168 + */
169 + private function insert_ads() {
170 + if ( $this->params->is_amp ) {
171 + return;
172 + }
173 +
174 + // Don't run on not found pages.
175 + if ( is_404() ) {
176 + return;
177 + }
178 +
179 + // Add the resource hints.
180 + add_filter( 'wp_resource_hints', array( $this, 'resource_hints' ), 10, 2 );
181 +
182 + // Enqueue JS assets.
183 + $this->enqueue_assets();
184 +
185 + $is_static_front_page = is_front_page() && 'page' === get_option( 'show_on_front' );
186 +
187 + if ( ! ( $is_static_front_page || is_home() ) ) {
188 + if ( $this->formats['inline']['enabled'] ) {
189 + add_filter(
190 + 'the_content',
191 + array( $this, 'insert_inline_marker' ),
192 + 10
193 + );
194 + }
195 + }
196 +
197 + if ( $this->formats['bottom_sticky']['enabled'] ) {
198 + // Disable IPW slot.
199 + add_filter( 'wordads_iponweb_bottom_sticky_ad_disable', '__return_true', 10 );
200 + }
201 +
202 + if ( $this->formats['sidebar_sticky_right']['enabled'] ) {
203 + // Disable IPW slot.
204 + add_filter( 'wordads_iponweb_sidebar_sticky_right_ad_disable', '__return_true', 10 );
205 + }
206 + }
207 +
208 + /**
209 + * Inserts JS configuration used by watl.js.
210 + *
211 + * @return void
212 + */
213 + public function insert_config() {
214 + global $post;
215 +
216 + $config = array(
217 + 'post_id' => ( $post instanceof WP_Post ) && is_singular( 'post' ) ? $post->ID : null,
218 + 'origin' => 'jetpack',
219 + 'theme' => get_stylesheet(),
220 + 'target' => $this->target_keywords(),
221 + ) + $this->formats;
222 +
223 + // Do conversion.
224 + $js_config = WordAds_Array_Utils::array_to_js_object( $config );
225 +
226 + // Output script.
227 + wp_print_inline_script_tag( "var wa_smart = $js_config; wa_smart.cmd = [];" );
228 + }
229 +
230 + /**
231 + * Add the Smart resource hints.
232 + *
233 + * @param array $hints Domains for hinting.
234 + * @param string $relation_type Resource type.
235 + *
236 + * @return array Domains for hinting.
237 + */
238 + public function resource_hints( $hints, $relation_type ) {
239 + if ( 'dns-prefetch' === $relation_type ) {
240 + $hints[] = '//af.pubmine.com';
241 + }
242 +
243 + return $hints;
244 + }
245 +
246 + /**
247 + * Gets the URL to a JSONP endpoint with configuration data.
248 + *
249 + * @return string The URL.
250 + */
251 + private function get_config_url(): string {
252 + return sprintf(
253 + 'https://public-api.wordpress.com/wpcom/v2/sites/%1$d/adflow/conf/?_jsonp=a8c_adflow_callback',
254 + $this->params->blog_id
255 + );
256 + }
257 +
258 + /**
259 + * Places marker at the end of the content so inline can identify the post content container.
260 + *
261 + * @param string|null $content The post content.
262 + * @return string|null The post content with the marker appended.
263 + */
264 + public function insert_inline_marker( ?string $content ): ?string {
265 + if ( null === $content ) {
266 + return null;
267 + }
268 + $inline_ad_marker = '<span id="wordads-inline-marker" style="display: none;"></span>';
269 +
270 + // Append the ad to the post content.
271 + return $content . $inline_ad_marker;
272 + }
273 +
274 + /**
275 + * Gets a formatted list of target keywords.
276 + *
277 + * @return string Formatted list of target keywords.
278 + */
279 + private function target_keywords(): string {
280 + $target_keywords = array_merge(
281 + $this->get_blog_keywords(),
282 + $this->get_language_keywords()
283 + );
284 +
285 + return implode( ';', $target_keywords );
286 + }
287 +
288 + /**
289 + * Gets a formatted list of blog keywords.
290 + *
291 + * @return array The list of blog keywords.
292 + */
293 + private function get_blog_keywords(): array {
294 + return array( 'wp_blog_id=' . $this->params->blog_id );
295 + }
296 +
297 + /**
298 + * Gets the site language formatted as a keyword.
299 + *
300 + * @return array The language as a keyword.
301 + */
302 + private function get_language_keywords(): array {
303 + return array( 'language=' . explode( '-', get_locale() )[0] );
304 + }
305 +
306 + /**
307 + * Enable formats by post types and the display options.
308 + *
309 + * @return void
310 + */
311 + private function enable_formats(): void {
312 + $this->formats['top']['enabled'] = $this->params->options['enable_header_ad'];
313 + $this->formats['inline']['enabled'] = is_singular( 'post' ) && $this->params->options['wordads_inline_enabled'];
314 + $this->formats['belowpost']['enabled'] = $this->params->should_show();
315 + $this->formats['bottom_sticky']['enabled'] = $this->params->options['wordads_bottom_sticky_enabled'];
316 + $this->formats['sidebar_sticky_right']['enabled'] = $this->params->options['wordads_sidebar_sticky_right_enabled'];
317 + }
318 +
319 + /**
320 + * Allow format enabled override from query string, eg. ?inline=true.
321 + *
322 + * @return void
323 + */
324 + private function override_formats_from_query_string(): void {
325 + // phpcs:disable WordPress.Security.NonceVerification.Recommended
326 + if ( ! isset( $_GET['wordads-logging'] ) ) {
327 + return;
328 + }
329 +
330 + foreach ( $this->formats as $format_type => $_ ) {
331 + // phpcs:disable WordPress.Security.NonceVerification.Recommended
332 + if ( isset( $_GET[ $format_type ] ) && 'true' === $_GET[ $format_type ] ) {
333 + $this->formats[ $format_type ]['enabled'] = true;
334 + }
335 + }
336 + }
337 +
338 + /**
339 + * Check if has any format enabled.
340 + *
341 + * @return bool True if enabled, false otherwise.
342 + */
343 + private function has_any_format_enabled(): bool {
344 + return in_array( true, array_column( $this->formats, 'enabled' ), true );
345 + }
346 +}