Completed
Push — branch-6.1 ( 682175...e7ecab )
by
unknown
18:28 queued 08:25
created

WordAds::is_infinite_scroll()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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