Completed
Push — update/remove-omni-search-test... ( 6db49e...ed8043 )
by
unknown
30:51 queued 20:39
created

WordAds::get_ad_snippet()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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