Completed
Push — add/wordads-shortcode ( 912e41...566c8f )
by
unknown
08:34
created

WordAds::insert_inline_ad()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 9

Duplication

Lines 23
Ratio 100 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 4
nop 1
dl 23
loc 23
rs 8.7972
c 0
b 0
f 0
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
	 * The different supported ad types.
22
	 * v0.1 - mrec only for now
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
	 * @param  string $option the option to grab
51
	 * @param  mixed  $default (optional)
52
	 * @return option or $default if not set
53
	 *
54
	 * @since 4.5.0
55
	 */
56
	function option( $option, $default = false ) {
57
		if ( ! isset( $this->params->options[ $option ] ) ) {
58
			return $default;
59
		}
60
61
		return $this->params->options[ $option ];
62
	}
63
64
	/**
65
	 * Instantiate the plugin
66
	 *
67
	 * @since 4.5.0
68
	 */
69
	function __construct() {
70
		add_action( 'init', array( $this, 'init' ) );
71
	}
72
73
	/**
74
	 * Code to run on WordPress 'init' hook
75
	 *
76
	 * @since 4.5.0
77
	 */
78
	function init() {
79
		// bail on infinite scroll
80
		if ( self::is_infinite_scroll() ) {
81
			return;
82
		}
83
84
		require_once( WORDADS_ROOT . '/php/params.php' );
85
		$this->params = new WordAds_Params();
86
87
		if ( is_admin() ) {
88
			require_once( WORDADS_ROOT . '/php/admin.php' );
89
			return;
90
		}
91
92
		if ( $this->should_bail() ) {
93
			return;
94
		}
95
96
		$this->insert_adcode();
97
	}
98
99
	/**
100
	 * Check for Jetpack's The_Neverending_Home_Page and use got_infinity
101
	 * @return boolean true if load came from infinite scroll
102
	 *
103
	 * @since 4.5.0
104
	 */
105
	public static function is_infinite_scroll() {
106
		return class_exists( 'The_Neverending_Home_Page' ) && The_Neverending_Home_Page::got_infinity();
107
	}
108
109
	/**
110
	 * Add the actions/filters to insert the ads. Checks for mobile or desktop.
111
	 *
112
	 * @since 4.5.0
113
	 */
114
	private function insert_adcode() {
115
		add_action( 'wp_head', array( $this, 'insert_head_meta' ), 20 );
116
		add_action( 'wp_head', array( $this, 'insert_head_iponweb' ), 30 );
117
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
118
119
		/**
120
		 * Filters enabling ads in `the_content` filter
121
		 *
122
		 * @see https://jetpack.com/support/ads/
123
		 *
124
		 * @module wordads
125
		 *
126
		 * @since 5.8.0
127
		 *
128
		 * @param bool True to disable ads in `the_content`
129
		 */
130
		if ( ! apply_filters( 'wordads_content_disable', false ) ) {
131
			add_filter( 'the_content', array( $this, 'insert_ad' ) );
132
		}
133
134
		/**
135
		 * Filters enabling ads in `the_excerpt` filter
136
		 *
137
		 * @see https://jetpack.com/support/ads/
138
		 *
139
		 * @module wordads
140
		 *
141
		 * @since 5.8.0
142
		 *
143
		 * @param bool True to disable ads in `the_excerpt`
144
		 */
145
		if ( ! apply_filters( 'wordads_excerpt_disable', false ) ) {
146
			add_filter( 'the_excerpt', array( $this, 'insert_ad' ) );
147
		}
148
149
		if ( $this->option( 'enable_header_ad', true ) ) {
150
			switch ( get_stylesheet() ) {
151
				case 'twentyseventeen':
152
				case 'twentyfifteen':
153
				case 'twentyfourteen':
154
					add_action( 'wp_footer', array( $this, 'insert_header_ad_special' ) );
155
					break;
156
				default:
157
					add_action( 'wp_head', array( $this, 'insert_header_ad' ), 100 );
158
					break;
159
			}
160
		}
161
	}
162
163
	/**
164
	 * Register desktop scripts and styles
165
	 *
166
	 * @since 4.5.0
167
	 */
168
	function enqueue_scripts() {
169
		wp_enqueue_style(
170
			'wordads',
171
			WORDADS_URL . 'css/style.css',
172
			array(),
173
			'2015-12-18'
174
		);
175
	}
176
177
	/**
178
	 * IPONWEB metadata used by the various scripts
179
	 * @return [type] [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
180
	 */
181
	function insert_head_meta() {
182
		$themename = esc_js( get_stylesheet() );
183
		$pagetype = intval( $this->params->get_page_type_ipw() );
184
		$data_tags = ( $this->params->cloudflare ) ? ' data-cfasync="false"' : '';
185
		$site_id = $this->params->blog_id;
186
		echo <<<HTML
187
		<script$data_tags type="text/javascript">
188
			var __ATA_PP = { pt: $pagetype, ht: 2, tn: '$themename', amp: false, siteid: $site_id };
189
			var __ATA = __ATA || {};
190
			__ATA.cmd = __ATA.cmd || [];
191
			__ATA.criteo = __ATA.criteo || {};
192
			__ATA.criteo.cmd = __ATA.criteo.cmd || [];
193
		</script>
194
HTML;
195
	}
196
197
	/**
198
	 * IPONWEB scripts in <head>
199
	 *
200
	 * @since 4.5.0
201
	 */
202
	function insert_head_iponweb() {
203
		$data_tags = ( $this->params->cloudflare ) ? ' data-cfasync="false"' : '';
204
		echo <<<HTML
205
		<link rel='dns-prefetch' href='//s.pubmine.com' />
206
		<link rel='dns-prefetch' href='//x.bidswitch.net' />
207
		<link rel='dns-prefetch' href='//static.criteo.net' />
208
		<link rel='dns-prefetch' href='//ib.adnxs.com' />
209
		<link rel='dns-prefetch' href='//aax.amazon-adsystem.com' />
210
		<link rel='dns-prefetch' href='//bidder.criteo.com' />
211
		<link rel='dns-prefetch' href='//cas.criteo.com' />
212
		<link rel='dns-prefetch' href='//gum.criteo.com' />
213
		<link rel='dns-prefetch' href='//ads.pubmatic.com' />
214
		<link rel='dns-prefetch' href='//gads.pubmatic.com' />
215
		<link rel='dns-prefetch' href='//tpc.googlesyndication.com' />
216
		<link rel='dns-prefetch' href='//ad.doubleclick.net' />
217
		<link rel='dns-prefetch' href='//googleads.g.doubleclick.net' />
218
		<link rel='dns-prefetch' href='//www.googletagservices.com' />
219
		<link rel='dns-prefetch' href='//cdn.switchadhub.com' />
220
		<link rel='dns-prefetch' href='//delivery.g.switchadhub.com' />
221
		<link rel='dns-prefetch' href='//delivery.swid.switchadhub.com' />
222
		<script$data_tags async type="text/javascript" src="//s.pubmine.com/head.js"></script>
223
HTML;
224
	}
225
226
	/**
227
	 * Insert the ad onto the page
228
	 *
229
	 * @since 4.5.0
230
	 */
231 View Code Duplication
	function insert_ad( $content ) {
232
		// Ad JS won't work in XML feeds.
233
		if ( is_feed() ) {
234
			return $content;
235
		}
236
		/**
237
		 * Allow third-party tools to disable the display of in post ads.
238
		 *
239
		 * @module wordads
240
		 *
241
		 * @since 4.5.0
242
		 *
243
		 * @param bool true Should the in post unit be disabled. Default to false.
244
		 */
245
		$disable = apply_filters( 'wordads_inpost_disable', false );
246
		if ( ! $this->params->should_show() || $disable ) {
247
			return $content;
248
		}
249
250
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
251
		return $content . $this->get_ad( 'belowpost', $ad_type );
252
	}
253
254
	/**
255
	 * Insert an inline ad into a post content
256
	 * Used for rendering the `wordad` shortcode.
257
	 *
258
	 * @since 6.1.0
259
	 */
260 View Code Duplication
	function insert_inline_ad( $content ) {
261
		// Ad JS won't work in XML feeds.
262
		if ( is_feed() ) {
263
			return $content;
264
		}
265
		/**
266
		 * Allow third-party tools to disable the display of in post ads.
267
		 *
268
		 * @module wordads
269
		 *
270
		 * @since 4.5.0
271
		 *
272
		 * @param bool true Should the in post unit be disabled. Default to false.
273
		 */
274
		$disable = apply_filters( 'wordads_inpost_disable', false );
275
		if ( $disable ) {
276
			return $content;
277
		}
278
279
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
280
		$content .= $this->get_ad( 'inline', $ad_type );
281
		return $content;
282
	}
283
284
	/**
285
	 * Inserts ad into header
286
	 *
287
	 * @since 4.5.0
288
	 */
289
	function insert_header_ad() {
290
		/**
291
		 * Allow third-party tools to disable the display of header ads.
292
		 *
293
		 * @module wordads
294
		 *
295
		 * @since 4.5.0
296
		 *
297
		 * @param bool true Should the header unit be disabled. Default to false.
298
		 */
299
		if ( apply_filters( 'wordads_header_disable', false ) ) {
300
			return;
301
		}
302
303
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
304
		echo $this->get_ad( 'top', $ad_type );
305
	}
306
307
	/**
308
	 * Special cases for inserting header unit via jQuery
309
	 *
310
	 * @since 4.5.0
311
	 */
312
	function insert_header_ad_special() {
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
		$selector = '#content';
327
		switch ( get_stylesheet() ) {
328
			case 'twentyseventeen':
329
				$selector = '#content';
330
				break;
331
			case 'twentyfifteen':
332
				$selector = '#main';
333
				break;
334
			case 'twentyfourteen':
335
				$selector = 'article:first';
336
				break;
337
		}
338
339
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
340
		echo $this->get_ad( 'top', $ad_type );
341
		echo <<<HTML
342
		<script type="text/javascript">
343
			jQuery('.wpcnt-header').insertBefore('$selector');
344
		</script>
345
HTML;
346
	}
347
348
	/**
349
	 * Get the ad for the spot and type.
350
	 * @param  string $spot top, side, inline, or belowpost
351
	 * @param  string $type iponweb or adsense
352
	 */
353
	function get_ad( $spot, $type = 'iponweb' ) {
354
		$snippet = '';
355
		$blocker_unit = 'mrec';
0 ignored issues
show
Unused Code introduced by
$blocker_unit is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
356
		if ( 'iponweb' == $type ) {
357
			$section_id = WORDADS_API_TEST_ID;
0 ignored issues
show
Unused Code introduced by
$section_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
358
			$width = 300;
359
			$height = 250;
360
			$second_belowpost = '';
0 ignored issues
show
Unused Code introduced by
$second_belowpost is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
361
			$snippet = '';
362
			if ( 'top' == $spot ) {
363
				// mrec for mobile, leaderboard for desktop
364
				$section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '2';
365
				$width = $this->params->mobile_device ? 300 : 728;
366
				$height = $this->params->mobile_device ? 250 : 90;
367
				$blocker_unit = $this->params->mobile_device ? 'top_mrec' : 'top';
368
				$snippet = $this->get_ad_snippet( $section_id, $height, $width, $blocker_unit );
369
			} else if ( 'belowpost' == $spot ) {
370
				$section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '1';
371
				$width = 300;
372
				$height = 250;
373
374
				$snippet = $this->get_ad_snippet( $section_id, $height, $width, 'mrec', 'float:left;margin-right:5px;margin-top:0px;' );
375
				if ( $this->option( 'wordads_second_belowpost', true ) ) {
376
					$section_id2 = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID2 : $this->params->blog_id . '4';
377
					$snippet .= $this->get_ad_snippet( $section_id2, $height, $width, 'mrec2', 'float:left;margin-top:0px;' );
378
				}
379
			} else if ( 'inline' === $spot ) {
380
				$section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID3 : $this->params->blog_id . '3';
381
				$snippet = $this->get_ad_snippet( $section_id, $height, $width, 'mrec', 'float:left;margin-right:5px;margin-top:0px;' );
382
			}
383
		} else if ( 'house' == $type ) {
384
			$leaderboard = 'top' == $spot && ! $this->params->mobile_device;
385
			$snippet = $this->get_house_ad( $leaderboard ? 'leaderboard' : 'mrec' );
386
			if ( 'belowpost' == $spot && $this->option( 'wordads_second_belowpost', true ) ) {
387
				$snippet .= $this->get_house_ad( $leaderboard ? 'leaderboard' : 'mrec' );
388
			}
389
		}
390
391
		$header = 'top' == $spot ? 'wpcnt-header' : '';
392
		$about = __( 'Advertisements', 'jetpack' );
393
		return <<<HTML
394
		<div class="wpcnt $header">
395
			<div class="wpa">
396
				<span class="wpa-about">$about</span>
397
				<div class="u $spot">
398
					$snippet
399
				</div>
400
			</div>
401
		</div>
402
HTML;
403
	}
404
405
406
	/**
407
	 * Returns the snippet to be inserted into the ad unit
408
	 * @param  int $section_id
409
	 * @param  int $height
410
	 * @param  int $width
411
	 * @param  string $css
412
	 * @return string
413
	 *
414
	 * @since 5.7
415
	 */
416
	function get_ad_snippet( $section_id, $height, $width, $adblock_unit = 'mrec', $css = '' ) {
417
		$this->ads[] = array( 'section_id' => $section_id, 'width' => $width, 'height' => $height );
418
		$ad_number = count( $this->ads );
419
		// Max 6 ads per page.
420
		if ( $ad_number > 6 ) {
421
			return;
422
		}
423
		$data_tags = $this->params->cloudflare ? ' data-cfasync="false"' : '';
424
		$adblock_ad = $this->get_adblocker_ad( $adblock_unit );
425
426
		return <<<HTML
427
		<div style="padding-bottom:15px;width:{$width}px;height:{$height}px;$css">
428
			<div id="atatags-{$ad_number}">
429
				<script$data_tags type="text/javascript">
430
				__ATA.cmd.push(function() {
431
					__ATA.initSlot('atatags-{$ad_number}',  {
432
						collapseEmpty: 'before',
433
						sectionId: '{$section_id}',
434
						width: {$width},
435
						height: {$height}
436
					});
437
				});
438
				</script>
439
				$adblock_ad
440
			</div>
441
		</div>
442
HTML;
443
	}
444
445
	/**
446
	 * Get Criteo Acceptable Ad unit
447
	 * @param  string $unit mrec, mrec2, widesky, top, top_mrec
448
	 *
449
	 * @since 5.3
450
	 */
451
	public function get_adblocker_ad( $unit = 'mrec' ) {
452
		$data_tags = $this->params->cloudflare ? ' data-cfasync="false"' : '';
453
		$criteo_id = mt_rand();
454
		$height = 250;
455
		$width = 300;
456
		$zone_id = 388248;
457
		if ( 'mrec2' == $unit ) { // 2nd belowpost
458
			$zone_id = 837497;
459
		} else if ( 'widesky' == $unit ) { // sidebar
460
			$zone_id = 563902;
461
			$width = 160;
462
			$height= 600;
463
		} else if ( 'top' == $unit ) { // top leaderboard
464
			$zone_id = 563903;
465
			$width = 728;
466
			$height = 90;
467
		} else if ( 'top_mrec' == $unit ) { // top mrec
468
			$zone_id = 563903;
469
		}
470
471
		return <<<HTML
472
		<div id="crt-$criteo_id" style="width:{$width}px;height:{$height}px;display:none !important;"></div>
473
		<script$data_tags type="text/javascript">
474
		(function(){var c=function(){var a=document.getElementById("crt-{$criteo_id}");window.Criteo?(a.parentNode.style.setProperty("display","inline-block","important"),a.style.setProperty("display","block","important"),window.Criteo.DisplayAcceptableAdIfAdblocked({zoneid:{$zone_id},containerid:"crt-{$criteo_id}",collapseContainerIfNotAdblocked:!0,callifnotadblocked:function(){a.style.setProperty("display","none","important");a.style.setProperty("visbility","hidden","important")}})):(a.style.setProperty("display","none","important"),a.style.setProperty("visibility","hidden","important"))};if(window.Criteo)c();else{if(!__ATA.criteo.script){var b=document.createElement("script");b.src="//static.criteo.net/js/ld/publishertag.js";b.onload=function(){for(var a=0;a<__ATA.criteo.cmd.length;a++){var b=__ATA.criteo.cmd[a];"function"===typeof b&&b()}};(document.head||document.getElementsByTagName("head")[0]).appendChild(b);__ATA.criteo.script=b}__ATA.criteo.cmd.push(c)}})();
475
		</script>
476
HTML;
477
	}
478
479
	/**
480
	 * Check the reasons to bail before we attempt to insert ads.
481
	 * @return true if we should bail (don't insert ads)
482
	 *
483
	 * @since 4.5.0
484
	 */
485
	public function should_bail() {
486
		return ! $this->option( 'wordads_approved' );
487
	}
488
489
	/**
490
	 * Returns markup for HTML5 house ad base on unit
491
	 * @param  string $unit mrec, widesky, or leaderboard
492
	 * @return string       markup for HTML5 house ad
493
	 *
494
	 * @since 4.7.0
495
	 */
496
	public function get_house_ad( $unit = 'mrec' ) {
497
		if ( ! in_array( $unit, array( 'mrec', 'widesky', 'leaderboard' ) ) ) {
498
			$unit = 'mrec';
499
		}
500
501
		$width  = 300;
502
		$height = 250;
503
		if ( 'widesky' == $unit ) {
504
			$width  = 160;
505
			$height = 600;
506
		} else if ( 'leaderboard' == $unit ) {
507
			$width  = 728;
508
			$height = 90;
509
		}
510
511
		return <<<HTML
512
		<iframe
513
			src="https://s0.wp.com/wp-content/blog-plugins/wordads/house/html5/$unit/index.html"
514
			width="$width"
515
			height="$height"
516
			frameborder="0"
517
			scrolling="no"
518
			marginheight="0"
519
			marginwidth="0">
520
		</iframe>
521
HTML;
522
	}
523
524
	/**
525
	 * Activation hook actions
526
	 *
527
	 * @since 4.5.0
528
	 */
529
	public static function activate() {
530
		WordAds_API::update_wordads_status_from_api();
531
	}
532
}
533
534
add_action( 'jetpack_activate_module_wordads', array( 'WordAds', 'activate' ) );
535
add_action( 'jetpack_activate_module_wordads', array( 'WordAds_Cron', 'activate' ) );
536
add_action( 'jetpack_deactivate_module_wordads', array( 'WordAds_Cron', 'deactivate' ) );
537
538
global $wordads;
539
$wordads = new WordAds();
540