Completed
Push — add/plugin-search-hints ( 43e333...e2b502 )
by
unknown
06:49
created

WordAds::get_ad()   D

Complexity

Conditions 19
Paths 44

Size

Total Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 19
nc 44
nop 2
dl 0
loc 51
rs 4.5166
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
		add_filter( 'wordads_ads_txt', array( $this, 'insert_custom_adstxt' ) );
144
145
		/**
146
		 * Filters enabling ads in `the_content` filter
147
		 *
148
		 * @see https://jetpack.com/support/ads/
149
		 *
150
		 * @module wordads
151
		 *
152
		 * @since 5.8.0
153
		 *
154
		 * @param bool True to disable ads in `the_content`
155
		 */
156
		if ( ! apply_filters( 'wordads_content_disable', false ) ) {
157
			add_filter( 'the_content', array( $this, 'insert_ad' ) );
158
		}
159
160
		/**
161
		 * Filters enabling ads in `the_excerpt` filter
162
		 *
163
		 * @see https://jetpack.com/support/ads/
164
		 *
165
		 * @module wordads
166
		 *
167
		 * @since 5.8.0
168
		 *
169
		 * @param bool True to disable ads in `the_excerpt`
170
		 */
171
		if ( ! apply_filters( 'wordads_excerpt_disable', false ) ) {
172
			add_filter( 'the_excerpt', array( $this, 'insert_ad' ) );
173
		}
174
175
		if ( $this->option( 'enable_header_ad', true ) ) {
176
			switch ( get_stylesheet() ) {
177
				case 'twentyseventeen':
178
				case 'twentyfifteen':
179
				case 'twentyfourteen':
180
					add_action( 'wp_footer', array( $this, 'insert_header_ad_special' ) );
181
					break;
182
				default:
183
					add_action( 'wp_head', array( $this, 'insert_header_ad' ), 100 );
184
					break;
185
			}
186
		}
187
	}
188
189
	/**
190
	 * Register desktop scripts and styles
191
	 *
192
	 * @since 4.5.0
193
	 */
194
	function enqueue_scripts() {
195
		wp_enqueue_style(
196
			'wordads',
197
			WORDADS_URL . 'css/style.css',
198
			array(),
199
			'2015-12-18'
200
		);
201
	}
202
203
	/**
204
	 * IPONWEB metadata used by the various scripts
205
	 *
206
	 * @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...
207
	 */
208
	function insert_head_meta() {
209
		$themename = esc_js( get_stylesheet() );
210
		$pagetype  = intval( $this->params->get_page_type_ipw() );
211
		$data_tags = ( $this->params->cloudflare ) ? ' data-cfasync="false"' : '';
212
		$site_id   = $this->params->blog_id;
213
		$consent   = intval( isset( $_COOKIE['personalized-ads-consent'] ) );
214
		echo <<<HTML
215
		<script$data_tags type="text/javascript">
216
			var __ATA_PP = { pt: $pagetype, ht: 2, tn: '$themename', amp: false, siteid: $site_id, consent: $consent };
217
			var __ATA = __ATA || {};
218
			__ATA.cmd = __ATA.cmd || [];
219
			__ATA.criteo = __ATA.criteo || {};
220
			__ATA.criteo.cmd = __ATA.criteo.cmd || [];
221
		</script>
222
HTML;
223
	}
224
225
	/**
226
	 * IPONWEB scripts in <head>
227
	 *
228
	 * @since 4.5.0
229
	 */
230
	function insert_head_iponweb() {
231
		$data_tags = ( $this->params->cloudflare ) ? ' data-cfasync="false"' : '';
232
		echo <<<HTML
233
		<link rel='dns-prefetch' href='//s.pubmine.com' />
234
		<link rel='dns-prefetch' href='//x.bidswitch.net' />
235
		<link rel='dns-prefetch' href='//static.criteo.net' />
236
		<link rel='dns-prefetch' href='//ib.adnxs.com' />
237
		<link rel='dns-prefetch' href='//aax.amazon-adsystem.com' />
238
		<link rel='dns-prefetch' href='//bidder.criteo.com' />
239
		<link rel='dns-prefetch' href='//cas.criteo.com' />
240
		<link rel='dns-prefetch' href='//gum.criteo.com' />
241
		<link rel='dns-prefetch' href='//ads.pubmatic.com' />
242
		<link rel='dns-prefetch' href='//gads.pubmatic.com' />
243
		<link rel='dns-prefetch' href='//tpc.googlesyndication.com' />
244
		<link rel='dns-prefetch' href='//ad.doubleclick.net' />
245
		<link rel='dns-prefetch' href='//googleads.g.doubleclick.net' />
246
		<link rel='dns-prefetch' href='//www.googletagservices.com' />
247
		<script$data_tags async type="text/javascript" src="//s.pubmine.com/head.js"></script>
248
HTML;
249
	}
250
251
	/**
252
	 * Insert the ad onto the page
253
	 *
254
	 * @since 4.5.0
255
	 */
256
	function insert_ad( $content ) {
257
		// Don't insert ads in feeds, or for anything but the main display. (This is required for compatibility with the Publicize module).
258
		if ( is_feed() || ! is_main_query() || ! in_the_loop() ) {
259
			return $content;
260
		}
261
		/**
262
		 * Allow third-party tools to disable the display of in post ads.
263
		 *
264
		 * @module wordads
265
		 *
266
		 * @since 4.5.0
267
		 *
268
		 * @param bool true Should the in post unit be disabled. Default to false.
269
		 */
270
		$disable = apply_filters( 'wordads_inpost_disable', false );
271
		if ( ! $this->params->should_show() || $disable ) {
272
			return $content;
273
		}
274
275
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
276
		return $content . $this->get_ad( 'belowpost', $ad_type );
277
	}
278
279
	/**
280
	 * Insert an inline ad into a post content
281
	 * Used for rendering the `wordads` shortcode.
282
	 *
283
	 * @since 6.1.0
284
	 */
285
	function insert_inline_ad( $content ) {
286
		// Ad JS won't work in XML feeds.
287
		if ( is_feed() ) {
288
			return $content;
289
		}
290
		/**
291
		 * Allow third-party tools to disable the display of in post ads.
292
		 *
293
		 * @module wordads
294
		 *
295
		 * @since 4.5.0
296
		 *
297
		 * @param bool true Should the in post unit be disabled. Default to false.
298
		 */
299
		$disable = apply_filters( 'wordads_inpost_disable', false );
300
		if ( $disable ) {
301
			return $content;
302
		}
303
304
		$ad_type  = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
305
		$content .= $this->get_ad( 'inline', $ad_type );
306
		return $content;
307
	}
308
309
	/**
310
	 * Inserts ad into header
311
	 *
312
	 * @since 4.5.0
313
	 */
314
	function insert_header_ad() {
315
		/**
316
		 * Allow third-party tools to disable the display of header ads.
317
		 *
318
		 * @module wordads
319
		 *
320
		 * @since 4.5.0
321
		 *
322
		 * @param bool true Should the header unit be disabled. Default to false.
323
		 */
324
		if ( apply_filters( 'wordads_header_disable', false ) ) {
325
			return;
326
		}
327
328
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
329
		echo $this->get_ad( 'top', $ad_type );
330
	}
331
332
	/**
333
	 * Special cases for inserting header unit via jQuery
334
	 *
335
	 * @since 4.5.0
336
	 */
337
	function insert_header_ad_special() {
338
		/**
339
		 * Allow third-party tools to disable the display of header ads.
340
		 *
341
		 * @module wordads
342
		 *
343
		 * @since 4.5.0
344
		 *
345
		 * @param bool true Should the header unit be disabled. Default to false.
346
		 */
347
		if ( apply_filters( 'wordads_header_disable', false ) ) {
348
			return;
349
		}
350
351
		$selector = '#content';
352
		switch ( get_stylesheet() ) {
353
			case 'twentyseventeen':
354
				$selector = '#content';
355
				break;
356
			case 'twentyfifteen':
357
				$selector = '#main';
358
				break;
359
			case 'twentyfourteen':
360
				$selector = 'article:first';
361
				break;
362
		}
363
364
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
365
		echo $this->get_ad( 'top', $ad_type );
366
		echo <<<HTML
367
		<script type="text/javascript">
368
			jQuery('.wpcnt-header').insertBefore('$selector');
369
		</script>
370
HTML;
371
	}
372
373
	/**
374
	 * Filter the latest ads.txt to include custom user entries. Strips any tags or whitespace.
375
	 *
376
	 * @param  string $adstxt The ads.txt being filtered
377
	 * @return string         Filtered ads.txt with custom entries, if applicable
378
	 *
379
	 * @since 6.5.0
380
	 */
381
	function insert_custom_adstxt( $adstxt ) {
382
		$custom_adstxt = trim( wp_strip_all_tags( $this->option( 'wordads_custom_adstxt' ) ) );
383
		if ( $custom_adstxt ) {
384
			$adstxt .= "\n\n#Jetpack - User Custom Entries\n";
385
			$adstxt .= $custom_adstxt . "\n";
386
		}
387
388
		return $adstxt;
389
	}
390
391
	/**
392
	 * Get the ad for the spot and type.
393
	 *
394
	 * @param  string $spot top, side, inline, or belowpost
395
	 * @param  string $type iponweb or adsense
396
	 */
397
	function get_ad( $spot, $type = 'iponweb' ) {
398
		$snippet = '';
399
		if ( 'iponweb' == $type ) {
400
			// Default to mrec
401
			$width  = 300;
402
			$height = 250;
403
404
			$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...
405
			$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...
406
			$snippet          = '';
407
			if ( 'top' == $spot ) {
408
				// mrec for mobile, leaderboard for desktop
409
				$section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '2';
410
				$width      = $this->params->mobile_device ? 300 : 728;
411
				$height     = $this->params->mobile_device ? 250 : 90;
412
				$snippet    = $this->get_ad_snippet( $section_id, $height, $width, $spot );
413
			} elseif ( 'belowpost' == $spot ) {
414
				$section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '1';
415
				$width      = 300;
416
				$height     = 250;
417
418
				$snippet = $this->get_ad_snippet( $section_id, $height, $width, $spot, 'float:left;margin-right:5px;margin-top:0px;' );
419
				if ( $this->option( 'wordads_second_belowpost', true ) ) {
420
					$section_id2 = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID2 : $this->params->blog_id . '4';
421
					$snippet    .= $this->get_ad_snippet( $section_id2, $height, $width, $spot, 'float:left;margin-top:0px;' );
422
				}
423
			} elseif ( 'inline' === $spot ) {
424
				$section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '5';
425
				$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...
426
			}
427
		} elseif ( 'house' == $type ) {
428
			$leaderboard = 'top' == $spot && ! $this->params->mobile_device;
429
			$snippet     = $this->get_house_ad( $leaderboard ? 'leaderboard' : 'mrec' );
430
			if ( 'belowpost' == $spot && $this->option( 'wordads_second_belowpost', true ) ) {
431
				$snippet .= $this->get_house_ad( $leaderboard ? 'leaderboard' : 'mrec' );
432
			}
433
		}
434
435
		$header = 'top' == $spot ? 'wpcnt-header' : '';
436
		$about  = __( 'Advertisements', 'jetpack' );
437
		return <<<HTML
438
		<div class="wpcnt $header">
439
			<div class="wpa">
440
				<span class="wpa-about">$about</span>
441
				<div class="u $spot">
442
					$snippet
443
				</div>
444
			</div>
445
		</div>
446
HTML;
447
	}
448
449
450
	/**
451
	 * Returns the snippet to be inserted into the ad unit
452
	 *
453
	 * @param  int    $section_id
454
	 * @param  int    $height
455
	 * @param  int    $width
456
	 * @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...
457
	 * @param  string $css
458
	 * @return string
459
	 *
460
	 * @since 5.7
461
	 */
462
	function get_ad_snippet( $section_id, $height, $width, $location = '', $css = '' ) {
463
		$this->ads[] = array(
464
			'location' => $location,
465
			'width'    => $width,
466
			'height'   => $height,
467
		);
468
		$ad_number   = count( $this->ads );
469
		// Max 6 ads per page.
470
		if ( $ad_number > 5 && 'top' !== $location ) {
471
			return;
472
		}
473
		$data_tags = $this->params->cloudflare ? ' data-cfasync="false"' : '';
474
475
		return <<<HTML
476
		<div style="padding-bottom:15px;width:{$width}px;height:{$height}px;$css">
477
			<div id="atatags-{$ad_number}">
478
				<script$data_tags type="text/javascript">
479
				__ATA.cmd.push(function() {
480
					__ATA.initSlot('atatags-{$ad_number}',  {
481
						collapseEmpty: 'before',
482
						sectionId: '{$section_id}',
483
						location: '{$location}',
484
						width: {$width},
485
						height: {$height}
486
					});
487
				});
488
				</script>
489
			</div>
490
		</div>
491
HTML;
492
	}
493
494
	/**
495
	 * Check the reasons to bail before we attempt to insert ads.
496
	 *
497
	 * @return true if we should bail (don't insert ads)
498
	 *
499
	 * @since 4.5.0
500
	 */
501
	public function should_bail() {
502
		return ! $this->option( 'wordads_approved' ) || (bool) $this->option( 'wordads_unsafe' );
503
	}
504
505
	/**
506
	 * Returns markup for HTML5 house ad base on unit
507
	 *
508
	 * @param  string $unit mrec, widesky, or leaderboard
509
	 * @return string       markup for HTML5 house ad
510
	 *
511
	 * @since 4.7.0
512
	 */
513
	public function get_house_ad( $unit = 'mrec' ) {
514
515
		switch ( $unit ) {
516
			case 'widesky':
517
				$width  = 160;
518
				$height = 600;
519
				break;
520
			case 'leaderboard':
521
				$width  = 728;
522
				$height = 90;
523
				break;
524
			case 'mrec':
525
			default:
526
				$width  = 300;
527
				$height = 250;
528
				break;
529
		}
530
531
		return <<<HTML
532
		<iframe
533
			src="https://s0.wp.com/wp-content/blog-plugins/wordads/house/html5/$unit/index.html"
534
			width="$width"
535
			height="$height"
536
			frameborder="0"
537
			scrolling="no"
538
			marginheight="0"
539
			marginwidth="0">
540
		</iframe>
541
HTML;
542
	}
543
544
	/**
545
	 * Activation hook actions
546
	 *
547
	 * @since 4.5.0
548
	 */
549
	public static function activate() {
550
		WordAds_API::update_wordads_status_from_api();
551
	}
552
}
553
554
add_action( 'jetpack_activate_module_wordads', array( 'WordAds', 'activate' ) );
555
add_action( 'jetpack_activate_module_wordads', array( 'WordAds_Cron', 'activate' ) );
556
add_action( 'jetpack_deactivate_module_wordads', array( 'WordAds_Cron', 'deactivate' ) );
557
558
global $wordads;
559
$wordads = new WordAds();
560