Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
68.48% covered (warning)
68.48%
302 / 441
22.22% covered (danger)
22.22%
2 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
crowdsignal_link
92.86% covered (success)
92.86%
13 / 14
0.00% covered (danger)
0.00%
0 / 1
3.00
CrowdsignalShortcode
68.97% covered (warning)
68.97%
289 / 419
25.00% covered (danger)
25.00%
2 / 8
325.57
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 register_scripts
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
1
 get_async_code
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
2
 crowdsignal_embed_to_shortcode
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
72
 polldaddy_shortcode
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 crowdsignal_shortcode
77.95% covered (warning)
77.95%
251 / 322
0.00% covered (danger)
0.00%
0 / 1
112.70
 generate_scripts
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
42
 crowdsignal_shortcode_infinite
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
1<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2/**
3 * Crowdsignal (PollDaddy) shortcode.
4 *
5 * Formats:
6 * [polldaddy type="iframe" survey="EB151947E5950FCF" height="auto" domain="jeherve" id="a-survey-with-branches"]
7 * [crowdsignal type="iframe" survey="EB151947E5950FCF" height="auto" domain="jeherve" id="a-survey-with-branches"]
8 * https://polldaddy.com/poll/7910844/
9 * https://jeherve.survey.fm/a-survey
10 * https://jeherve.survey.fm/a-survey-with-branches
11 * [crowdsignal type="iframe" survey="7676FB1FF2B56CE9" height="auto" domain="jeherve" id="a-survey"]
12 * [crowdsignal survey="7676FB1FF2B56CE9"]
13 * [polldaddy survey="7676FB1FF2B56CE9"]
14 * [crowdsignal poll=9541291]
15 * [crowdsignal poll=9541291 type=slider]
16 * [crowdsignal rating=8755352]
17 *
18 * @package automattic/jetpack
19 */
20
21// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
22
23use Automattic\Jetpack\Assets;
24use Automattic\Jetpack\Constants;
25
26if ( ! defined( 'ABSPATH' ) ) {
27    exit( 0 );
28}
29
30// Keep compatibility with the PollDaddy plugin.
31if (
32    ! class_exists( 'CrowdsignalShortcode' )
33    && ! class_exists( 'PolldaddyShortcode' )
34) {
35    /**
36     * Class wrapper for Crowdsignal shortcodes
37     *
38     * @phan-constructor-used-for-side-effects
39     */
40    class CrowdsignalShortcode {
41
42        /**
43         * Should the Crowdsignal JavaScript be added to the page?
44         *
45         * @var bool
46         */
47        private static $add_script = false;
48
49        /**
50         * Array of Polls / Surveys present on the page, and that need to be added.
51         *
52         * @var bool|array
53         */
54        private static $scripts = false;
55
56        /**
57         * Add all the actions & register the shortcode.
58         */
59        public function __construct() {
60            add_action( 'init', array( $this, 'register_scripts' ) );
61
62            add_shortcode( 'crowdsignal', array( $this, 'crowdsignal_shortcode' ) );
63            add_shortcode( 'polldaddy', array( $this, 'polldaddy_shortcode' ) );
64
65            if ( jetpack_shortcodes_should_hook_pre_kses() ) {
66                add_filter( 'pre_kses', array( $this, 'crowdsignal_embed_to_shortcode' ) );
67            }
68
69            add_action( 'infinite_scroll_render', array( $this, 'crowdsignal_shortcode_infinite' ), 11 );
70        }
71
72        /**
73         * Register scripts that may be enqueued later on by the shortcode.
74         */
75        public static function register_scripts() {
76            wp_register_script(
77                'crowdsignal-shortcode',
78                Assets::get_file_url_for_environment( '_inc/build/crowdsignal-shortcode.min.js', '_inc/crowdsignal-shortcode.js' ),
79                array(),
80                JETPACK__VERSION,
81                true
82            );
83            wp_register_script(
84                'crowdsignal-survey',
85                Assets::get_file_url_for_environment( '_inc/build/crowdsignal-survey.min.js', '_inc/crowdsignal-survey.js' ),
86                array(),
87                JETPACK__VERSION,
88                true
89            );
90            wp_register_script(
91                'crowdsignal-rating',
92                'https://polldaddy.com/js/rating/rating.js',
93                array(),
94                JETPACK__VERSION,
95                true
96            );
97        }
98
99        /**
100         * JavaScript code for a specific survey / poll.
101         *
102         * @param array  $settings Array of information about a survey / poll.
103         * @param string $survey_link HTML link tag for a specific survey or poll.
104         * @param string $survey_url  Link to the survey or poll.
105         */
106        private function get_async_code( array $settings, $survey_link, $survey_url ) {
107            wp_enqueue_script( 'crowdsignal-survey' );
108
109            if ( 'button' === $settings['type'] ) {
110                $placeholder = sprintf(
111                    '<a class="cs-embed pd-embed" href="%1$s" data-settings="%2$s">%3$s</a>',
112                    esc_url( $survey_url ),
113                    esc_attr( wp_json_encode( $settings, JSON_HEX_AMP | JSON_UNESCAPED_SLASHES ) ),
114                    esc_html( $settings['title'] )
115                );
116            } else {
117                $placeholder = sprintf(
118                    '<div class="cs-embed pd-embed" data-settings="%1$s"></div><noscript>%2$s</noscript>',
119                    esc_attr( wp_json_encode( $settings, JSON_HEX_AMP | JSON_UNESCAPED_SLASHES ) ),
120                    $survey_link
121                );
122            }
123
124            return $placeholder;
125        }
126
127        /**
128         * Crowdsignal Poll Embed script - transforms code that looks like that:
129         * <script type="text/javascript" charset="utf-8" async src="http://static.polldaddy.com/p/123456.js"></script>
130         * <noscript><a href="http://polldaddy.com/poll/123456/">What is your favourite color?</a></noscript>
131         * into the [crowdsignal poll=...] shortcode format
132         *
133         * @param string $content Post content.
134         */
135        public function crowdsignal_embed_to_shortcode( $content ) {
136
137            if ( ! is_string( $content ) || ! str_contains( $content, 'polldaddy.com/p/' ) ) {
138                return $content;
139            }
140
141            $regexes = array();
142
143            $regexes[] = '#<script[^>]+?src="https?://(secure|static)\.polldaddy\.com/p/([0-9]+)\.js"[^>]*+>\s*?</script>\r?\n?(<noscript>.*?</noscript>)?#i';
144
145            $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';
146
147            foreach ( $regexes as $regex ) {
148                if ( ! preg_match_all( $regex, $content, $matches, PREG_SET_ORDER ) ) {
149                    continue;
150                }
151
152                foreach ( $matches as $match ) {
153                    if ( ! isset( $match[2] ) ) {
154                        continue;
155                    }
156
157                    $id = (int) $match[2];
158
159                    if ( $id > 0 ) {
160                        $content = str_replace( $match[0], " [crowdsignal poll=$id]", $content );
161                        /** This action is documented in modules/shortcodes/youtube.php */
162                        do_action( 'jetpack_embed_to_shortcode', 'crowdsignal', $id );
163                    }
164                }
165            }
166
167            return $content;
168        }
169
170        /**
171         * Support for legacy Polldaddy shortcode.
172         *
173         * @param array $atts Shortcode attributes.
174         */
175        public function polldaddy_shortcode( $atts ) {
176            if ( ! is_array( $atts ) ) {
177                return '<!-- Polldaddy shortcode passed invalid attributes -->';
178            }
179
180            $atts['site'] = 'polldaddy.com';
181            return $this->crowdsignal_shortcode( $atts );
182        }
183
184        /**
185         * Shortcode for Crowdsignal
186         * [crowdsignal poll|survey|rating="123456"]
187         *
188         * @param array $atts Shortcode attributes.
189         */
190        public function crowdsignal_shortcode( $atts ) {
191            global $post;
192            global $content_width;
193
194            if ( ! is_array( $atts ) ) {
195                return '<!-- Crowdsignal shortcode passed invalid attributes -->';
196            }
197
198            $attributes = shortcode_atts(
199                array(
200                    'survey'     => null,
201                    'link_text'  => esc_html__( 'Take Our Survey', 'jetpack' ),
202                    'poll'       => 'empty',
203                    'rating'     => 'empty',
204                    'unique_id'  => null,
205                    'item_id'    => null,
206                    'title'      => null,
207                    'permalink'  => null,
208                    'cb'         => 0, // cache buster. Helps with testing.
209                    'type'       => 'button',
210                    'body'       => '',
211                    'button'     => '',
212                    'text_color' => '000000',
213                    'back_color' => 'FFFFFF',
214                    'align'      => '',
215                    'style'      => '',
216                    'width'      => $content_width,
217                    'height'     => floor( $content_width * 3 / 4 ),
218                    'delay'      => 100,
219                    'visit'      => 'single',
220                    'domain'     => '',
221                    'id'         => '',
222                    'site'       => 'crowdsignal.com',
223                ),
224                $atts,
225                'crowdsignal'
226            );
227
228            $inline = ! in_the_loop()
229                && ! Constants::is_defined( 'TESTING_IN_JETPACK' );
230
231            $infinite_scroll = false;
232
233            if ( is_home() && current_theme_supports( 'infinite-scroll' ) ) {
234                $infinite_scroll = true;
235            }
236
237            if ( function_exists( 'get_option' ) && get_option( 'polldaddy_load_poll_inline' ) ) {
238                $inline = true;
239            }
240
241            self::$add_script = $infinite_scroll;
242
243            /*
244             * Rating embed.
245             */
246            if ( (int) $attributes['rating'] > 0 ) {
247                $post_id = $post instanceof WP_Post ? $post->ID : get_the_ID();
248                $post_id = $post_id ?? '';
249
250                if ( empty( $attributes['unique_id'] ) ) {
251                    $attributes['unique_id'] = is_page() ? 'wp-page-' . $post_id : 'wp-post-' . $post_id;
252                }
253
254                if ( empty( $attributes['item_id'] ) ) {
255                    $attributes['item_id'] = is_page() ? '_page_' . $post_id : '_post_' . $post_id;
256                }
257
258                if ( empty( $attributes['title'] ) ) {
259                    $title = $post instanceof WP_Post ? $post->post_title : get_the_title();
260                    /** This filter is documented in core/src/wp-includes/general-template.php */
261                    $attributes['title'] = apply_filters( 'wp_title', $title, '', '' );
262                }
263
264                if ( empty( $attributes['permalink'] ) ) {
265                    if ( $post_id ) {
266                        $attributes['permalink'] = get_permalink( $post_id );
267                    } else {
268                        $attributes['permalink'] = home_url( add_query_arg( array() ) );
269                    }
270                }
271
272                $rating    = (int) $attributes['rating'];
273                $unique_id = sanitize_key( wp_strip_all_tags( $attributes['unique_id'] ) );
274                $item_id   = wp_strip_all_tags( $attributes['item_id'] );
275                $item_id   = preg_replace( '/[^_a-z0-9]/i', '', $item_id );
276
277                $settings = wp_json_encode(
278                    array(
279                        'id'        => $rating,
280                        'unique_id' => $unique_id,
281                        'title'     => rawurlencode( trim( $attributes['title'] ) ),
282                        'permalink' => esc_url( $attributes['permalink'] ),
283                        'item_id'   => $item_id,
284                    ),
285                    JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP
286                );
287
288                if (
289                    class_exists( 'Jetpack_AMP_Support' )
290                    && Jetpack_AMP_Support::is_amp_request()
291                ) {
292                    return sprintf(
293                        '<a href="%s" target="_blank">%s</a>',
294                        esc_url( $attributes['permalink'] ),
295                        esc_html( trim( $attributes['title'] ) )
296                    );
297                } elseif ( $inline ) {
298                    $rating_js  = "<!--//--><![CDATA[//><!--\n";
299                    $rating_js .= "PDRTJS_settings_{$rating}{$item_id}={$settings};";
300                    $rating_js .= "\n//--><!]]>";
301
302                    wp_enqueue_script( 'crowdsignal-rating' );
303                    wp_add_inline_script(
304                        'crowdsignal-rating',
305                        $rating_js,
306                        'before'
307                    );
308
309                    return sprintf(
310                        '<div class="cs-rating pd-rating" id="pd_rating_holder_%1$d%2$s"></div>',
311                        absint( $rating ),
312                        esc_attr( $item_id )
313                    );
314                } else {
315                    if ( false === self::$scripts ) {
316                        self::$scripts = array();
317                    }
318
319                    $data = array(
320                        'id'       => $rating,
321                        'item_id'  => $item_id,
322                        'settings' => $settings,
323                    );
324
325                    self::$scripts['rating'][] = $data;
326
327                    add_action( 'wp_footer', array( $this, 'generate_scripts' ) );
328
329                    if ( $infinite_scroll ) {
330                        return sprintf(
331                            '<div class="cs-rating pd-rating" id="pd_rating_holder_%1$d%2$s" data-settings="%3$s"></div>',
332                            absint( $rating ),
333                            esc_attr( $item_id ),
334                            esc_attr( wp_json_encode( $data, JSON_HEX_AMP | JSON_UNESCAPED_SLASHES ) )
335                        );
336                    } else {
337                        return sprintf(
338                            '<div class="cs-rating pd-rating" id="pd_rating_holder_%1$d%2$s"></div>',
339                            absint( $rating ),
340                            esc_attr( $item_id )
341                        );
342                    }
343                }
344            } elseif ( (int) $attributes['poll'] > 0 ) {
345                /*
346                 * Poll embed.
347                 */
348
349                if ( empty( $attributes['title'] ) ) {
350                    $attributes['title'] = esc_html__( 'Take Our Poll', 'jetpack' );
351                }
352
353                $poll = (int) $attributes['poll'];
354
355                if ( 'crowdsignal.com' === $attributes['site'] ) {
356                    $poll_url = sprintf( 'https://poll.fm/%d', $poll );
357                } else {
358                    $poll_url = sprintf( 'https://polldaddy.com/p/%d', $poll );
359                }
360
361                $poll_js   = sprintf( 'https://secure.polldaddy.com/p/%d.js', $poll );
362                $poll_link = sprintf(
363                    '<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
364                    esc_url( $poll_url ),
365                    esc_html( $attributes['title'] )
366                );
367
368                if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) {
369                    return $poll_link;
370                } elseif ( 'slider' === $attributes['type'] && ! $inline ) { // Slider poll.
371                    if ( ! in_array(
372                        $attributes['visit'],
373                        array( 'single', 'multiple' ),
374                        true
375                    ) ) {
376                        $attributes['visit'] = 'single';
377                    }
378
379                    $settings = array(
380                        'type'  => 'slider',
381                        'embed' => 'poll',
382                        'delay' => (int) $attributes['delay'],
383                        'visit' => $attributes['visit'],
384                        'id'    => $poll,
385                        'site'  => $attributes['site'],
386                    );
387
388                    return $this->get_async_code( $settings, $poll_link, $poll_url );
389                } else {
390                    if ( 1 === $attributes['cb'] ) {
391                        $attributes['cb'] = '?cb=' . time();
392                    } else {
393                        $attributes['cb'] = false;
394                    }
395                    $margins = '';
396                    $float   = '';
397
398                    if ( in_array(
399                        $attributes['align'],
400                        array( 'right', 'left' ),
401                        true
402                    ) ) {
403                        $float = sprintf( 'float: %s;', $attributes['align'] );
404
405                        if ( 'left' === $attributes['align'] ) {
406                            $margins = 'margin: 0 10px 0 0;';
407                        } elseif ( 'right' === $attributes['align'] ) {
408                            $margins = 'margin: 0 0 0 10px';
409                        }
410                    }
411
412                    /*
413                     * Force the normal style embed on single posts/pages
414                     * otherwise it's not rendered on infinite scroll themed blogs
415                     * ('infinite_scroll_render' isn't fired)
416                     */
417                    if ( is_singular() ) {
418                        $inline = true;
419                    }
420
421                    if ( false === $attributes['cb'] && ! $inline ) {
422                        if ( false === self::$scripts ) {
423                            self::$scripts = array();
424                        }
425
426                        $data = array( 'url' => $poll_js );
427
428                        self::$scripts['poll'][ $poll ] = $data;
429
430                        add_action( 'wp_footer', array( $this, 'generate_scripts' ) );
431
432                        wp_enqueue_script( 'crowdsignal-shortcode' );
433                        wp_localize_script(
434                            'crowdsignal-shortcode',
435                            'crowdsignal_shortcode_options',
436                            array(
437                                'script_url' => esc_url_raw(
438                                    Assets::get_file_url_for_environment(
439                                        '_inc/build/polldaddy-shortcode.min.js',
440                                        '_inc/polldaddy-shortcode.js'
441                                    )
442                                ),
443                            )
444                        );
445
446                        /**
447                         * Hook into the Crowdsignal shortcode before rendering.
448                         *
449                         * @since 8.4.0
450                         *
451                         * @param int $poll Poll ID.
452                         */
453                        do_action( 'crowdsignal_shortcode_before', $poll );
454
455                        return sprintf(
456                            '<a name="pd_a_%1$d"></a><div class="CSS_Poll PDS_Poll" id="PDI_container%1$d" data-settings="%2$s" style="%3$s%4$s"></div><div id="PD_superContainer"></div><noscript>%5$s</noscript>',
457                            absint( $poll ),
458                            esc_attr( wp_json_encode( $data, JSON_HEX_AMP | JSON_UNESCAPED_SLASHES ) ),
459                            $float,
460                            $margins,
461                            $poll_link
462                        );
463                    } else {
464                        if ( $inline ) {
465                            $attributes['cb'] = '';
466                        }
467
468                        wp_enqueue_script(
469                            'crowdsignal-' . absint( $poll ),
470                            esc_url( $poll_js . $attributes['cb'] ),
471                            array(),
472                            JETPACK__VERSION,
473                            true
474                        );
475
476                        /** This action is already documented in modules/shortcodes/crowdsignal.php */
477                        do_action( 'crowdsignal_shortcode_before', $poll );
478
479                        return sprintf(
480                            '<a id="pd_a_%1$s"></a><div class="CSS_Poll PDS_Poll" id="PDI_container%1$s" style="%2$s%3$s"></div><div id="PD_superContainer"></div><noscript>%4$s</noscript>',
481                            absint( $poll ),
482                            $float,
483                            $margins,
484                            $poll_link
485                        );
486                    }
487                }
488            } elseif ( ! empty( $attributes['survey'] ) ) {
489                /*
490                 * Survey embed.
491                 */
492
493                if ( in_array(
494                    $attributes['type'],
495                    array( 'iframe', 'button', 'banner', 'slider' ),
496                    true
497                ) ) {
498
499                    if ( empty( $attributes['title'] ) ) {
500                        $attributes['title'] = esc_html__( 'Take Our Survey', 'jetpack' );
501                        if ( ! empty( $attributes['link_text'] ) ) {
502                            $attributes['title'] = $attributes['link_text'];
503                        }
504                    }
505
506                    if (
507                        'banner' === $attributes['type']
508                        || 'slider' === $attributes['type']
509                    ) {
510                        $inline = false;
511                    }
512
513                    $survey_url = '';
514
515                    if ( 'true' !== $attributes['survey'] ) {
516                        $survey = preg_replace( '/[^a-f0-9]/i', '', $attributes['survey'] );
517
518                        if ( 'crowdsignal.com' === $attributes['site'] ) {
519                            $survey_url = 'https://survey.fm/' . $survey;
520                        } else {
521                            $survey_url = 'https://polldaddy.com/s/' . $survey;
522                        }
523                    } elseif ( isset( $attributes['domain'] ) && isset( $attributes['id'] ) ) {
524                        $survey_domain = preg_replace( '/[^a-z0-9\-]/i', '', $attributes['domain'] );
525                        $survey_id     = preg_replace( '/[\/\?&\{\}]/', '', $attributes['id'] );
526                        $survey_url    = sprintf(
527                            'https://%1$s.survey.fm/%2$s',
528                            $survey_domain,
529                            $survey_id
530                        );
531                    }
532
533                    $survey_link = sprintf(
534                        '<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
535                        esc_url( $survey_url ),
536                        esc_html( $attributes['title'] )
537                    );
538
539                    $settings = array();
540
541                    if ( 'iframe' === $attributes['type'] ) {
542                        if ( 'auto' !== $attributes['height'] ) {
543                            if (
544                                is_numeric( $content_width )
545                                && $content_width > 0
546                                && is_numeric( $attributes['width'] )
547                                && $attributes['width'] > $content_width
548                            ) {
549                                $attributes['width'] = $content_width;
550                            }
551
552                            if ( empty( $attributes['width'] ) ) {
553                                $attributes['width'] = '100%';
554                            } else {
555                                $attributes['width'] = (int) $attributes['width'];
556                            }
557
558                            if ( ! $attributes['height'] ) {
559                                $attributes['height'] = '600';
560                            } else {
561                                $attributes['height'] = (int) $attributes['height'];
562                            }
563
564                            return sprintf(
565                                '<iframe src="%1$s?iframe=1" frameborder="0" width="%2$d" height="%3$d" scrolling="auto" allowtransparency="true" marginheight="0" marginwidth="0">%4$s</iframe>',
566                                esc_url( $survey_url ),
567                                absint( $attributes['width'] ),
568                                absint( $attributes['height'] ),
569                                $survey_link
570                            );
571                        } elseif (
572                            ! empty( $attributes['domain'] )
573                            && ! empty( $attributes['id'] )
574                        ) {
575                            $domain = preg_replace( '/[^a-z0-9\-]/i', '', $attributes['domain'] );
576                            $id     = preg_replace( '/[\/\?&\{\}]/', '', $attributes['id'] );
577
578                            $auto_src = esc_url( "https://{$domain}.survey.fm/{$id}" );
579                            $auto_src = wp_parse_url( $auto_src );
580
581                            if ( ! is_array( $auto_src ) || array() === $auto_src ) {
582                                return '<!-- no crowdsignal output -->';
583                            }
584
585                            if ( ! isset( $auto_src['host'] ) || ! isset( $auto_src['path'] ) ) {
586                                return '<!-- no crowdsignal output -->';
587                            }
588
589                            $domain = $auto_src['host'] . '/';
590                            $id     = ltrim( $auto_src['path'], '/' );
591
592                            $settings = array(
593                                'type'   => $attributes['type'],
594                                'auto'   => true,
595                                'domain' => $domain,
596                                'id'     => $id,
597                                'site'   => $attributes['site'],
598                            );
599                        }
600                    } else {
601                        $text_color = sanitize_hex_color_no_hash( $attributes['text_color'] );
602                        $back_color = sanitize_hex_color_no_hash( $attributes['back_color'] );
603
604                        if (
605                            ! in_array(
606                                $attributes['align'],
607                                array(
608                                    'right',
609                                    'left',
610                                    'top-left',
611                                    'top-right',
612                                    'middle-left',
613                                    'middle-right',
614                                    'bottom-left',
615                                    'bottom-right',
616                                ),
617                                true
618                            )
619                        ) {
620                            $attributes['align'] = '';
621                        }
622
623                        if (
624                            ! in_array(
625                                $attributes['style'],
626                                array(
627                                    'inline',
628                                    'side',
629                                    'corner',
630                                    'rounded',
631                                    'square',
632                                ),
633                                true
634                            )
635                        ) {
636                            $attributes['style'] = '';
637                        }
638
639                        $settings = array_filter(
640                            array(
641                                'title'      => wp_strip_all_tags( $attributes['title'] ),
642                                'type'       => $attributes['type'],
643                                'body'       => wp_strip_all_tags( $attributes['body'] ),
644                                'button'     => wp_strip_all_tags( $attributes['button'] ),
645                                'text_color' => $text_color,
646                                'back_color' => $back_color,
647                                'align'      => $attributes['align'],
648                                'style'      => $attributes['style'],
649                                'id'         => $survey ?? null,
650                                'site'       => $attributes['site'],
651                            )
652                        );
653                    }
654
655                    if ( empty( $settings ) ) {
656                        return '<!-- no crowdsignal output -->';
657                    }
658
659                    return $this->get_async_code( $settings, $survey_link, $survey_url );
660                }
661            } else {
662                return '<!-- no crowdsignal output -->';
663            }
664        }
665
666        /**
667         * Enqueue JavaScript containing all ratings / polls on the page.
668         * Hooked into wp_footer
669         */
670        public function generate_scripts() {
671            if ( is_array( self::$scripts ) ) {
672                if ( isset( self::$scripts['rating'] ) ) {
673                    $script = "<!--//--><![CDATA[//><!--\n";
674                    foreach ( self::$scripts['rating'] as $rating ) {
675                        $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']} );}}";
676                    }
677                    $script .= "\n//--><!]]>";
678
679                    wp_enqueue_script( 'crowdsignal-rating' );
680                    wp_add_inline_script(
681                        'crowdsignal-rating',
682                        $script,
683                        'before'
684                    );
685                }
686
687                if ( isset( self::$scripts['poll'] ) ) {
688                    foreach ( self::$scripts['poll'] as $poll_id => $poll ) {
689                        wp_enqueue_script(
690                            'crowdsignal-' . absint( $poll_id ),
691                            esc_url( $poll['url'] ),
692                            array(),
693                            JETPACK__VERSION,
694                            true
695                        );
696                    }
697                }
698            }
699            self::$scripts = false;
700        }
701
702        /**
703         * Dynamically load the .js, if needed
704         *
705         * This hooks in late (priority 11) to infinite_scroll_render to determine
706         * a posteriori if a shortcode has been called.
707         */
708        public function crowdsignal_shortcode_infinite() {
709            // only try to load if a shortcode has been called and theme supports infinite scroll.
710            if ( self::$add_script ) {
711                wp_enqueue_script( 'crowdsignal-shortcode' );
712                wp_localize_script(
713                    'crowdsignal-shortcode',
714                    'crowdsignal_shortcode_options',
715                    array(
716                        'script_url' => esc_url_raw(
717                            Assets::get_file_url_for_environment(
718                                '_inc/build/polldaddy-shortcode.min.js',
719                                '_inc/polldaddy-shortcode.js'
720                            )
721                        ),
722                    )
723                );
724            }
725        }
726    }
727
728    // Kick it all off.
729    new CrowdsignalShortcode();
730
731    if ( ! function_exists( 'crowdsignal_link' ) ) {
732        /**
733         * Replace link with shortcode.
734         * Examples: https://poll.fm/10499328 | https://7iger.survey.fm/test-embed
735         *
736         * @param string $content Post content.
737         */
738        function crowdsignal_link( $content ) {
739            if (
740                class_exists( 'Jetpack_AMP_Support' )
741                && Jetpack_AMP_Support::is_amp_request()
742            ) {
743                return $content;
744            }
745
746            // Replace poll links.
747            $content = jetpack_preg_replace_outside_tags(
748                '!(?:\n|\A)https?://(polldaddy\.com/poll|poll\.fm)/([0-9]+?)(/.*)?(?:\n|\Z)!i',
749                '[crowdsignal poll=$2]',
750                $content
751            );
752
753            // Replace survey.fm links.
754            $content = jetpack_preg_replace_outside_tags(
755                '!(?:\n|\A)https?:\/\/([^"\'.]+)\.survey\.fm\/([^"\'\/\s]+)(?:\/.*)?(?:\n|\Z)!i',
756                '[crowdsignal type="iframe" survey="true" height="auto" domain="$1" id="$2"]',
757                $content
758            );
759
760            return $content;
761        }
762
763        // higher priority because we need it before auto-link and autop get to it.
764        add_filter( 'the_content', 'crowdsignal_link', 1 );
765        add_filter( 'the_content_rss', 'crowdsignal_link', 1 );
766    }
767}