Completed
Push — add/changelog-71 ( b70f6c...ac535c )
by Jeremy
10:29
created

WordAds::get_solo_unit_css()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
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
	 * 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
		'leaderboard'        => array(
32
			'tag'    => '728x90_leaderboard',
33
			'height' => '90',
34
			'width'  => '728',
35
		),
36
		'mobile_leaderboard' => array(
37
			'tag'    => '320x50_mobileleaderboard',
38
			'height' => '50',
39
			'width'  => '320',
40
		),
41
		'wideskyscraper'     => array(
42
			'tag'    => '160x600_wideskyscraper',
43
			'height' => '600',
44
			'width'  => '160',
45
		),
46
	);
47
48
	public static $SOLO_UNIT_CSS = 'float:left;margin-right:5px;margin-top:0px;';
49
50
	/**
51
	 * Convenience function for grabbing options from params->options
52
	 *
53
	 * @param  string $option the option to grab
54
	 * @param  mixed  $default (optional)
55
	 * @return option or $default if not set
56
	 *
57
	 * @since 4.5.0
58
	 */
59
	function option( $option, $default = false ) {
60
		if ( ! isset( $this->params->options[ $option ] ) ) {
61
			return $default;
62
		}
63
64
		return $this->params->options[ $option ];
65
	}
66
67
	/**
68
	 * Instantiate the plugin
69
	 *
70
	 * @since 4.5.0
71
	 */
72
	function __construct() {
73
		add_action( 'init', array( $this, 'init' ) );
74
	}
75
76
	/**
77
	 * Code to run on WordPress 'init' hook
78
	 *
79
	 * @since 4.5.0
80
	 */
81
	function init() {
82
		// bail on infinite scroll
83
		if ( self::is_infinite_scroll() ) {
84
			return;
85
		}
86
87
		require_once WORDADS_ROOT . '/php/params.php';
88
		$this->params = new WordAds_Params();
89
90
		if ( is_admin() ) {
91
			require_once WORDADS_ROOT . '/php/admin.php';
92
			return;
93
		}
94
95
		if ( $this->should_bail() ) {
96
			return;
97
		}
98
99
		$this->insert_adcode();
100
101
		if ( '/ads.txt' === $_SERVER['REQUEST_URI'] ) {
102
103
			if ( false === ( $ads_txt_transient = get_transient( 'jetpack_ads_txt' ) ) ) {
104
				$ads_txt_transient = ! is_wp_error( WordAds_API::get_wordads_ads_txt() ) ? WordAds_API::get_wordads_ads_txt() : '';
105
				set_transient( 'jetpack_ads_txt', $ads_txt_transient, DAY_IN_SECONDS );
106
			}
107
108
			/**
109
			 * Provide plugins a way of modifying the contents of the automatically-generated ads.txt file.
110
			 *
111
			 * @module wordads
112
			 *
113
			 * @since 6.1.0
114
			 *
115
			 * @param string WordAds_API::get_wordads_ads_txt() The contents of the ads.txt file.
116
			 */
117
			$ads_txt_content = apply_filters( 'wordads_ads_txt', $ads_txt_transient );
118
119
			header( 'Content-Type: text/plain; charset=utf-8' );
120
			echo esc_html( $ads_txt_content );
121
			die();
122
		}
123
	}
124
125
	/**
126
	 * Check for Jetpack's The_Neverending_Home_Page and use got_infinity
127
	 *
128
	 * @return boolean true if load came from infinite scroll
129
	 *
130
	 * @since 4.5.0
131
	 */
132
	public static function is_infinite_scroll() {
133
		return class_exists( 'The_Neverending_Home_Page' ) && The_Neverending_Home_Page::got_infinity();
134
	}
135
136
	/**
137
	 * Add the actions/filters to insert the ads. Checks for mobile or desktop.
138
	 *
139
	 * @since 4.5.0
140
	 */
141
	private function insert_adcode() {
142
		add_action( 'wp_head', array( $this, 'insert_head_meta' ), 20 );
143
		add_action( 'wp_head', array( $this, 'insert_head_iponweb' ), 30 );
144
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
145
		add_filter( 'wordads_ads_txt', array( $this, 'insert_custom_adstxt' ) );
146
147
		/**
148
		 * Filters enabling ads in `the_content` filter
149
		 *
150
		 * @see https://jetpack.com/support/ads/
151
		 *
152
		 * @module wordads
153
		 *
154
		 * @since 5.8.0
155
		 *
156
		 * @param bool True to disable ads in `the_content`
157
		 */
158
		if ( ! apply_filters( 'wordads_content_disable', false ) ) {
159
			add_filter( 'the_content', array( $this, 'insert_ad' ) );
160
		}
161
162
		/**
163
		 * Filters enabling ads in `the_excerpt` filter
164
		 *
165
		 * @see https://jetpack.com/support/ads/
166
		 *
167
		 * @module wordads
168
		 *
169
		 * @since 5.8.0
170
		 *
171
		 * @param bool True to disable ads in `the_excerpt`
172
		 */
173
		if ( ! apply_filters( 'wordads_excerpt_disable', false ) ) {
174
			add_filter( 'the_excerpt', array( $this, 'insert_ad' ) );
175
		}
176
177
		if ( $this->option( 'enable_header_ad', true ) ) {
178
			switch ( get_stylesheet() ) {
179
				case 'twentyseventeen':
180
				case 'twentyfifteen':
181
				case 'twentyfourteen':
182
					add_action( 'wp_footer', array( $this, 'insert_header_ad_special' ) );
183
					break;
184
				default:
185
					add_action( 'wp_head', array( $this, 'insert_header_ad' ), 100 );
186
					break;
187
			}
188
		}
189
	}
190
191
	/**
192
	 * Register desktop scripts and styles
193
	 *
194
	 * @since 4.5.0
195
	 */
196
	function enqueue_scripts() {
197
		wp_enqueue_style(
198
			'wordads',
199
			WORDADS_URL . 'css/style.css',
200
			array(),
201
			'2015-12-18'
202
		);
203
	}
204
205
	/**
206
	 * IPONWEB metadata used by the various scripts
207
	 *
208
	 * @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...
209
	 */
210
	function insert_head_meta() {
211
		$themename = esc_js( get_stylesheet() );
212
		$pagetype  = intval( $this->params->get_page_type_ipw() );
213
		$data_tags = ( $this->params->cloudflare ) ? ' data-cfasync="false"' : '';
214
		$site_id   = $this->params->blog_id;
215
		$consent   = intval( isset( $_COOKIE['personalized-ads-consent'] ) );
216
		echo <<<HTML
217
		<script$data_tags type="text/javascript">
218
			var __ATA_PP = { pt: $pagetype, ht: 2, tn: '$themename', amp: false, siteid: $site_id, consent: $consent };
219
			var __ATA = __ATA || {};
220
			__ATA.cmd = __ATA.cmd || [];
221
			__ATA.criteo = __ATA.criteo || {};
222
			__ATA.criteo.cmd = __ATA.criteo.cmd || [];
223
		</script>
224
HTML;
225
	}
226
227
	/**
228
	 * IPONWEB scripts in <head>
229
	 *
230
	 * @since 4.5.0
231
	 */
232
	function insert_head_iponweb() {
233
		$data_tags = ( $this->params->cloudflare ) ? ' data-cfasync="false"' : '';
234
		echo <<<HTML
235
		<link rel='dns-prefetch' href='//s.pubmine.com' />
236
		<link rel='dns-prefetch' href='//x.bidswitch.net' />
237
		<link rel='dns-prefetch' href='//static.criteo.net' />
238
		<link rel='dns-prefetch' href='//ib.adnxs.com' />
239
		<link rel='dns-prefetch' href='//aax.amazon-adsystem.com' />
240
		<link rel='dns-prefetch' href='//bidder.criteo.com' />
241
		<link rel='dns-prefetch' href='//cas.criteo.com' />
242
		<link rel='dns-prefetch' href='//gum.criteo.com' />
243
		<link rel='dns-prefetch' href='//ads.pubmatic.com' />
244
		<link rel='dns-prefetch' href='//gads.pubmatic.com' />
245
		<link rel='dns-prefetch' href='//tpc.googlesyndication.com' />
246
		<link rel='dns-prefetch' href='//ad.doubleclick.net' />
247
		<link rel='dns-prefetch' href='//googleads.g.doubleclick.net' />
248
		<link rel='dns-prefetch' href='//www.googletagservices.com' />
249
		<script$data_tags async type="text/javascript" src="//s.pubmine.com/head.js"></script>
250
HTML;
251
	}
252
253
	/**
254
	 * Insert the ad onto the page
255
	 *
256
	 * @since 4.5.0
257
	 */
258
	function insert_ad( $content ) {
259
		// Don't insert ads in feeds, or for anything but the main display. (This is required for compatibility with the Publicize module).
260
		if ( is_feed() || ! is_main_query() || ! in_the_loop() ) {
261
			return $content;
262
		}
263
		/**
264
		 * Allow third-party tools to disable the display of in post ads.
265
		 *
266
		 * @module wordads
267
		 *
268
		 * @since 4.5.0
269
		 *
270
		 * @param bool true Should the in post unit be disabled. Default to false.
271
		 */
272
		$disable = apply_filters( 'wordads_inpost_disable', false );
273
		if ( ! $this->params->should_show() || $disable ) {
274
			return $content;
275
		}
276
277
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
278
		return $content . $this->get_ad( 'belowpost', $ad_type );
279
	}
280
281
	/**
282
	 * Insert an inline ad into a post content
283
	 * Used for rendering the `wordads` shortcode.
284
	 *
285
	 * @since 6.1.0
286
	 */
287
	function insert_inline_ad( $content ) {
288
		// Ad JS won't work in XML feeds.
289
		if ( is_feed() ) {
290
			return $content;
291
		}
292
		/**
293
		 * Allow third-party tools to disable the display of in post ads.
294
		 *
295
		 * @module wordads
296
		 *
297
		 * @since 4.5.0
298
		 *
299
		 * @param bool true Should the in post unit be disabled. Default to false.
300
		 */
301
		$disable = apply_filters( 'wordads_inpost_disable', false );
302
		if ( $disable ) {
303
			return $content;
304
		}
305
306
		$ad_type  = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
307
		$content .= $this->get_ad( 'inline', $ad_type );
308
		return $content;
309
	}
310
311
	/**
312
	 * Inserts ad into header
313
	 *
314
	 * @since 4.5.0
315
	 */
316
	function insert_header_ad() {
317
		/**
318
		 * Allow third-party tools to disable the display of header ads.
319
		 *
320
		 * @module wordads
321
		 *
322
		 * @since 4.5.0
323
		 *
324
		 * @param bool true Should the header unit be disabled. Default to false.
325
		 */
326
		if ( apply_filters( 'wordads_header_disable', false ) ) {
327
			return;
328
		}
329
330
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
331
		echo $this->get_ad( 'top', $ad_type );
332
	}
333
334
	/**
335
	 * Special cases for inserting header unit via jQuery
336
	 *
337
	 * @since 4.5.0
338
	 */
339
	function insert_header_ad_special() {
340
		/**
341
		 * Allow third-party tools to disable the display of header ads.
342
		 *
343
		 * @module wordads
344
		 *
345
		 * @since 4.5.0
346
		 *
347
		 * @param bool true Should the header unit be disabled. Default to false.
348
		 */
349
		if ( apply_filters( 'wordads_header_disable', false ) ) {
350
			return;
351
		}
352
353
		$selector = '#content';
354
		switch ( get_stylesheet() ) {
355
			case 'twentyseventeen':
356
				$selector = '#content';
357
				break;
358
			case 'twentyfifteen':
359
				$selector = '#main';
360
				break;
361
			case 'twentyfourteen':
362
				$selector = 'article:first';
363
				break;
364
		}
365
366
		$ad_type = $this->option( 'wordads_house' ) ? 'house' : 'iponweb';
367
		echo $this->get_ad( 'top', $ad_type );
368
		echo <<<HTML
369
		<script type="text/javascript">
370
			jQuery('.wpcnt-header').insertBefore('$selector');
371
		</script>
372
HTML;
373
	}
374
375
	/**
376
	 * Filter the latest ads.txt to include custom user entries. Strips any tags or whitespace.
377
	 *
378
	 * @param  string $adstxt The ads.txt being filtered
379
	 * @return string         Filtered ads.txt with custom entries, if applicable
380
	 *
381
	 * @since 6.5.0
382
	 */
383
	function insert_custom_adstxt( $adstxt ) {
384
		$custom_adstxt = trim( wp_strip_all_tags( $this->option( 'wordads_custom_adstxt' ) ) );
385
		if ( $custom_adstxt ) {
386
			$adstxt .= "\n\n#Jetpack - User Custom Entries\n";
387
			$adstxt .= $custom_adstxt . "\n";
388
		}
389
390
		return $adstxt;
391
	}
392
393
	/**
394
	 * Get the ad for the spot and type.
395
	 *
396
	 * @param  string $spot top, side, inline, or belowpost
397
	 * @param  string $type iponweb or adsense
398
	 */
399
	function get_ad( $spot, $type = 'iponweb' ) {
400
		$snippet = '';
401
		if ( 'iponweb' == $type ) {
402
			// Default to mrec
403
			$width  = 300;
404
			$height = 250;
405
406
			$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...
407
			$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...
408
			$snippet          = '';
409
			if ( 'top' == $spot ) {
410
				// mrec for mobile, leaderboard for desktop
411
				$section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '2';
412
				$width      = $this->params->mobile_device ? 300 : 728;
413
				$height     = $this->params->mobile_device ? 250 : 90;
414
				$snippet    = $this->get_ad_snippet( $section_id, $height, $width, $spot );
415
			} elseif ( 'belowpost' == $spot ) {
416
				$section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '1';
417
				$width      = 300;
418
				$height     = 250;
419
420
				$snippet = $this->get_ad_snippet( $section_id, $height, $width, $spot, self::$SOLO_UNIT_CSS );
421
				if ( $this->option( 'wordads_second_belowpost', true ) ) {
422
					$section_id2 = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID2 : $this->params->blog_id . '4';
423
					$snippet    .= $this->get_ad_snippet( $section_id2, $height, $width, $spot, 'float:left;margin-top:0px;' );
424
				}
425
			} elseif ( 'inline' === $spot ) {
426
				$section_id = 0 === $this->params->blog_id ? WORDADS_API_TEST_ID : $this->params->blog_id . '5';
427
				$snippet    = $this->get_ad_snippet( $section_id, $height, $width, $spot, 'mrec', self::$SOLO_UNIT_CSS );
0 ignored issues
show
Unused Code introduced by
The call to WordAds::get_ad_snippet() has too many arguments starting with self::$SOLO_UNIT_CSS.

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...
428
			}
429
		} elseif ( 'house' == $type ) {
430
			$leaderboard = 'top' == $spot && ! $this->params->mobile_device;
431
			$snippet     = $this->get_house_ad( $leaderboard ? 'leaderboard' : 'mrec' );
432
			if ( 'belowpost' == $spot && $this->option( 'wordads_second_belowpost', true ) ) {
433
				$snippet .= $this->get_house_ad( $leaderboard ? 'leaderboard' : 'mrec' );
434
			}
435
		}
436
437
		return $this->get_ad_div( $spot, $snippet );
438
	}
439
440
441
	/**
442
	 * Returns the snippet to be inserted into the ad unit
443
	 *
444
	 * @param  int    $section_id
445
	 * @param  int    $height
446
	 * @param  int    $width
447
	 * @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...
448
	 * @param  string $css
449
	 * @return string
450
	 *
451
	 * @since 5.7
452
	 */
453
	function get_ad_snippet( $section_id, $height, $width, $location = '', $css = '' ) {
454
		$this->ads[] = array(
455
			'location' => $location,
456
			'width'    => $width,
457
			'height'   => $height,
458
		);
459
		$ad_number   = count( $this->ads );
460
461
		$data_tags = $this->params->cloudflare ? ' data-cfasync="false"' : '';
462
		$css = esc_attr( $css );
463
464
		return <<<HTML
465
		<div style="padding-bottom:15px;width:{$width}px;height:{$height}px;$css">
466
			<div id="atatags-{$ad_number}">
467
				<script$data_tags type="text/javascript">
468
				__ATA.cmd.push(function() {
469
					__ATA.initSlot('atatags-{$ad_number}',  {
470
						collapseEmpty: 'before',
471
						sectionId: '{$section_id}',
472
						location: '{$location}',
473
						width: {$width},
474
						height: {$height}
475
					});
476
				});
477
				</script>
478
			</div>
479
		</div>
480
HTML;
481
	}
482
483
	/**
484
	 * Returns the complete ad div with snippet to be inserted into the page
485
	 *
486
	 * @param  string  $spot top, side, inline, or belowpost
487
	 * @param  string  $snippet The snippet to insert into the div
488
	 * @param  array  $css_classes
489
	 * @return string The supporting ad unit div
490
	 *
491
	 * @since 7.1
492
	 */
493
	function get_ad_div( $spot, $snippet, array $css_classes = array() ) {
494
		if ( empty( $css_classes ) ) {
495
			$css_classes = array();
496
		}
497
498
		$css_classes[] = 'wpcnt';
499
		if ( 'top' == $spot ) {
500
			$css_classes[] = 'wpcnt-header';
501
		}
502
503
		$spot = esc_attr( $spot );
504
		$classes = esc_attr( implode( ' ', $css_classes ) );
505
		$about  = esc_html__( 'Advertisements', 'jetpack' );
506
		return <<<HTML
507
		<div class="$classes">
508
			<div class="wpa">
509
				<span class="wpa-about">$about</span>
510
				<div class="u $spot">
511
					$snippet
512
				</div>
513
			</div>
514
		</div>
515
HTML;
516
	}
517
518
	/**
519
	 * Check the reasons to bail before we attempt to insert ads.
520
	 *
521
	 * @return true if we should bail (don't insert ads)
522
	 *
523
	 * @since 4.5.0
524
	 */
525
	public function should_bail() {
526
		return ! $this->option( 'wordads_approved' ) || (bool) $this->option( 'wordads_unsafe' );
527
	}
528
529
	/**
530
	 * Returns markup for HTML5 house ad base on unit
531
	 *
532
	 * @param  string $unit mrec, widesky, or leaderboard
533
	 * @return string       markup for HTML5 house ad
534
	 *
535
	 * @since 4.7.0
536
	 */
537
	public function get_house_ad( $unit = 'mrec' ) {
538
539
		switch ( $unit ) {
540
			case 'widesky':
541
				$width  = 160;
542
				$height = 600;
543
				break;
544
			case 'leaderboard':
545
				$width  = 728;
546
				$height = 90;
547
				break;
548
			case 'mrec':
549
			default:
550
				$width  = 300;
551
				$height = 250;
552
				break;
553
		}
554
555
		return <<<HTML
556
		<iframe
557
			src="https://s0.wp.com/wp-content/blog-plugins/wordads/house/html5/$unit/index.html"
558
			width="$width"
559
			height="$height"
560
			frameborder="0"
561
			scrolling="no"
562
			marginheight="0"
563
			marginwidth="0">
564
		</iframe>
565
HTML;
566
	}
567
568
	/**
569
	 * Activation hook actions
570
	 *
571
	 * @since 4.5.0
572
	 */
573
	public static function activate() {
574
		WordAds_API::update_wordads_status_from_api();
575
	}
576
}
577
578
add_action( 'jetpack_activate_module_wordads', array( 'WordAds', 'activate' ) );
579
add_action( 'jetpack_activate_module_wordads', array( 'WordAds_Cron', 'activate' ) );
580
add_action( 'jetpack_deactivate_module_wordads', array( 'WordAds_Cron', 'deactivate' ) );
581
582
global $wordads;
583
$wordads = new WordAds();
584