PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 6.7
Jetpack – WP Security, Backup, Speed, & Growth v6.7
16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / modules / shortcodes / crowdsignal.php
crowdsignal.php
570 lines 16.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Keep compatibility with polldaddy-plugin
4 if ( ! class_exists( 'CrowdsignalShortcode' ) && ! class_exists( 'PolldaddyShortcode' ) ) {
5
6 /**
7 * Class wrapper for Crowdsignal shortcodes
8 */
9
10 class CrowdsignalShortcode {
11
12 static $add_script = false;
13 static $scripts = false;
14
15 /**
16 * Add all the actions & resgister the shortcode
17 */
18 function __construct() {
19 if ( defined( 'GLOBAL_TAGS' ) == false ) {
20 add_shortcode( 'crowdsignal', array( $this, 'crowdsignal_shortcode' ) );
21 add_shortcode( 'polldaddy', array( $this, 'crowdsignal_shortcode' ) );
22
23 add_filter( 'pre_kses', array( $this, 'crowdsignal_embed_to_shortcode' ) );
24 }
25 add_action( 'wp_enqueue_scripts', array( $this, 'check_infinite' ) );
26 add_action( 'infinite_scroll_render', array( $this, 'crowdsignal_shortcode_infinite' ), 11 );
27 }
28
29 private function get_async_code( array $settings, $survey_link ) {
30 $include = <<<CONTAINER
31 ( function( d, c, j ) {
32 if ( !d.getElementById( j ) ) {
33 var pd = d.createElement( c ), s;
34 pd.id = j;
35 pd.src = 'https://polldaddy.com/survey.js';
36 s = d.getElementsByTagName( c )[0];
37 s.parentNode.insertBefore( pd, s );
38 }
39 }( document, 'script', 'pd-embed' ) );
40 CONTAINER;
41
42 // Compress it a bit
43 $include = $this->compress_it( $include );
44
45 $placeholder =
46 '<div class="cs-embed pd-embed" data-settings="'
47 . esc_attr( json_encode( $settings ) )
48 . '"></div>';
49 if ( 'button' === $settings['type'] ) {
50 $placeholder =
51 '<a class="cs-embed pd-embed" href="'
52 . esc_attr( $survey_link )
53 . '" data-settings="'
54 . esc_attr( json_encode( $settings ) )
55 . '">'
56 . esc_html( $settings['title'] )
57 . '</a>';
58 }
59
60 $js_include = $placeholder . "\n";
61 $js_include .= '<script type="text/javascript"><!--//--><![CDATA[//><!--' . "\n";
62 $js_include .= $include . "\n";
63 $js_include .= "//--><!]]></script>\n";
64
65 if ( 'button' !== $settings['type'] ) {
66 $js_include .= '<noscript>' . $survey_link . "</noscript>\n";
67 }
68
69 return $js_include;
70 }
71
72 private function compress_it( $js ) {
73 $js = str_replace( array( "\n", "\t", "\r" ), '', $js );
74 $js = preg_replace( '/\s*([,:\?\{;\-=\(\)])\s*/', '$1', $js );
75 return $js;
76 }
77
78 /*
79 * Crowdsignal Poll Embed script - transforms code that looks like that:
80 * <script type="text/javascript" charset="utf-8" async src="http://static.polldaddy.com/p/123456.js"></script>
81 * <noscript><a href="http://polldaddy.com/poll/123456/">What is your favourite color?</a></noscript>
82 * into the [crowdsignal poll=...] shortcode format
83 */
84 function crowdsignal_embed_to_shortcode( $content ) {
85
86 if ( ! is_string( $content ) || false === strpos( $content, 'polldaddy.com/p/' ) ) {
87 return $content;
88 }
89
90 $regexes = array();
91
92 $regexes[] = '#<script[^>]+?src="https?://(secure|static)\.polldaddy\.com/p/([0-9]+)\.js"[^>]*+>\s*?</script>\r?\n?(<noscript>.*?</noscript>)?#i';
93
94 $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';
95
96 foreach ( $regexes as $regex ) {
97 if ( ! preg_match_all( $regex, $content, $matches, PREG_SET_ORDER ) ) {
98 continue;
99 }
100
101 foreach ( $matches as $match ) {
102 if ( ! isset( $match[2] ) ) {
103 continue;
104 }
105
106 $id = (int) $match[2];
107
108 if ( $id > 0 ) {
109 $content = str_replace( $match[0], " [crowdsignal poll=$id]", $content );
110 /** This action is documented in modules/shortcodes/youtube.php */
111 do_action( 'jetpack_embed_to_shortcode', 'crowdsignal', $id );
112 }
113 }
114 }
115
116 return $content;
117 }
118
119 /**
120 * Shortcode for polldadddy
121 * [crowdsignal poll|survey|rating="123456"]
122 */
123 function crowdsignal_shortcode( $atts ) {
124 global $post;
125 global $content_width;
126
127 extract( shortcode_atts( array(
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, 'crowdsignal' ) );
151
152 if ( ! is_array( $atts ) ) {
153 return '<!-- Crowdsignal 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 ( $inline ) {
213 return <<<SCRIPT
214 <div class="cs-rating pd-rating" id="pd_rating_holder_{$rating}{$item_id}"></div>
215 <script type="text/javascript" charset="UTF-8"><!--//--><![CDATA[//><!--
216 PDRTJS_settings_{$rating}{$item_id}={$settings};
217 //--><!]]></script>
218 <script type="text/javascript" charset="UTF-8" async src="https://polldaddy.com/js/rating/rating.js"></script>
219 SCRIPT;
220 } else {
221 if ( false === self::$scripts ) {
222 self::$scripts = array();
223 }
224
225 $data = array( 'id' => $rating, 'item_id' => $item_id, 'settings' => $settings );
226
227 self::$scripts['rating'][] = $data;
228
229 add_action( 'wp_footer', array( $this, 'generate_scripts' ) );
230
231 $data = esc_attr( json_encode( $data ) );
232
233 if ( $infinite_scroll ) {
234 return <<<CONTAINER
235 <div class="cs-rating pd-rating" id="pd_rating_holder_{$rating}{$item_id}" data-settings="{$data}"></div>
236 CONTAINER;
237 } else {
238 return <<<CONTAINER
239 <div class="cs-rating pd-rating" id="pd_rating_holder_{$rating}{$item_id}"></div>
240 CONTAINER;
241 }
242 }
243 } elseif ( intval( $poll ) > 0 ) { //poll embed
244
245 $poll = intval( $poll );
246 $poll_url = sprintf( 'https://poll.fm/%d', $poll );
247 $poll_js = sprintf( 'https://secure.polldaddy.com/p/%d.js', $poll );
248 $poll_link = sprintf( '<a href="%s" target="_blank">Take Our Poll</a>', $poll_url );
249
250 if ( $no_script ) {
251 return $poll_link;
252 } else {
253 if ( $type == 'slider' && !$inline ) {
254
255 if ( ! in_array( $visit, array( 'single', 'multiple' ) ) ) {
256 $visit = 'single';
257 }
258
259 $settings = array(
260 'type' => 'slider',
261 'embed' => 'poll',
262 'delay' => intval( $delay ),
263 'visit' => $visit,
264 'id' => intval( $poll )
265 );
266
267 return $this->get_async_code( $settings, $poll_link );
268 } else {
269 $cb = ( $cb == 1 ? '?cb='.mktime() : false );
270 $margins = '';
271 $float = '';
272
273 if ( in_array( $align, array( 'right', 'left' ) ) ) {
274 $float = sprintf( 'float: %s;', $align );
275
276 if ( $align == 'left')
277 $margins = 'margin: 0px 10px 0px 0px;';
278 elseif ( $align == 'right' )
279 $margins = 'margin: 0px 0px 0px 10px';
280 }
281
282 // 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)
283 if ( is_singular() ) {
284 $inline = true;
285 }
286
287 if ( false === $cb && ! $inline ) {
288 if ( false === self::$scripts ) {
289 self::$scripts = array();
290 }
291
292 $data = array( 'url' => $poll_js );
293
294 self::$scripts['poll'][intval( $poll )] = $data;
295
296 add_action( 'wp_footer', array( $this, 'generate_scripts' ) );
297
298 $data = esc_attr( json_encode( $data ) );
299
300 $script_url = esc_url_raw( plugins_url( 'js/polldaddy-shortcode.js', __FILE__ ) );
301 $str = <<<CONTAINER
302 <a name="pd_a_{$poll}"></a>
303 <div class="CSS_Poll PDS_Poll" id="PDI_container{$poll}" data-settings="{$data}" style="display:inline-block;{$float}{$margins}"></div>
304 <div id="PD_superContainer"></div>
305 <noscript>{$poll_link}</noscript>
306 CONTAINER;
307
308 $loader = <<<SCRIPT
309 ( function( d, c, j ) {
310 if ( ! d.getElementById( j ) ) {
311 var pd = d.createElement( c ), s;
312 pd.id = j;
313 pd.src = '{$script_url}';
314 s = d.getElementsByTagName( c )[0];
315 s.parentNode.insertBefore( pd, s );
316 } else if ( typeof jQuery !== 'undefined' ) {
317 jQuery( d.body ).trigger( 'pd-script-load' );
318 }
319 } ( document, 'script', 'pd-polldaddy-loader' ) );
320 SCRIPT;
321
322 $loader = $this->compress_it( $loader );
323 $loader = "<script type='text/javascript'>\n" . $loader . "\n</script>";
324
325 return $str . $loader;
326 } else {
327 if ( $inline ) {
328 $cb = '';
329 }
330
331 return <<<CONTAINER
332 <a id="pd_a_{$poll}"></a>
333 <div class="CSS_Poll PDS_Poll" id="PDI_container{$poll}" style="display:inline-block;{$float}{$margins}"></div>
334 <div id="PD_superContainer"></div>
335 <script type="text/javascript" charset="UTF-8" async src="{$poll_js}{$cb}"></script>
336 <noscript>{$poll_link}</noscript>
337 CONTAINER;
338 }
339 }
340 }
341 } elseif ( ! empty( $survey ) ) { //survey embed
342
343 if ( in_array( $type, array( 'iframe', 'button', 'banner', 'slider' ) ) ) {
344
345 if ( empty( $title ) ) {
346 $title = __( 'Take Our Survey', 'jetpack' );
347 if( ! empty( $link_text ) ) {
348 $title = $link_text;
349 }
350 }
351
352 if ( $type == 'banner' || $type == 'slider' )
353 $inline = false;
354
355 $survey = preg_replace( '/[^a-f0-9]/i', '', $survey );
356 $survey_url = esc_url( "https://survey.fm/{$survey}" );
357 $survey_link = sprintf( '<a href="%s" target="_blank">%s</a>', $survey_url, esc_html( $title ) );
358
359 $settings = array();
360
361 // Do we want a full embed code or a link?
362 if ( $no_script || $inline || $infinite_scroll ) {
363 return $survey_link;
364 }
365
366 if ( $type == 'iframe' ) {
367 if ( $height != 'auto' ) {
368 if ( isset( $content_width ) && is_numeric( $width ) && $width > $content_width ) {
369 $width = $content_width;
370 }
371
372 if ( ! $width ) {
373 $width = '100%';
374 } else {
375 $width = (int) $width;
376 }
377
378 if ( ! $height ) {
379 $height = '600';
380 } else {
381 $height = (int) $height;
382 }
383
384 return <<<CONTAINER
385 <iframe src="{$survey_url}?iframe=1" frameborder="0" width="{$width}" height="{$height}" scrolling="auto" allowtransparency="true" marginheight="0" marginwidth="0">{$survey_link}</iframe>
386 CONTAINER;
387 } elseif ( ! empty( $domain ) && ! empty( $id ) ) {
388
389 $domain = preg_replace( '/[^a-z0-9\-]/i', '', $domain );
390 $id = preg_replace( '/[\/\?&\{\}]/', '', $id );
391
392 $auto_src = esc_url( "https://{$domain}.survey.fm/{$id}" );
393 $auto_src = parse_url( $auto_src );
394
395 if ( ! is_array( $auto_src ) || count( $auto_src ) == 0 ) {
396 return '<!-- no crowdsignal output -->';
397 }
398
399 if ( ! isset( $auto_src['host'] ) || ! isset( $auto_src['path'] ) ) {
400 return '<!-- no crowdsignal output -->';
401 }
402
403 $domain = $auto_src['host'] . '/';
404 $id = ltrim( $auto_src['path'], '/' );
405
406 $settings = array(
407 'type' => $type,
408 'auto' => true,
409 'domain' => $domain,
410 'id' => $id
411 );
412 }
413 } else {
414 $text_color = preg_replace( '/[^a-f0-9]/i', '', $text_color );
415 $back_color = preg_replace( '/[^a-f0-9]/i', '', $back_color );
416
417 if (
418 ! in_array(
419 $align,
420 array(
421 'right',
422 'left',
423 'top-left',
424 'top-right',
425 'middle-left',
426 'middle-right',
427 'bottom-left',
428 'bottom-right'
429 )
430 )
431 ) {
432 $align = '';
433 }
434
435 if (
436 ! in_array(
437 $style,
438 array(
439 'inline',
440 'side',
441 'corner',
442 'rounded',
443 'square'
444 )
445 )
446 ) {
447 $style = '';
448 }
449
450 $title = wp_strip_all_tags( $title );
451 $body = wp_strip_all_tags( $body );
452 $button = wp_strip_all_tags( $button );
453
454 $settings = array_filter( array(
455 'title' => $title,
456 'type' => $type,
457 'body' => $body,
458 'button' => $button,
459 'text_color' => $text_color,
460 'back_color' => $back_color,
461 'align' => $align,
462 'style' => $style,
463 'id' => $survey,
464 ) );
465 }
466
467 if ( empty( $settings ) ) {
468 return '<!-- no crowdsignal output -->';
469 }
470
471 return $this->get_async_code( $settings, $survey_link );
472 }
473 } else {
474 return '<!-- no crowdsignal output -->';
475 }
476 }
477
478 function generate_scripts() {
479 $script = '';
480
481 if ( is_array( self::$scripts ) ) {
482 if ( isset( self::$scripts['rating'] ) ) {
483 $script = "<script type='text/javascript' charset='UTF-8' id='polldaddyRatings'><!--//--><![CDATA[//><!--\n";
484 foreach( self::$scripts['rating'] as $rating ) {
485 $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']} );}}";
486 }
487 $script .= "\n//--><!]]></script><script type='text/javascript' charset='UTF-8' async src='https://polldaddy.com/js/rating/rating.js'></script>";
488
489 }
490
491 if ( isset( self::$scripts['poll'] ) ) {
492 foreach( self::$scripts['poll'] as $poll ) {
493 $script .= "<script type='text/javascript' charset='UTF-8' async src='{$poll['url']}'></script>";
494 }
495 }
496 }
497
498 self::$scripts = false;
499 echo $script;
500 }
501
502 /**
503 * If the theme uses infinite scroll, include jquery at the start
504 */
505 function check_infinite() {
506 if (
507 current_theme_supports( 'infinite-scroll' )
508 && class_exists( 'The_Neverending_Home_Page' )
509 && The_Neverending_Home_Page::archive_supports_infinity()
510 ) {
511 wp_enqueue_script( 'jquery' );
512 }
513 }
514
515 /**
516 * Dynamically load the .js, if needed
517 *
518 * This hooks in late (priority 11) to infinite_scroll_render to determine
519 * a posteriori if a shortcode has been called.
520 */
521 function crowdsignal_shortcode_infinite() {
522 // only try to load if a shortcode has been called and theme supports infinite scroll
523 if( self::$add_script ) {
524 $script_url = esc_url_raw( plugins_url( 'js/polldaddy-shortcode.js', __FILE__ ) );
525
526 // if the script hasn't been loaded, load it
527 // if the script loads successfully, fire an 'pd-script-load' event
528 echo <<<SCRIPT
529 <script type='text/javascript'>
530 //<![CDATA[
531 ( function( d, c, j ) {
532 if ( !d.getElementById( j ) ) {
533 var pd = d.createElement( c ), s;
534 pd.id = j;
535 pd.async = true;
536 pd.src = '{$script_url}';
537 s = d.getElementsByTagName( c )[0];
538 s.parentNode.insertBefore( pd, s );
539 } else if ( typeof jQuery !== 'undefined' ) {
540 jQuery( d.body ).trigger( 'pd-script-load' );
541 }
542 } ( document, 'script', 'pd-polldaddy-loader' ) );
543 //]]>
544 </script>
545 SCRIPT;
546
547 }
548 }
549 }
550
551 // kick it all off
552 new CrowdsignalShortcode();
553
554 if ( ! function_exists( 'crowdsignal_link' ) ) {
555 // http://polldaddy.com/poll/1562975/?view=results&msg=voted
556 function crowdsignal_link( $content ) {
557 return preg_replace( '!(?:\n|\A)https?://(polldaddy\.com/poll|poll\.fm)/([0-9]+?)(/.*)?(?:\n|\Z)!i', "\n<script type='text/javascript' charset='utf-8' src='//static.polldaddy.com/p/$2.js'></script><noscript> <a href='https://poll.fm/$2'>View Poll</a></noscript>\n", $content );
558 }
559
560 // higher priority because we need it before auto-link and autop get to it
561 add_filter( 'the_content', 'crowdsignal_link', 1 );
562 add_filter( 'the_content_rss', 'crowdsignal_link', 1 );
563 }
564
565 wp_oembed_add_provider( '#https?://(.+\.)?polldaddy\.com/.*#i', 'https://api.crowdsignal.com/oembed', true );
566 wp_oembed_add_provider( '#https?://.+\.survey\.fm/.*#i', 'https://api.crowdsignal.com/oembed', true );
567 wp_oembed_add_provider( '#https?://poll\.fm/.*#i', 'https://api.crowdsignal.com/oembed', true );
568
569 }
570