Completed
Push — add/gdpr-ads-compliance ( c52a1e...cda5c5 )
by
unknown
26:32 queued 14:46
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
	 * 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
			$ads_txt_server_contents = ! is_wp_error( WordAds_API::get_wordads_ads_txt() ) ? WordAds_API::get_wordads_ads_txt() : '';
101
102
			/**
103
			 * Provide plugins a way of modifying the contents of the automatically-generated ads.txt file.
104
			 *
105
			 * @module wordads
106
			 *
107
			 * @since 6.1.0
108
			 *
109
			 * @param string WordAds_API::get_wordads_ads_txt() The contents of the ads.txt file.
110
			 */
111
			$ads_txt_content = apply_filters( 'wordads_ads_txt', $ads_txt_server_contents );
112
113
			header( 'Content-Type: text/plain; charset=utf-8' );
114
			echo esc_html( $ads_txt_content );
115
			die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method init() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
116
		}
117
	}
118
119
	/**
120
	 * Check for Jetpack's The_Neverending_Home_Page and use got_infinity
121
	 *
122
	 * @return boolean true if load came from infinite scroll
123
	 *
124
	 * @since 4.5.0
125
	 */
126
	public static function is_infinite_scroll() {
127
		return class_exists( 'The_Neverending_Home_Page' ) && The_Neverending_Home_Page::got_infinity();
128
	}
129
130
	/**
131
	 * Add the actions/filters to insert the ads. Checks for mobile or desktop.
132
	 *
133
	 * @since 4.5.0
134
	 */
135
	private function insert_adcode() {
136
		add_action( 'wp_head',              array( $this, 'insert_head_meta' ), 20 );
137
		add_action( 'wp_head',              array( $this, 'insert_head_iponweb' ), 30 );
138
		add_action( 'wp_enqueue_scripts',   array( $this, 'enqueue_scripts' ) );
139
140
		/**
141
		 * Filters enabling ads in `the_content` filter
142
		 *
143
		 * @see https://jetpack.com/support/ads/
144
		 *
145
		 * @module wordads
146
		 *
147
		 * @since 5.8.0
148
		 *
149
		 * @param bool True to disable ads in `the_content`
150
		 */
151
		if ( ! apply_filters( 'wordads_content_disable', false ) ) {
152
			add_filter( 'the_content', array( $this, 'insert_ad' ) );
153
		}
154
155
		/**
156
		 * Filters enabling ads in `the_excerpt` filter
157
		 *
158
		 * @see https://jetpack.com/support/ads/
159
		 *
160
		 * @module wordads
161
		 *
162
		 * @since 5.8.0
163
		 *
164
		 * @param bool True to disable ads in `the_excerpt`
165
		 */
166
		if ( ! apply_filters( 'wordads_excerpt_disable', false ) ) {
167
			add_filter( 'the_excerpt', array( $this, 'insert_ad' ) );
168
		}
169
170
		if ( $this->option( 'enable_header_ad', true ) ) {
171
			switch ( get_stylesheet() ) {
172
				case 'twentyseventeen':
173
				case 'twentyfifteen':
174
				case 'twentyfourteen':
175
					add_action( 'wp_footer', array( $this, 'insert_header_ad_special' ) );
176
					break;
177
				default:
178
					add_action( 'wp_head', array( $this, 'insert_header_ad' ), 100 );
179
					break;
180
			}
181
		}
182
	}
183
184
	/**
185
	 * Register desktop scripts and styles
186
	 *
187
	 * @since 4.5.0
188
	 */
189
	function enqueue_scripts() {
190
		wp_enqueue_style(
191
			'wordads',
192
			WORDADS_URL . 'css/style.css',
193
			array(),
194
			'2015-12-18'
195
		);
196
	}
197
198
	/**
199
	 * IPONWEB metadata used by the various scripts
200
	 * @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...
201
	 */
202
	function insert_head_meta() {
203
		$themename = esc_js( get_stylesheet() );
204
		$pagetype = intval( $this->params->get_page_type_ipw() );
205
		$data_tags = ( $this->params->cloudflare ) ? ' data-cfasync="false"' : '';
206
		$site_id = $this->params->blog_id;
207
		$consent = isset( $_COOKIE['personalized-ads-consent'] );
208
		echo <<<HTML
209
		<script$data_tags type="text/javascript">
210
			var __ATA_PP = { pt: $pagetype, ht: 2, tn: '$themename', amp: false, siteid: $site_id, consent: $consent };
211
			var __ATA = __ATA || {};
212
			__ATA.cmd = __ATA.cmd || [];
213
			__ATA.criteo = __ATA.criteo || {};
214
			__ATA.criteo.cmd = __ATA.criteo.cmd || [];
215
		</script>
216
HTML;
217
	}
218
219
	/**
220
	 * IPONWEB scripts in <head>
221
	 *
222
	 * @since 4.5.0
223
	 */
224
	function insert_head_iponweb() {
225
		$data_tags = ( $this->params->cloudflare ) ? ' data-cfasync="false"' : '';
226
		echo <<<HTML
227
		<link rel='dns-prefetch' href='//s.pubmine.com' />
228
		<link rel='dns-prefetch' href='//x.bidswitch.net' />
229
		<link rel='dns-prefetch' href='//static.criteo.net' />
230
		<link rel='dns-prefetch' href='//ib.adnxs.com' />
231
		<link rel='dns-prefetch' href='//aax.amazon-adsystem.com' />
232
		<link rel='dns-prefetch' href='//bidder.criteo.com' />
233
		<link rel='dns-prefetch' href='//cas.criteo.com' />
234
		<link rel='dns-prefetch' href='//gum.criteo.com' />
235
		<link rel='dns-prefetch' href='//ads.pubmatic.com' />
236
		<link rel='dns-prefetch' href='//gads.pubmatic.com' />
237
		<link rel='dns-prefetch' href='//tpc.googlesyndication.com' />
238
		<link rel='dns-prefetch' href='//ad.doubleclick.net' />
239
		<link rel='dns-prefetch' href='//googleads.g.doubleclick.net' />
240
		<link rel='dns-prefetch' href='//www.googletagservices.com' />
241
		<script$data_tags async type="text/javascript" src="//s.pubmine.com/head.js"></script>
242
HTML;
243
	}
244
245
	/**
246
	 * Insert the ad onto the page
247
	 *
248
	 * @since 4.5.0
249
	 */
250 View Code Duplication
	function insert_ad( $content ) {
251
		// Ad JS won't work in XML feeds.
252
		if ( is_feed() ) {
253
			return $content;
254
		}
255
		/**
256
		 * Allow third-party tools to disable the display of in post ads.
257
		 *
258
		 * @module wordads
259
		 *
260
		 * @since 4.5.0
261
		 *
262
		 * @param bool true Should the in post unit be disabled. Default to false.
263
		 */
264
		$disable = apply_filters( 'wordads_inpost_disable', false );
265
		if ( ! $this->params->should_show() || $disable ) {
266
			return $content;
267
		}
268
269
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
270
		return $content . $this->get_ad( 'belowpost', $ad_type );
271
	}
272
273
	/**
274
	 * Insert an inline ad into a post content
275
	 * Used for rendering the `wordads` shortcode.
276
	 *
277
	 * @since 6.1.0
278
	 */
279 View Code Duplication
	function insert_inline_ad( $content ) {
280
		// Ad JS won't work in XML feeds.
281
		if ( is_feed() ) {
282
			return $content;
283
		}
284
		/**
285
		 * Allow third-party tools to disable the display of in post ads.
286
		 *
287
		 * @module wordads
288
		 *
289
		 * @since 4.5.0
290
		 *
291
		 * @param bool true Should the in post unit be disabled. Default to false.
292
		 */
293
		$disable = apply_filters( 'wordads_inpost_disable', false );
294
		if ( $disable ) {
295
			return $content;
296
		}
297
298
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
299
		$content .= $this->get_ad( 'inline', $ad_type );
300
		return $content;
301
	}
302
303
	/**
304
	 * Inserts ad into header
305
	 *
306
	 * @since 4.5.0
307
	 */
308
	function insert_header_ad() {
309
		/**
310
		 * Allow third-party tools to disable the display of header ads.
311
		 *
312
		 * @module wordads
313
		 *
314
		 * @since 4.5.0
315
		 *
316
		 * @param bool true Should the header unit be disabled. Default to false.
317
		 */
318
		if ( apply_filters( 'wordads_header_disable', false ) ) {
319
			return;
320
		}
321
322
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
323
		echo $this->get_ad( 'top', $ad_type );
324
	}
325
326
	/**
327
	 * Special cases for inserting header unit via jQuery
328
	 *
329
	 * @since 4.5.0
330
	 */
331
	function insert_header_ad_special() {
332
		/**
333
		 * Allow third-party tools to disable the display of header ads.
334
		 *
335
		 * @module wordads
336
		 *
337
		 * @since 4.5.0
338
		 *
339
		 * @param bool true Should the header unit be disabled. Default to false.
340
		 */
341
		if ( apply_filters( 'wordads_header_disable', false ) ) {
342
			return;
343
		}
344
345
		$selector = '#content';
346
		switch ( get_stylesheet() ) {
347
			case 'twentyseventeen':
348
				$selector = '#content';
349
				break;
350
			case 'twentyfifteen':
351
				$selector = '#main';
352
				break;
353
			case 'twentyfourteen':
354
				$selector = 'article:first';
355
				break;
356
		}
357
358
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
359
		echo $this->get_ad( 'top', $ad_type );
360
		echo <<<HTML
361
		<script type="text/javascript">
362
			jQuery('.wpcnt-header').insertBefore('$selector');
363
		</script>
364
HTML;
365
	}
366
367
	/**
368
	 * Get the ad for the spot and type.
369
	 * @param  string $spot top, side, inline, or belowpost
370
	 * @param  string $type iponweb or adsense
371
	 */
372
	function get_ad( $spot, $type = 'iponweb' ) {
373
		$snippet = '';
374
		if ( 'iponweb' == $type ) {
375
			// Default to mrec
376
			$width = 300;
377
			$height = 250;
378
379
			$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...
380
			$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...
381
			$snippet = '';
382
			if ( 'top' == $spot ) {
383
				// mrec for mobile, leaderboard for desktop
384
				$width = $this->params->mobile_device ? 300 : 728;
385
				$height = $this->params->mobile_device ? 250 : 90;
386
				$snippet = $this->get_ad_snippet( $height, $width, $spot );
387
			} else if ( 'belowpost' == $spot ) {
388
				$width = 300;
389
				$height = 250;
390
391
				$snippet = $this->get_ad_snippet( $height, $width, $spot, 'float:left;margin-right:5px;margin-top:0px;' );
392
				if ( $this->option( 'wordads_second_belowpost', true ) ) {
393
					$snippet .= $this->get_ad_snippet( $height, $width, $spot, 'float:left;margin-top:0px;' );
394
				}
395
			} else if ( 'inline' === $spot ) {
396
				$snippet = $this->get_ad_snippet( $height, $width, $spot, 'mrec', 'float:left;margin-right:5px;margin-top:0px;' );
0 ignored issues
show
Unused Code introduced by
The call to WordAds::get_ad_snippet() has too many arguments starting with 'float:left;margin-right:5px;margin-top:0px;'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
397
			}
398
		} else if ( 'house' == $type ) {
399
			$leaderboard = 'top' == $spot && ! $this->params->mobile_device;
400
			$snippet = $this->get_house_ad( $leaderboard ? 'leaderboard' : 'mrec' );
401
			if ( 'belowpost' == $spot && $this->option( 'wordads_second_belowpost', true ) ) {
402
				$snippet .= $this->get_house_ad( $leaderboard ? 'leaderboard' : 'mrec' );
403
			}
404
		}
405
406
		$header = 'top' == $spot ? 'wpcnt-header' : '';
407
		$about = __( 'Advertisements', 'jetpack' );
408
		return <<<HTML
409
		<div class="wpcnt $header">
410
			<div class="wpa">
411
				<span class="wpa-about">$about</span>
412
				<div class="u $spot">
413
					$snippet
414
				</div>
415
			</div>
416
		</div>
417
HTML;
418
	}
419
420
421
	/**
422
	 * Returns the snippet to be inserted into the ad unit
423
	 * @param  int $height
424
	 * @param  int $width
425
	 * @param  int $location
0 ignored issues
show
Documentation introduced by
Should the type for parameter $location not be string|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
426
	 * @param  string $css
427
	 * @return string
428
	 *
429
	 * @since 5.7
430
	 */
431
	function get_ad_snippet( $height, $width, $location = '', $css = '' ) {
432
		$this->ads[] = array( 'location' => $location, 'width' => $width, 'height' => $height );
433
		$ad_number = count( $this->ads );
434
		// Max 6 ads per page.
435
		if ( $ad_number > 5 && 'top' !== $location ) {
436
			return;
437
		}
438
		$data_tags = $this->params->cloudflare ? ' data-cfasync="false"' : '';
439
440
		return <<<HTML
441
		<div style="padding-bottom:15px;width:{$width}px;height:{$height}px;$css">
442
			<div id="atatags-{$ad_number}">
443
				<script$data_tags type="text/javascript">
444
				__ATA.cmd.push(function() {
445
					__ATA.initSlot('atatags-{$ad_number}',  {
446
						collapseEmpty: 'before',
447
						location: '{$location}',
448
						width: {$width},
449
						height: {$height}
450
					});
451
				});
452
				</script>
453
			</div>
454
		</div>
455
HTML;
456
	}
457
458
	/**
459
	 * Check the reasons to bail before we attempt to insert ads.
460
	 * @return true if we should bail (don't insert ads)
461
	 *
462
	 * @since 4.5.0
463
	 */
464
	public function should_bail() {
465
		return ! $this->option( 'wordads_approved' );
466
	}
467
468
	/**
469
	 * Returns markup for HTML5 house ad base on unit
470
	 * @param  string $unit mrec, widesky, or leaderboard
471
	 * @return string       markup for HTML5 house ad
472
	 *
473
	 * @since 4.7.0
474
	 */
475
	public function get_house_ad( $unit = 'mrec' ) {
476
477
		switch ( $unit ) {
478
			case 'widesky':
479
				$width  = 160;
480
				$height = 600;
481
				break;
482
			case 'leaderboard':
483
				$width  = 728;
484
				$height = 90;
485
				break;
486
			case 'mrec':
487
			default:
488
				$width  = 300;
489
				$height = 250;
490
				break;
491
		}
492
493
		return <<<HTML
494
		<iframe
495
			src="https://s0.wp.com/wp-content/blog-plugins/wordads/house/html5/$unit/index.html"
496
			width="$width"
497
			height="$height"
498
			frameborder="0"
499
			scrolling="no"
500
			marginheight="0"
501
			marginwidth="0">
502
		</iframe>
503
HTML;
504
	}
505
506
	/**
507
	 * Activation hook actions
508
	 *
509
	 * @since 4.5.0
510
	 */
511
	public static function activate() {
512
		WordAds_API::update_wordads_status_from_api();
513
	}
514
}
515
516
add_action( 'jetpack_activate_module_wordads', array( 'WordAds', 'activate' ) );
517
add_action( 'jetpack_activate_module_wordads', array( 'WordAds_Cron', 'activate' ) );
518
add_action( 'jetpack_deactivate_module_wordads', array( 'WordAds_Cron', 'deactivate' ) );
519
520
global $wordads;
521
$wordads = new WordAds();
522