PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 7.6.2
Jetpack – WP Security, Backup, Speed, & Growth v7.6.2
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 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 All 503 releases
jetpack / modules / wordads / wordads.php

wordads.php in Jetpack – WP Security, Backup, Speed, & Growth 7.6.2, at modules/wordads/wordads.php

620 lines 16.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 define( 'WORDADS_ROOT', dirname( __FILE__ ) );
4 define( 'WORDADS_BASENAME', plugin_basename( __FILE__ ) );
5 define( 'WORDADS_FILE_PATH', WORDADS_ROOT . '/' . basename( __FILE__ ) );
6 define( 'WORDADS_URL', plugins_url( '/', __FILE__ ) );
7 define( 'WORDADS_API_TEST_ID', '26942' );
8 define( 'WORDADS_API_TEST_ID2', '114160' );
9
10 require_once WORDADS_ROOT . '/php/widgets.php';
11 require_once WORDADS_ROOT . '/php/api.php';
12 require_once WORDADS_ROOT . '/php/cron.php';
13
14 class WordAds {
15
16 public $params = null;
17
18 public $ads = array();
19
20 /**
21 * Array of supported ad types.
22 *
23 * @var array
24 */
25 public static $ad_tag_ids = array(
26 'mrec' => array(
27 'tag' => '300x250_mediumrectangle',
28 'height' => '250',
29 'width' => '300',
30 ),
31 'leaderboard' => array(
32 'tag' => '728x90_leaderboard',
33 'height' => '90',
34 'width' => '728',
35 ),
36 'mobile_leaderboard' => array(
37 'tag' => '320x50_mobileleaderboard',
38 'height' => '50',
39 'width' => '320',
40 ),
41 'wideskyscraper' => array(
42 'tag' => '160x600_wideskyscraper',
43 'height' => '600',
44 'width' => '160',
45 ),
46 );
47
48 /**
49 * Mapping array of location slugs to placement ids
50 *
51 * @var array
52 */
53 public static $ad_location_ids = array(
54 'top' => 110,
55 'belowpost' => 120,
56 'belowpost2' => 130,
57 'sidebar' => 140,
58 'widget' => 150,
59 'gutenberg' => 200,
60 'inline' => 310,
61 'inline-plugin' => 320,
62 );
63
64 public static $SOLO_UNIT_CSS = 'float:left;margin-right:5px;margin-top:0px;';
65
66 /**
67 * Convenience function for grabbing options from params->options
68 *
69 * @param string $option the option to grab
70 * @param mixed $default (optional)
71 * @return option or $default if not set
72 *
73 * @since 4.5.0
74 */
75 function option( $option, $default = false ) {
76 if ( ! isset( $this->params->options[ $option ] ) ) {
77 return $default;
78 }
79
80 return $this->params->options[ $option ];
81 }
82
83 /**
84 * Returns the ad tag property array for supported ad types.
85 * @return array array with ad tags
86 *
87 * @since 7.1.0
88 */
89 function get_ad_tags() {
90 return self::$ad_tag_ids;
91 }
92
93 /**
94 * Returns the solo css for unit
95 * @return string the special css for solo units
96 *
97 * @since 7.1.0
98 */
99 function get_solo_unit_css() {
100 return self::$SOLO_UNIT_CSS;
101 }
102
103 /**
104 * Instantiate the plugin
105 *
106 * @since 4.5.0
107 */
108 function __construct() {
109 add_action( 'init', array( $this, 'init' ) );
110 }
111
112 /**
113 * Code to run on WordPress 'init' hook
114 *
115 * @since 4.5.0
116 */
117 function init() {
118 require_once WORDADS_ROOT . '/php/params.php';
119 $this->params = new WordAds_Params();
120
121 if ( $this->should_bail() || self::is_infinite_scroll() ) {
122 return;
123 }
124
125 if ( is_admin() ) {
126 require_once WORDADS_ROOT . '/php/admin.php';
127 return;
128 }
129
130 $this->insert_adcode();
131
132 if ( '/ads.txt' === $_SERVER['REQUEST_URI'] ) {
133
134 if ( false === ( $ads_txt_transient = get_transient( 'jetpack_ads_txt' ) ) ) {
135 $ads_txt_transient = ! is_wp_error( WordAds_API::get_wordads_ads_txt() ) ? WordAds_API::get_wordads_ads_txt() : '';
136 set_transient( 'jetpack_ads_txt', $ads_txt_transient, DAY_IN_SECONDS );
137 }
138
139 /**
140 * Provide plugins a way of modifying the contents of the automatically-generated ads.txt file.
141 *
142 * @module wordads
143 *
144 * @since 6.1.0
145 *
146 * @param string WordAds_API::get_wordads_ads_txt() The contents of the ads.txt file.
147 */
148 $ads_txt_content = apply_filters( 'wordads_ads_txt', $ads_txt_transient );
149
150 header( 'Content-Type: text/plain; charset=utf-8' );
151 echo esc_html( $ads_txt_content );
152 die();
153 }
154 }
155
156 /**
157 * Check for Jetpack's The_Neverending_Home_Page and use got_infinity
158 *
159 * @return boolean true if load came from infinite scroll
160 *
161 * @since 4.5.0
162 */
163 public static function is_infinite_scroll() {
164 return class_exists( 'The_Neverending_Home_Page' ) && The_Neverending_Home_Page::got_infinity();
165 }
166
167 /**
168 * Add the actions/filters to insert the ads. Checks for mobile or desktop.
169 *
170 * @since 4.5.0
171 */
172 private function insert_adcode() {
173 add_action( 'wp_head', array( $this, 'insert_head_meta' ), 20 );
174 add_action( 'wp_head', array( $this, 'insert_head_iponweb' ), 30 );
175 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
176 add_filter( 'wordads_ads_txt', array( $this, 'insert_custom_adstxt' ) );
177
178 /**
179 * Filters enabling ads in `the_content` filter
180 *
181 * @see https://jetpack.com/support/ads/
182 *
183 * @module wordads
184 *
185 * @since 5.8.0
186 *
187 * @param bool True to disable ads in `the_content`
188 */
189 if ( ! apply_filters( 'wordads_content_disable', false ) ) {
190 add_filter( 'the_content', array( $this, 'insert_ad' ) );
191 }
192
193 /**
194 * Filters enabling ads in `the_excerpt` filter
195 *
196 * @see https://jetpack.com/support/ads/
197 *
198 * @module wordads
199 *
200 * @since 5.8.0
201 *
202 * @param bool True to disable ads in `the_excerpt`
203 */
204 if ( ! apply_filters( 'wordads_excerpt_disable', false ) ) {
205 add_filter( 'the_excerpt', array( $this, 'insert_ad' ) );
206 }
207
208 if ( $this->option( 'enable_header_ad', true ) ) {
209 switch ( get_stylesheet() ) {
210 case 'twentyseventeen':
211 case 'twentyfifteen':
212 case 'twentyfourteen':
213 add_action( 'wp_footer', array( $this, 'insert_header_ad_special' ) );
214 break;
215 default:
216 add_action( 'wp_head', array( $this, 'insert_header_ad' ), 100 );
217 break;
218 }
219 }
220 }
221
222 /**
223 * Register desktop scripts and styles
224 *
225 * @since 4.5.0
226 */
227 function enqueue_scripts() {
228 wp_enqueue_style(
229 'wordads',
230 WORDADS_URL . 'css/style.css',
231 array(),
232 '2015-12-18'
233 );
234 }
235
236 /**
237 * IPONWEB metadata used by the various scripts
238 *
239 * @return [type] [description]
240 */
241 function insert_head_meta() {
242 $themename = esc_js( get_stylesheet() );
243 $pagetype = intval( $this->params->get_page_type_ipw() );
244 $data_tags = ( $this->params->cloudflare ) ? ' data-cfasync="false"' : '';
245 $site_id = $this->params->blog_id;
246 $consent = intval( isset( $_COOKIE['personalized-ads-consent'] ) );
247 echo <<<HTML
248 <script$data_tags type="text/javascript">
249 var __ATA_PP = { pt: $pagetype, ht: 2, tn: '$themename', amp: false, siteid: $site_id, consent: $consent };
250 var __ATA = __ATA || {};
251 __ATA.cmd = __ATA.cmd || [];
252 __ATA.criteo = __ATA.criteo || {};
253 __ATA.criteo.cmd = __ATA.criteo.cmd || [];
254 </script>
255 HTML;
256 }
257
258 /**
259 * IPONWEB scripts in <head>
260 *
261 * @since 4.5.0
262 */
263 function insert_head_iponweb() {
264 $data_tags = ( $this->params->cloudflare ) ? ' data-cfasync="false"' : '';
265 echo <<<HTML
266 <link rel='dns-prefetch' href='//s.pubmine.com' />
267 <link rel='dns-prefetch' href='//x.bidswitch.net' />
268 <link rel='dns-prefetch' href='//static.criteo.net' />
269 <link rel='dns-prefetch' href='//ib.adnxs.com' />
270 <link rel='dns-prefetch' href='//aax.amazon-adsystem.com' />
271 <link rel='dns-prefetch' href='//bidder.criteo.com' />
272 <link rel='dns-prefetch' href='//cas.criteo.com' />
273 <link rel='dns-prefetch' href='//gum.criteo.com' />
274 <link rel='dns-prefetch' href='//ads.pubmatic.com' />
275 <link rel='dns-prefetch' href='//gads.pubmatic.com' />
276 <link rel='dns-prefetch' href='//tpc.googlesyndication.com' />
277 <link rel='dns-prefetch' href='//ad.doubleclick.net' />
278 <link rel='dns-prefetch' href='//googleads.g.doubleclick.net' />
279 <link rel='dns-prefetch' href='//www.googletagservices.com' />
280 <script$data_tags async type="text/javascript" src="//s.pubmine.com/head.js"></script>
281 HTML;
282 }
283
284 /**
285 * Insert the ad onto the page
286 *
287 * @since 4.5.0
288 */
289 function insert_ad( $content ) {
290 // Don't insert ads in feeds, or for anything but the main display. (This is required for compatibility with the Publicize module).
291 if ( is_feed() || ! is_main_query() || ! in_the_loop() ) {
292 return $content;
293 }
294 /**
295 * Allow third-party tools to disable the display of in post ads.
296 *
297 * @module wordads
298 *
299 * @since 4.5.0
300 *
301 * @param bool true Should the in post unit be disabled. Default to false.
302 */
303 $disable = apply_filters( 'wordads_inpost_disable', false );
304 if ( ! $this->params->should_show() || $disable ) {
305 return $content;
306 }
307
308 $ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
309 return $content . $this->get_ad( 'belowpost', $ad_type );
310 }
311
312 /**
313 * Insert an inline ad into a post content
314 * Used for rendering the `wordads` shortcode.
315 *
316 * @since 6.1.0
317 */
318 function insert_inline_ad( $content ) {
319 // Ad JS won't work in XML feeds.
320 if ( is_feed() ) {
321 return $content;
322 }
323 /**
324 * Allow third-party tools to disable the display of in post ads.
325 *
326 * @module wordads
327 *
328 * @since 4.5.0
329 *
330 * @param bool true Should the in post unit be disabled. Default to false.
331 */
332 $disable = apply_filters( 'wordads_inpost_disable', false );
333 if ( $disable ) {
334 return $content;
335 }
336
337 $ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
338 $content .= $this->get_ad( 'inline', $ad_type );
339 return $content;
340 }
341
342 /**
343 * Inserts ad into header
344 *
345 * @since 4.5.0
346 */
347 function insert_header_ad() {
348 /**
349 * Allow third-party tools to disable the display of header ads.
350 *
351 * @module wordads
352 *
353 * @since 4.5.0
354 *
355 * @param bool true Should the header unit be disabled. Default to false.
356 */
357 if ( apply_filters( 'wordads_header_disable', false ) ) {
358 return;
359 }
360
361 $ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
362 echo $this->get_ad( 'top', $ad_type );
363 }
364
365 /**
366 * Special cases for inserting header unit via jQuery
367 *
368 * @since 4.5.0
369 */
370 function insert_header_ad_special() {
371 /**
372 * Allow third-party tools to disable the display of header ads.
373 *
374 * @module wordads
375 *
376 * @since 4.5.0
377 *
378 * @param bool true Should the header unit be disabled. Default to false.
379 */
380 if ( apply_filters( 'wordads_header_disable', false ) ) {
381 return;
382 }
383
384 $selector = '#content';
385 switch ( get_stylesheet() ) {
386 case 'twentyseventeen':
387 $selector = '#content';
388 break;
389 case 'twentyfifteen':
390 $selector = '#main';
391 break;
392 case 'twentyfourteen':
393 $selector = 'article:first';
394 break;
395 }
396
397 $ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
398 echo $this->get_ad( 'top', $ad_type );
399 echo <<<HTML
400 <script type="text/javascript">
401 jQuery('.wpcnt-header').insertBefore('$selector');
402 </script>
403 HTML;
404 }
405
406 /**
407 * Filter the latest ads.txt to include custom user entries. Strips any tags or whitespace.
408 *
409 * @param string $adstxt The ads.txt being filtered
410 * @return string Filtered ads.txt with custom entries, if applicable
411 *
412 * @since 6.5.0
413 */
414 function insert_custom_adstxt( $adstxt ) {
415 $custom_adstxt = trim( wp_strip_all_tags( $this->option( 'wordads_custom_adstxt' ) ) );
416 if ( $custom_adstxt ) {
417 $adstxt .= "\n\n#Jetpack - User Custom Entries\n";
418 $adstxt .= $custom_adstxt . "\n";
419 }
420
421 return $adstxt;
422 }
423
424 /**
425 * Get the ad for the spot and type.
426 *
427 * @param string $spot top, side, inline, or belowpost
428 * @param string $type iponweb or adsense
429 */
430 function get_ad( $spot, $type = 'iponweb' ) {
431 $snippet = '';
432 if ( 'iponweb' == $type ) {
433 // Default to mrec
434 $width = 300;
435 $height = 250;
436
437 $section_id = WORDADS_API_TEST_ID;
438 $second_belowpost = '';
439 $snippet = '';
440 if ( 'top' == $spot ) {
441 // mrec for mobile, leaderboard for desktop
442 $section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '2';
443 $width = $this->params->mobile_device ? 300 : 728;
444 $height = $this->params->mobile_device ? 250 : 90;
445 $snippet = $this->get_ad_snippet( $section_id, $height, $width, $spot );
446 } elseif ( 'belowpost' == $spot ) {
447 $section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '1';
448 $width = 300;
449 $height = 250;
450
451 $snippet = $this->get_ad_snippet( $section_id, $height, $width, $spot, self::$SOLO_UNIT_CSS );
452 if ( $this->option( 'wordads_second_belowpost', true ) ) {
453 $section_id2 = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID2 : $this->params->blog_id . '4';
454 $snippet .= $this->get_ad_snippet( $section_id2, $height, $width, $spot . '2', 'float:left;margin-top:0px;' );
455 }
456 } elseif ( 'inline' === $spot ) {
457 $section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '5';
458 $snippet = $this->get_ad_snippet( $section_id, $height, $width, $spot, self::$SOLO_UNIT_CSS );
459 }
460 } elseif ( 'house' == $type ) {
461 $leaderboard = 'top' == $spot && ! $this->params->mobile_device;
462 $snippet = $this->get_house_ad( $leaderboard ? 'leaderboard' : 'mrec' );
463 if ( 'belowpost' == $spot && $this->option( 'wordads_second_belowpost', true ) ) {
464 $snippet .= $this->get_house_ad( $leaderboard ? 'leaderboard' : 'mrec' );
465 }
466 }
467
468 return $this->get_ad_div( $spot, $snippet );
469 }
470
471
472 /**
473 * Returns the snippet to be inserted into the ad unit
474 *
475 * @param int $section_id
476 * @param int $height
477 * @param int $width
478 * @param int $location
479 * @param string $css
480 * @return string
481 *
482 * @since 5.7
483 */
484 function get_ad_snippet( $section_id, $height, $width, $location = '', $css = '' ) {
485 $this->ads[] = array(
486 'location' => $location,
487 'width' => $width,
488 'height' => $height,
489 );
490 $ad_number = count( $this->ads ) . '-' . uniqid();
491
492 $data_tags = $this->params->cloudflare ? ' data-cfasync="false"' : '';
493 $css = esc_attr( $css );
494
495 $loc_id = 100;
496 if ( ! empty( self::$ad_location_ids[ $location ] ) ) {
497 $loc_id = self::$ad_location_ids[ $location ];
498 }
499
500 return <<<HTML
501 <div style="padding-bottom:15px;width:{$width}px;height:{$height}px;$css">
502 <div id="atatags-{$ad_number}">
503 <script$data_tags type="text/javascript">
504 __ATA.cmd.push(function() {
505 __ATA.initSlot('atatags-{$ad_number}', {
506 collapseEmpty: 'before',
507 sectionId: '{$section_id}',
508 location: {$loc_id},
509 width: {$width},
510 height: {$height}
511 });
512 });
513 </script>
514 </div>
515 </div>
516 HTML;
517 }
518
519 /**
520 * Returns the complete ad div with snippet to be inserted into the page
521 *
522 * @param string $spot top, side, inline, or belowpost
523 * @param string $snippet The snippet to insert into the div
524 * @param array $css_classes
525 * @return string The supporting ad unit div
526 *
527 * @since 7.1
528 */
529 function get_ad_div( $spot, $snippet, array $css_classes = array() ) {
530 if ( empty( $css_classes ) ) {
531 $css_classes = array();
532 }
533
534 $css_classes[] = 'wpcnt';
535 if ( 'top' == $spot ) {
536 $css_classes[] = 'wpcnt-header';
537 }
538
539 $spot = esc_attr( $spot );
540 $classes = esc_attr( implode( ' ', $css_classes ) );
541 $about = esc_html__( 'Advertisements', 'jetpack' );
542 return <<<HTML
543 <div class="$classes">
544 <div class="wpa">
545 <span class="wpa-about">$about</span>
546 <div class="u $spot">
547 $snippet
548 </div>
549 </div>
550 </div>
551 HTML;
552 }
553
554 /**
555 * Check the reasons to bail before we attempt to insert ads.
556 *
557 * @return true if we should bail (don't insert ads)
558 *
559 * @since 4.5.0
560 */
561 public function should_bail() {
562 return ! $this->option( 'wordads_approved' ) || (bool) $this->option( 'wordads_unsafe' );
563 }
564
565 /**
566 * Returns markup for HTML5 house ad base on unit
567 *
568 * @param string $unit mrec, widesky, or leaderboard
569 * @return string markup for HTML5 house ad
570 *
571 * @since 4.7.0
572 */
573 public function get_house_ad( $unit = 'mrec' ) {
574
575 switch ( $unit ) {
576 case 'widesky':
577 $width = 160;
578 $height = 600;
579 break;
580 case 'leaderboard':
581 $width = 728;
582 $height = 90;
583 break;
584 case 'mrec':
585 default:
586 $width = 300;
587 $height = 250;
588 break;
589 }
590
591 return <<<HTML
592 <iframe
593 src="https://s0.wp.com/wp-content/blog-plugins/wordads/house/html5/$unit/index.html"
594 width="$width"
595 height="$height"
596 frameborder="0"
597 scrolling="no"
598 marginheight="0"
599 marginwidth="0">
600 </iframe>
601 HTML;
602 }
603
604 /**
605 * Activation hook actions
606 *
607 * @since 4.5.0
608 */
609 public static function activate() {
610 WordAds_API::update_wordads_status_from_api();
611 }
612 }
613
614 add_action( 'jetpack_activate_module_wordads', array( 'WordAds', 'activate' ) );
615 add_action( 'jetpack_activate_module_wordads', array( 'WordAds_Cron', 'activate' ) );
616 add_action( 'jetpack_deactivate_module_wordads', array( 'WordAds_Cron', 'deactivate' ) );
617
618 global $wordads;
619 $wordads = new WordAds();
620