PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 15.9-a.7
Jetpack – WP Security, Backup, Speed, & Growth v15.9-a.7
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 2 weeks ago images 1 year ago img 4 weeks ago js 6 months ago archiveorg-book.php 6 months ago archiveorg.php 6 months ago archives.php 2 weeks ago bandcamp.php 6 months ago brightcove.php 5 months ago cartodb.php 6 months ago class.filter-embedded-html-objects.php 6 months ago codepen.php 6 months ago crowdsignal.php 5 months ago dailymotion.php 6 months ago descript.php 6 months ago facebook.php 6 months ago flatio.php 6 months ago flickr.php 5 months ago getty.php 6 months ago gist.php 6 months ago googleapps.php 6 months ago googlemaps.php 3 weeks ago googleplus.php 6 months ago gravatar.php 6 months ago houzz.php 6 months ago inline-pdfs.php 6 months ago instagram.php 6 months ago kickstarter.php 6 months ago mailchimp.php 5 months ago medium.php 6 months ago mixcloud.php 6 months ago others.php 6 months ago pinterest.php 6 months ago presentations.php 6 months ago quiz.php 6 months ago recipe.php 6 months ago scribd.php 6 months ago shortcode-utils.php 6 months ago sitemap.php 6 months ago slideshare.php 6 months ago slideshow.php 4 weeks ago smartframe.php 6 months ago soundcloud.php 6 months ago spotify.php 6 months ago ted.php 6 months ago tweet.php 6 months ago twitchtv.php 6 months ago twitter-timeline.php 6 months ago twitter.php 6 months ago unavailable.php 6 months ago untappd-menu.php 6 months ago upcoming-events.php 6 months ago ustream.php 6 months ago videopress.php 6 months ago vimeo.php 1 week ago vine.php 6 months ago vr.php 1 week ago wufoo.php 6 months ago youtube.php 3 months 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