PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 15.2.1
Jetpack – WP Security, Backup, Speed, & Growth v15.2.1
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 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / modules / shortcodes / quiz.php
jetpack / modules / shortcodes Last commit date
css 10 months ago images 2 years ago img 2 years ago js 9 months ago archiveorg-book.php 1 year ago archiveorg.php 1 year ago archives.php 1 year ago bandcamp.php 11 months ago brightcove.php 1 year ago cartodb.php 1 year ago class.filter-embedded-html-objects.php 1 year ago codepen.php 1 year ago crowdsignal.php 9 months ago dailymotion.php 1 year ago descript.php 1 year ago facebook.php 1 year ago flatio.php 1 year ago flickr.php 11 months ago getty.php 1 year ago gist.php 1 year ago googleapps.php 1 year ago googlemaps.php 1 year ago googleplus.php 1 year ago gravatar.php 1 year ago houzz.php 1 year ago inline-pdfs.php 1 year ago instagram.php 1 year ago kickstarter.php 1 year ago mailchimp.php 1 year ago medium.php 1 year ago mixcloud.php 1 year ago others.php 1 year ago pinterest.php 1 year ago presentations.php 1 year ago quiz.php 1 year ago recipe.php 11 months ago scribd.php 1 year ago shortcode-utils.php 1 year ago sitemap.php 1 year ago slideshare.php 9 months ago slideshow.php 11 months ago smartframe.php 1 year ago soundcloud.php 1 year ago spotify.php 1 year ago ted.php 11 months ago tweet.php 1 year ago twitchtv.php 1 year ago twitter-timeline.php 1 year ago twitter.php 1 year ago unavailable.php 1 year ago untappd-menu.php 1 year ago upcoming-events.php 1 year ago ustream.php 1 year ago videopress.php 1 year ago vimeo.php 1 year ago vine.php 1 year ago vr.php 1 year ago wufoo.php 1 year ago youtube.php 1 year ago
quiz.php
369 lines
1 <?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileNam
2
3 use Automattic\Jetpack\Assets;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit( 0 );
7 }
8
9 /**
10 * Quiz shortcode.
11 *
12 * Usage:
13 *
14 * [quiz]
15 * [question]What's the right answer?[/question]
16 * [wrong]This one?[explanation]Nope[/explanation][/wrong]
17 * [answer]Yes, this is the one![explanation]Yay![/explanation][/answer]
18 * [wrong]Maybe this one[explanation]Keep trying[/explanation][/wrong]
19 * [wrong]How about this one?[explanation]Try again[/explanation][/wrong]
20 * [/quiz]
21 *
22 * Can also be wrapped in [quiz-wrapper] to display all quizzes together.
23 */
24 class Quiz_Shortcode {
25
26 /**
27 * Parameters admitted by [quiz] shortcode.
28 *
29 * @since 4.5.0
30 *
31 * @var array
32 */
33 private static $quiz_params = array();
34
35 /**
36 * Whether the [quiz-wrapper] shortcode is used.
37 *
38 * @since 10.1
39 *
40 * @var bool
41 */
42 private static $quiz_wrapper = false;
43
44 /**
45 * Whether the scripts were enqueued.
46 *
47 * @since 4.5.0
48 *
49 * @var bool
50 */
51 private static $scripts_enqueued = false;
52
53 /**
54 * In a8c training, store user currently logged in.
55 *
56 * @since 4.5.0
57 *
58 * @var null
59 */
60 private static $username = null;
61
62 /**
63 * Whether the noscript tag was already printed.
64 *
65 * @since 4.5.0
66 *
67 * @var bool
68 */
69 private static $noscript_info_printed = false;
70
71 /**
72 * Whether JavaScript is available.
73 *
74 * @since 4.5.0
75 *
76 * @var null
77 */
78 private static $javascript_unavailable = null;
79
80 /**
81 * Register all shortcodes.
82 *
83 * @since 4.5.0
84 */
85 public static function init() {
86 add_shortcode( 'quiz-wrapper', array( __CLASS__, 'shortcode_wrapper' ) );
87 add_shortcode( 'quiz', array( __CLASS__, 'shortcode' ) );
88 add_shortcode( 'question', array( __CLASS__, 'question_shortcode' ) );
89 add_shortcode( 'answer', array( __CLASS__, 'answer_shortcode' ) );
90 add_shortcode( 'wrong', array( __CLASS__, 'wrong_shortcode' ) );
91 add_shortcode( 'explanation', array( __CLASS__, 'explanation_shortcode' ) );
92 }
93
94 /**
95 * Enqueue assets needed by the quiz,
96 *
97 * @since 4.5.0
98 */
99 private static function enqueue_scripts() {
100 wp_enqueue_style( 'quiz', plugins_url( 'css/quiz.css', __FILE__ ), array(), JETPACK__VERSION );
101 wp_enqueue_script(
102 'quiz',
103 Assets::get_file_url_for_environment( '_inc/build/shortcodes/js/quiz.min.js', 'modules/shortcodes/js/quiz.js' ),
104 array( 'jquery' ),
105 JETPACK__VERSION,
106 true
107 );
108 }
109
110 /**
111 * Check if this is a feed and thus JS is unavailable.
112 *
113 * @since 4.5.0
114 *
115 * @return bool|null
116 */
117 private static function is_javascript_unavailable() {
118 if ( self::$javascript_unavailable !== null ) {
119 return self::$javascript_unavailable;
120 }
121
122 if ( is_feed() ) {
123 self::$javascript_unavailable = true;
124 return self::$javascript_unavailable;
125 }
126
127 self::$javascript_unavailable = false;
128 return self::$javascript_unavailable;
129 }
130
131 /**
132 * Display message when JS is not available.
133 *
134 * @since 4.5.0
135 *
136 * @return string
137 */
138 private static function noscript_info() {
139 if ( self::$noscript_info_printed ) {
140 return '';
141 }
142 self::$noscript_info_printed = true;
143 return '<noscript><div><i>' . esc_html__( 'Please view this post in your web browser to complete the quiz.', 'jetpack' ) . '</i></div></noscript>';
144 }
145
146 /**
147 * Check if we're in WordPress.com.
148 *
149 * @since 4.5.0
150 *
151 * @return bool
152 */
153 public static function is_wpcom() {
154 return defined( 'IS_WPCOM' ) && IS_WPCOM;
155 }
156
157 /**
158 * Parse shortcode arguments and render its output.
159 *
160 * @since 4.5.0
161 *
162 * @param array $atts Shortcode parameters.
163 * @param string $content Content enclosed by shortcode tags.
164 *
165 * @return string
166 */
167 public static function shortcode( $atts, $content = null ) {
168
169 // There's nothing to do if there's nothing enclosed.
170 if ( empty( $content ) ) {
171 return '';
172 }
173
174 $id = '';
175
176 if ( self::is_javascript_unavailable() ) {
177 // in an e-mail print the question and the info sentence once per question, too.
178 self::$noscript_info_printed = false;
179 } else {
180
181 if ( ! self::$scripts_enqueued ) {
182 // lazy enqueue cannot use the wp_enqueue_scripts action anymore.
183 self::enqueue_scripts();
184 self::$scripts_enqueued = true;
185 }
186
187 $default_atts = self::is_wpcom()
188 ? array(
189 'trackid' => '',
190 'a8ctraining' => '',
191 )
192 : array(
193 'trackid' => '',
194 );
195
196 self::$quiz_params = shortcode_atts( $default_atts, $atts );
197
198 if ( ! empty( self::$quiz_params['trackid'] ) ) {
199 $id .= ' data-trackid="' . esc_attr( self::$quiz_params['trackid'] ) . '"';
200 }
201 if ( self::is_wpcom() && ! empty( self::$quiz_params['a8ctraining'] ) ) {
202 if ( self::$username === null ) {
203 self::$username = wp_get_current_user()->user_login;
204 }
205 $id .= ' data-a8ctraining="' . esc_attr( self::$quiz_params['a8ctraining'] ) . '" data-username="' . esc_attr( self::$username ) . '"';
206 }
207 }
208
209 $quiz = self::do_shortcode( $content );
210 $quiz_options = '';
211
212 if ( self::$quiz_wrapper ) {
213 $quiz_options = '<div class="jetpack-quiz-options">
214 <span class="jetpack-quiz-count"></span>
215 <a class="jetpack-quiz-option-button" data-quiz-option="previous" role="button" aria-label="' . esc_attr__( 'Previous quiz', 'jetpack' ) . '">
216 <svg viewBox="0 0 24 24" class="quiz-gridicon">
217 <g><path d="M14 20l-8-8 8-8 1.414 1.414L8.828 12l6.586 6.586"></path></g></svg></a>
218 <a class="jetpack-quiz-option-button" data-quiz-option="next" role="button" aria-label="' . esc_attr__( 'Next quiz', 'jetpack' ) . '">
219 <svg viewBox="0 0 24 24" class="quiz-gridicon">
220 <g><path d="M10 20l8-8-8-8-1.414 1.414L15.172 12l-6.586 6.586"></path></g></svg></a>
221 </div>';
222 }
223
224 return '<div class="jetpack-quiz quiz"' . $id . '>' . $quiz . $quiz_options . '</div>';
225 }
226
227 /**
228 * Wrap shortcode contents.
229 *
230 * @since 10.1
231 *
232 * @param array $atts Shortcode parameters.
233 * @param string $content Content enclosed by shortcode tags.
234 *
235 * @return string
236 */
237 public static function shortcode_wrapper( $atts, $content = null ) {
238 self::$quiz_wrapper = true;
239 return '<div class="jetpack-quiz-wrapper">' . self::do_shortcode( $content ) . '</div>';
240 }
241
242 /**
243 * Strip line breaks, restrict allowed HTML to a few allowed tags and execute nested shortcodes.
244 *
245 * @since 4.5.0
246 *
247 * @param string $content Post content.
248 *
249 * @return mixed|string
250 */
251 private static function do_shortcode( $content ) {
252 // strip autoinserted line breaks.
253 $content = preg_replace( '#(<(?:br /|/?p)>\n?)*(\[/?[a-z]+\])(<(?:br /|/?p)>\n?)*#', '$2', $content );
254
255 // Add internal parameter so it's only rendered when it has it.
256 $content = preg_replace( '/\[(question|answer|wrong|explanation)\]/i', '[$1 quiz_item="true"]', $content );
257 $content = do_shortcode( $content );
258 $content = wp_kses(
259 $content,
260 array(
261 'tt' => array(),
262 'a' => array(
263 'href' => true,
264 'class' => true,
265 'data-quiz-option' => true,
266 'aria-label' => true,
267 'role' => 'button',
268 ),
269 'pre' => array(),
270 'strong' => array(),
271 'i' => array(),
272 'svg' => array(),
273 'g' => array(),
274 'path' => array( 'd' => true ),
275 'br' => array(),
276 'span' => array( 'class' => true ),
277 'img' => array( 'src' => true ),
278 'div' => array(
279 'class' => true,
280 'data-correct' => 1,
281 'data-track-id' => 1,
282 'data-a8ctraining' => 1,
283 'data-username' => 1,
284 'tabindex' => false,
285 ),
286 )
287 );
288 return $content;
289 }
290
291 /**
292 * Render question.
293 *
294 * @since 4.5.0
295 *
296 * @param array $atts Shortcode attributes.
297 * @param null $content Post content.
298 *
299 * @return string
300 */
301 public static function question_shortcode( $atts, $content = null ) {
302 return isset( $atts['quiz_item'] )
303 ? '<div class="jetpack-quiz-question question" tabindex="-1">' . self::do_shortcode( $content ) . '</div>'
304 : '';
305 }
306
307 /**
308 * Render correct answer.
309 *
310 * @since 4.5.0
311 *
312 * @param array $atts Shortcode attributes.
313 * @param null $content Post content.
314 *
315 * @return string
316 */
317 public static function answer_shortcode( $atts, $content = null ) {
318 if ( self::is_javascript_unavailable() ) {
319 return self::noscript_info();
320 }
321
322 return isset( $atts['quiz_item'] )
323 ? '<div class="jetpack-quiz-answer answer" data-correct="1">' . self::do_shortcode( $content ) . '</div>'
324 : '';
325 }
326
327 /**
328 * Render wrong response.
329 *
330 * @since 4.5.0
331 *
332 * @param array $atts Shortcode attributes.
333 * @param null $content Post content.
334 *
335 * @return string
336 */
337 public static function wrong_shortcode( $atts, $content = null ) {
338 if ( self::is_javascript_unavailable() ) {
339 return self::noscript_info();
340 }
341
342 return isset( $atts['quiz_item'] )
343 ? '<div class="jetpack-quiz-answer answer">' . self::do_shortcode( $content ) . '</div>'
344 : '';
345 }
346
347 /**
348 * Render explanation for wrong or right answer.
349 *
350 * @since 4.5.0
351 *
352 * @param array $atts Shortcode attributes.
353 * @param null $content Post content.
354 *
355 * @return string
356 */
357 public static function explanation_shortcode( $atts, $content = null ) {
358 if ( self::is_javascript_unavailable() ) {
359 return self::noscript_info();
360 }
361
362 return isset( $atts['quiz_item'] )
363 ? '<div class="jetpack-quiz-explanation explanation">' . self::do_shortcode( $content ) . '</div>'
364 : '';
365 }
366 }
367
368 Quiz_Shortcode::init();
369