Completed
Push — branch-4.0 ( fc0d6f...bf547c )
by
unknown
08:22
created

PolldaddyShortcode::polldaddy_shortcode()   F

Complexity

Conditions 62
Paths 9073

Size

Total Lines 360
Code Lines 234

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 360
rs 2
cc 62
eloc 234
nc 9073
nop 1

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
if ( !class_exists( 'PolldaddyShortcode' ) ) {
4
	/**
5
* Class wrapper for polldaddy shortcodes
6
*/
7
8
class PolldaddyShortcode {
9
10
	static $add_script = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $add_script.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
11
	static $scripts = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $scripts.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
12
13
	/**
14
	 * Add all the actions & resgister the shortcode
15
	 */
16
	function __construct() {
17
		if ( defined( 'GLOBAL_TAGS' ) == false ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
18
			add_shortcode( 'polldaddy', array( $this, 'polldaddy_shortcode' ) );
19
			add_filter( 'pre_kses', array( $this, 'polldaddy_embed_to_shortcode' ) );
20
		}
21
		add_action( 'wp_enqueue_scripts', array( $this, 'check_infinite' ) );
22
		add_action( 'infinite_scroll_render', array( $this, 'polldaddy_shortcode_infinite' ), 11 );
23
	}
24
25
	private function get_async_code( array $settings, $survey_link ) {
26
		$embed_src     = 'http://i0.poll.fm/survey.js';
27
		$embed_src_ssl = 'https://polldaddy.com/survey.js';
28
29
		$include = <<<CONTAINER
30
( function( d, c, j ) {
31
  if ( !d.getElementById( j ) ) {
32
    var pd = d.createElement( c ), s;
33
    pd.id = j;
34
    pd.src = ( 'https:' == d.location.protocol ) ? '{$embed_src_ssl}' : '{$embed_src}';
35
    s = d.getElementsByTagName( c )[0];
36
    s.parentNode.insertBefore( pd, s );
37
  }
38
}( document, 'script', 'pd-embed' ) );
39
CONTAINER;
40
41
		// Compress it a bit
42
		$include = $this->compress_it( $include );
43
44
		$placeholder =
45
			'<div class="pd-embed" data-settings="'
46
			. esc_attr( json_encode( $settings ) )
47
			. '"></div>';
48
		if ( 'button' === $settings['type'] ) {
49
			$placeholder =
50
				'<a class="pd-embed" href="'
51
				. esc_attr( $survey_link )
52
				. '" data-settings="'
53
				. esc_attr( json_encode( $settings ) )
54
				. '">'
55
				. esc_html( $settings['title'] )
56
				. '</a>';
57
		}
58
59
		$js_include = $placeholder . "\n";
60
		$js_include .= '<script type="text/javascript"><!--//--><![CDATA[//><!--' . "\n";
61
		$js_include .= $include . "\n";
62
		$js_include .= "//--><!]]></script>\n";
63
64
		if ( 'button' !== $settings['type'] ) {
65
			$js_include .= '<noscript>' . $survey_link . "</noscript>\n";
66
		}
67
68
		return $js_include;
69
	}
70
71
	private function compress_it( $js ) {
72
		$js = str_replace( array( "\n", "\t", "\r" ), '', $js );
73
		$js = preg_replace( '/\s*([,:\?\{;\-=\(\)])\s*/', '$1', $js );
74
		return $js;
75
	}
76
77
	/*
78
	 * Polldaddy Poll Embed script - transforms code that looks like that:
79
	 * <script type="text/javascript" charset="utf-8" src="http://static.polldaddy.com/p/123456.js"></script>
80
	 * <noscript><a href="http://polldaddy.com/poll/123456/">What is your favourite color?</a></noscript>
81
	 * into the [polldaddy poll=...] shortcode format
82
	 */
83
	function polldaddy_embed_to_shortcode( $content ) {
84
85
		if ( false === strpos( $content, 'polldaddy.com/p/' ) ) {
86
			return $content;
87
		}
88
89
		$regexes = array();
90
91
		$regexes[] = '#<script[^>]+?src="https?://(secure|static)\.polldaddy\.com/p/([0-9]+)\.js"[^>]*+>\s*?</script>\r?\n?(<noscript>.*?</noscript>)?#i';
92
93
		$regexes[] = '#&lt;script(?:[^&]|&(?!gt;))+?src="https?://(secure|static)\.polldaddy\.com/p/([0-9]+)\.js"(?:[^&]|&(?!gt;))*+&gt;\s*?&lt;/script&gt;\r?\n?(&lt;noscript&gt;.*?&lt;/noscript&gt;)?#i';
94
95
		foreach ( $regexes as $regex ) {
96
			if ( ! preg_match_all( $regex, $content, $matches, PREG_SET_ORDER ) ) {
97
				continue;
98
			}
99
100
			foreach ( $matches as $match ) {
101
				if ( ! isset( $match[2] ) ) {
102
					continue;
103
				}
104
105
				$id = (int) $match[2];
106
107
				if ( $id > 0 ) {
108
					$content = str_replace( $match[0], " [polldaddy poll=$id]", $content );
109
					/** This action is documented in modules/shortcodes/youtube.php */
110
					do_action( 'jetpack_embed_to_shortcode', 'polldaddy', $id );
111
				}
112
			}
113
		}
114
115
		return $content;
116
	}
117
118
	/**
119
	 * Shortcode for polldadddy
120
	 * [polldaddy poll|survey|rating="123456"]
121
	 *
122
	 * */
123
	function polldaddy_shortcode( $atts ) {
124
		global $post;
125
		global $content_width;
126
127
		extract( shortcode_atts( array(
0 ignored issues
show
Bug introduced by
shortcode_atts(array('su...'), $atts, 'polldaddy') cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
128
			'survey'     => null,
129
			'link_text'  => 'Take Our Survey',
130
			'poll'       => 'empty',
131
			'rating'     => 'empty',
132
			'unique_id'  => null,
133
			'item_id'    => null,
134
			'title'      => null,
135
			'permalink'  => null,
136
			'cb'         => 0,
137
			'type'       => 'button',
138
			'body'       => '',
139
			'button'     => '',
140
			'text_color' => '000000',
141
			'back_color' => 'FFFFFF',
142
			'align'      => '',
143
			'style'      => '',
144
			'width'      => $content_width,
145
			'height'     => floor( $content_width * 3 / 4 ),
146
			'delay'      => 100,
147
			'visit'      => 'single',
148
			'domain'     => '',
149
			'id'         => '',
150
		), $atts, 'polldaddy' ) );
151
152
		if ( ! is_array( $atts ) ) {
153
			return '<!-- Polldaddy shortcode passed invalid attributes -->';
154
		}
155
156
		$inline          = ! in_the_loop();
157
		$no_script       = false;
158
		$infinite_scroll = false;
159
160
		if ( is_home() && current_theme_supports( 'infinite-scroll' ) ) {
161
			$infinite_scroll = true;
162
		}
163
164
		if ( defined( 'PADPRESS_LOADED' ) ) {
165
			$inline = true;
166
		}
167
168
		if ( function_exists( 'get_option' ) && get_option( 'polldaddy_load_poll_inline' ) ) {
169
			$inline = true;
170
		}
171
172
		if ( is_feed() || ( defined( 'DOING_AJAX' ) && ! $infinite_scroll ) ) {
173
			$no_script = false;
174
		}
175
176
		self::$add_script = $infinite_scroll;
177
178
		if ( intval( $rating ) > 0 && ! $no_script ) { //rating embed
179
180
			if ( empty( $unique_id ) ) {
181
				$unique_id = is_page() ? 'wp-page-' . $post->ID : 'wp-post-' . $post->ID;
182
			}
183
184
			if ( empty( $item_id ) ) {
185
				$item_id = is_page() ? '_page_' . $post->ID : '_post_' . $post->ID;
186
			}
187
188
			if ( empty( $title ) ) {
189
				/** This filter is documented in core/src/wp-includes/general-template.php */
190
				$title = apply_filters( 'wp_title', $post->post_title, '', '' );
191
			}
192
193
			if ( empty( $permalink ) ) {
194
				$permalink = get_permalink( $post->ID );
195
			}
196
197
			$rating    = intval( $rating );
198
			$unique_id = preg_replace( '/[^\-_a-z0-9]/i', '', wp_strip_all_tags( $unique_id ) );
199
			$item_id   = wp_strip_all_tags( $item_id );
200
			$item_id   = preg_replace( '/[^_a-z0-9]/i', '', $item_id );
201
202
			$settings = json_encode( array(
203
				'id'        => $rating,
204
				'unique_id' => $unique_id,
205
				'title'     => rawurlencode( trim( $title ) ),
206
				'permalink' => esc_url( $permalink ),
207
				'item_id'   => $item_id,
208
			) );
209
210
			$item_id = esc_js( $item_id );
211
212
			if ( is_ssl() ) {
213
				$rating_js_file = "https://polldaddy.com/js/rating/rating.js";
214
			} else {
215
				$rating_js_file = "http://i0.poll.fm/js/rating/rating.js";
216
			}
217
218
			if ( $inline ) {
219
				return <<<SCRIPT
220
<div class="pd-rating" id="pd_rating_holder_{$rating}{$item_id}"></div>
221
<script type="text/javascript" charset="UTF-8"><!--//--><![CDATA[//><!--
222
PDRTJS_settings_{$rating}{$item_id}={$settings};
223
//--><!]]></script>
224
<script type="text/javascript" charset="UTF-8" src="{$rating_js_file}"></script>
225
SCRIPT;
226
			} else {
227
				if ( false === self::$scripts ) {
228
					self::$scripts = array();
0 ignored issues
show
Documentation Bug introduced by
It seems like array() of type array is incompatible with the declared type boolean of property $scripts.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
229
				}
230
231
				$data = array( 'id' => $rating, 'item_id' => $item_id, 'settings' => $settings );
232
233
				self::$scripts['rating'][] = $data;
234
235
				add_action( 'wp_footer', array( $this, 'generate_scripts' ) );
236
237
				$data = esc_attr( json_encode( $data ) );
238
239
				if ( $infinite_scroll ) {
240
					return <<<CONTAINER
241
<div class="pd-rating" id="pd_rating_holder_{$rating}{$item_id}" data-settings="{$data}"></div>
242
CONTAINER;
243
				} else {
244
					return <<<CONTAINER
245
<div class="pd-rating" id="pd_rating_holder_{$rating}{$item_id}"></div>
246
CONTAINER;
247
				}
248
			}
249
		} elseif ( intval( $poll ) > 0 ) { //poll embed
250
251
			$poll      = intval( $poll );
252
			$poll_url  = sprintf( 'http://polldaddy.com/poll/%d', $poll );
253
			$poll_js   = sprintf( '%s.polldaddy.com/p/%d.js', ( is_ssl() ? 'https://secure' : 'http://static' ), $poll );
254
			$poll_link = sprintf( '<a href="%s" target="_blank">Take Our Poll</a>', $poll_url );
255
256
			if ( $no_script ) {
257
				return $poll_link;
258
			} else {
259
				if ( $type == 'slider' && !$inline ) {
260
261
					if ( ! in_array( $visit, array( 'single', 'multiple' ) ) ) {
262
						$visit = 'single';
263
					}
264
265
					$settings = array(
266
						'type'  => 'slider',
267
						'embed' => 'poll',
268
						'delay' => intval( $delay ),
269
						'visit' => $visit,
270
						'id'    => intval( $poll )
271
					);
272
273
					return $this->get_async_code( $settings, $poll_link );
274
				} else {
275
					$cb      = ( $cb == 1 ? '?cb='.mktime() : false );
276
					$margins = '';
277
					$float   = '';
278
279
					if ( in_array( $align, array( 'right', 'left' ) ) ) {
280
						$float = sprintf( 'float: %s;', $align );
281
282
						if ( $align == 'left')
283
							$margins = 'margin: 0px 10px 0px 0px;';
284
						elseif ( $align == 'right' )
285
							$margins = 'margin: 0px 0px 0px 10px';
286
					}
287
288
					// Force the normal style embed on single posts/pages otherwise it's not rendered on infinite scroll themed blogs ('infinite_scroll_render' isn't fired)
289
					if ( is_singular() ) {
290
						$inline = true;
291
					}
292
293
					if ( false === $cb && ! $inline ) {
294
						if ( false === self::$scripts ) {
295
							self::$scripts = array();
296
						}
297
298
						$data = array( 'url' => $poll_js );
299
300
						self::$scripts['poll'][intval( $poll )] = $data;
301
302
						add_action( 'wp_footer', array( $this, 'generate_scripts' ) );
303
304
						$data = esc_attr( json_encode( $data ) );
305
306
						$script_url = esc_url_raw( plugins_url( 'js/polldaddy-shortcode.js', __FILE__ ) );
307
						$str = <<<CONTAINER
308
<a name="pd_a_{$poll}"></a>
309
<div class="PDS_Poll" id="PDI_container{$poll}" data-settings="{$data}" style="display:inline-block;{$float}{$margins}"></div>
310
<div id="PD_superContainer"></div>
311
<noscript>{$poll_link}</noscript>
312
CONTAINER;
313
314
$loader = <<<SCRIPT
315
( function( d, c, j ) {
316
	if ( ! d.getElementById( j ) ) {
317
		var pd = d.createElement( c ), s;
318
		pd.id = j;
319
		pd.src = '{$script_url}';
320
		s = d.getElementsByTagName( c )[0];
321
		s.parentNode.insertBefore( pd, s );
322
	} else if ( typeof jQuery !== 'undefined' ) {
323
		jQuery( d.body ).trigger( 'pd-script-load' );
324
	}
325
} ( document, 'script', 'pd-polldaddy-loader' ) );
326
SCRIPT;
327
328
						$loader = $this->compress_it( $loader );
329
						$loader = "<script type='text/javascript'>\n" . $loader . "\n</script>";
330
331
						return $str . $loader;
332
					} else {
333
						if ( $inline ) {
334
							$cb = '';
335
						}
336
337
						return <<<CONTAINER
338
<a id="pd_a_{$poll}"></a>
339
<div class="PDS_Poll" id="PDI_container{$poll}" style="display:inline-block;{$float}{$margins}"></div>
340
<div id="PD_superContainer"></div>
341
<script type="text/javascript" charset="UTF-8" src="{$poll_js}{$cb}"></script>
342
<noscript>{$poll_link}</noscript>
343
CONTAINER;
344
					}
345
				}
346
			}
347
		} elseif ( ! empty( $survey ) ) { //survey embed
348
349
			if ( in_array( $type, array( 'iframe', 'button', 'banner', 'slider' ) ) ) {
350
351
				if ( empty( $title ) ) {
352
					$title = __( 'Take Our Survey', 'jetpack' );
353
					if( ! empty( $link_text ) ) {
354
						$title = $link_text;
355
					}
356
				}
357
358
				if ( $type == 'banner' || $type == 'slider' )
359
					$inline = false;
360
361
				$survey      = preg_replace( '/[^a-f0-9]/i', '', $survey );
362
				$survey_url  = esc_url( "http://polldaddy.com/s/{$survey}" );
363
				$survey_link = sprintf( '<a href="%s" target="_blank">%s</a>', $survey_url, esc_html( $title ) );
364
365
				$settings = array();
366
367
				// Do we want a full embed code or a link?
368
				if ( $no_script || $inline || $infinite_scroll ) {
369
					return $survey_link;
370
				}
371
372
				if ( $type == 'iframe' ) {
373
					if ( $height != 'auto' ) {
374
						if ( isset( $content_width ) && is_numeric( $width ) && $width > $content_width ) {
375
							$width = $content_width;
376
						}
377
378
						if ( ! $width ) {
379
							$width = '100%';
380
						} else {
381
							$width = (int) $width;
382
						}
383
384
						if ( ! $height ) {
385
							$height = '600';
386
						} else {
387
							$height = (int) $height;
388
						}
389
390
						return <<<CONTAINER
391
<iframe src="{$survey_url}?iframe=1" frameborder="0" width="{$width}" height="{$height}" scrolling="auto" allowtransparency="true" marginheight="0" marginwidth="0">{$survey_link}</iframe>
392
CONTAINER;
393
					} elseif ( ! empty( $domain ) && ! empty( $id ) ) {
394
395
						$domain = preg_replace( '/[^a-z0-9\-]/i', '', $domain );
396
						$id = preg_replace( '/[\/\?&\{\}]/', '', $id );
397
398
						$auto_src = esc_url( "http://{$domain}.polldaddy.com/s/{$id}" );
399
						$auto_src = parse_url( $auto_src );
400
401
						if ( ! is_array( $auto_src ) || count( $auto_src ) == 0 ) {
402
							return '<!-- no polldaddy output -->';
403
						}
404
405
						if ( ! isset( $auto_src['host'] ) || ! isset( $auto_src['path'] ) ) {
406
							return '<!-- no polldaddy output -->';
407
						}
408
409
						$domain   = $auto_src['host'].'/s/';
410
						$id       = str_ireplace( '/s/', '', $auto_src['path'] );
411
412
						$settings = array(
413
							'type'       => $type,
414
							'auto'       => true,
415
							'domain'     => $domain,
416
							'id'         => $id
417
						);
418
					}
419
				} else {
420
					$text_color = preg_replace( '/[^a-f0-9]/i', '', $text_color );
421
					$back_color = preg_replace( '/[^a-f0-9]/i', '', $back_color );
422
423
					if (
424
						! in_array(
425
							$align,
426
							array(
427
								'right',
428
								'left',
429
								'top-left',
430
								'top-right',
431
								'middle-left',
432
								'middle-right',
433
								'bottom-left',
434
								'bottom-right'
435
							)
436
						)
437
					) {
438
						$align = '';
439
					}
440
441
					if (
442
						! in_array(
443
							$style,
444
							array(
445
								'inline',
446
								'side',
447
								'corner',
448
								'rounded',
449
								'square'
450
							)
451
						)
452
					) {
453
						$style = '';
454
					}
455
456
					$title  = wp_strip_all_tags( $title );
457
					$body   = wp_strip_all_tags( $body );
458
					$button = wp_strip_all_tags( $button );
459
460
					$settings = array_filter( array(
461
						'title'      => $title,
462
						'type'       => $type,
463
						'body'       => $body,
464
						'button'     => $button,
465
						'text_color' => $text_color,
466
						'back_color' => $back_color,
467
						'align'      => $align,
468
						'style'      => $style,
469
						'id'         => $survey,
470
					) );
471
				}
472
473
				if ( empty( $settings ) ) {
474
					return '<!-- no polldaddy output -->';
475
				}
476
477
				return $this->get_async_code( $settings, $survey_link );
478
			}
479
		} else {
480
			return '<!-- no polldaddy output -->';
481
		}
482
	}
483
484
	function generate_scripts() {
485
		$script = '';
486
487
		if ( is_array( self::$scripts ) ) {
488
			if ( is_ssl() ) {
489
				$rating_js_file = "https://polldaddy.com/js/rating/rating.js";
490
			} else {
491
				$rating_js_file = "http://i0.poll.fm/js/rating/rating.js";
492
			}
493
494
			if ( isset( self::$scripts['rating'] ) ) {
495
				$script = "<script type='text/javascript' charset='UTF-8' id='polldaddyRatings'><!--//--><![CDATA[//><!--\n";
496
				foreach( self::$scripts['rating'] as $rating ) {
497
					$script .= "PDRTJS_settings_{$rating['id']}{$rating['item_id']}={$rating['settings']}; if ( typeof PDRTJS_RATING !== 'undefined' ){if ( typeof PDRTJS_{$rating['id']}{$rating['item_id']} == 'undefined' ){PDRTJS_{$rating['id']}{$rating['item_id']} = new PDRTJS_RATING( PDRTJS_settings_{$rating['id']}{$rating['item_id']} );}}";
498
				}
499
				$script .= "\n//--><!]]></script><script type='text/javascript' charset='UTF-8' src='{$rating_js_file}'></script>";
500
501
			}
502
503
			if ( isset( self::$scripts['poll'] ) ) {
504
				foreach( self::$scripts['poll'] as $poll ) {
505
					$script .= "<script type='text/javascript' charset='UTF-8' src='{$poll['url']}'></script>";
506
				}
507
			}
508
		}
509
510
		self::$scripts = false;
511
		echo $script;
512
	}
513
514
	/**
515
	 * If the theme uses infinite scroll, include jquery at the start
516
	 */
517
	function check_infinite() {
518
		if (
519
			current_theme_supports( 'infinite-scroll' )
520
			&& class_exists( 'The_Neverending_Home_Page' )
521
			&& The_Neverending_Home_Page::archive_supports_infinity()
522
		) {
523
			wp_enqueue_script( 'jquery' );
524
		}
525
	}
526
527
	/**
528
	 * Dynamically load the .js, if needed
529
	 *
530
	 * This hooks in late (priority 11) to infinite_scroll_render to determine
531
	 * a posteriori if a shortcode has been called.
532
	 */
533
	function polldaddy_shortcode_infinite() {
534
		// only try to load if a shortcode has been called and theme supports infinite scroll
535
		if( self::$add_script ) {
536
			$script_url = esc_url_raw( plugins_url( 'js/polldaddy-shortcode.js', __FILE__ ) );
537
538
			// if the script hasn't been loaded, load it
539
			// if the script loads successfully, fire an 'pd-script-load' event
540
			echo <<<SCRIPT
541
				<script type='text/javascript'>
542
				//<![CDATA[
543
				( function( d, c, j ) {
544
					if ( !d.getElementById( j ) ) {
545
						var pd = d.createElement( c ), s;
546
						pd.id = j;
547
						pd.src = '{$script_url}';
548
						s = d.getElementsByTagName( c )[0];
549
						s.parentNode.insertBefore( pd, s );
550
					} else if ( typeof jQuery !== 'undefined' ) {
551
						jQuery( d.body ).trigger( 'pd-script-load' );
552
					}
553
				} ( document, 'script', 'pd-polldaddy-loader' ) );
554
				//]]>
555
				</script>
556
SCRIPT;
557
558
		}
559
	}
560
}
561
562
// kick it all off
563
new PolldaddyShortcode();
564
565
if ( ! function_exists( 'polldaddy_link' ) ) {
566
	// http://polldaddy.com/poll/1562975/?view=results&msg=voted
567
	function polldaddy_link( $content ) {
568
		return jetpack_preg_replace_outside_tags( '!(?:\n|\A)http://polldaddy.com/poll/([0-9]+?)/(.+)?(?:\n|\Z)!i', "\n<script type='text/javascript' charset='utf-8' src='//static.polldaddy.com/p/$1.js'></script><noscript> <a href='http://polldaddy.com/poll/$1/'>View Poll</a></noscript>\n", $content, 'polldaddy.com/poll' );
569
	}
570
571
	// higher priority because we need it before auto-link and autop get to it
572
	add_filter( 'the_content', 'polldaddy_link', 1 );
573
	add_filter( 'the_content_rss', 'polldaddy_link', 1 );
574
}
575
576
wp_oembed_add_provider( '#http://poll\.fm/.*#i', 'http://polldaddy.com/oembed/', true );
577
578
}
579