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