PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 11.1.1
Jetpack – WP Security, Backup, Speed, & Growth v11.1.1
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 4 years ago images 12 years ago img 13 years ago js 4 years ago archiveorg-book.php 4 years ago archiveorg.php 4 years ago archives.php 5 years ago bandcamp.php 5 years ago brightcove.php 5 years ago cartodb.php 5 years ago class.filter-embedded-html-objects.php 5 years ago codepen.php 5 years ago crowdsignal.php 5 years ago dailymotion.php 4 years ago descript.php 4 years ago facebook.php 5 years ago flatio.php 5 years ago flickr.php 5 years ago getty.php 5 years ago gist.php 5 years ago googleapps.php 5 years ago googlemaps.php 5 years ago googleplus.php 5 years ago gravatar.php 5 years ago houzz.php 5 years ago inline-pdfs.php 4 years ago instagram.php 4 years ago kickstarter.php 5 years ago mailchimp.php 5 years ago medium.php 5 years ago mixcloud.php 5 years ago others.php 5 years ago pinterest.php 5 years ago presentations.php 5 years ago quiz.php 4 years ago recipe.php 5 years ago scribd.php 5 years ago sitemap.php 5 years ago slideshare.php 5 years ago slideshow.php 4 years ago smartframe.php 4 years ago soundcloud.php 4 years ago spotify.php 4 years ago ted.php 5 years ago tweet.php 5 years ago twitchtv.php 5 years ago twitter-timeline.php 5 years ago unavailable.php 4 years ago untappd-menu.php 5 years ago upcoming-events.php 5 years ago ustream.php 5 years ago videopress.php 5 years ago vimeo.php 4 years ago vine.php 5 years ago vr.php 4 years ago wordads.php 5 years ago wufoo.php 4 years ago youtube.php 4 years ago
quiz.php
365 lines
1 <?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileNam
2
3 use Automattic\Jetpack\Assets;
4
5 /**
6 * Quiz shortcode.
7 *
8 * Usage:
9 *
10 * [quiz]
11 * [question]What's the right answer?[/question]
12 * [wrong]This one?[explanation]Nope[/explanation][/wrong]
13 * [answer]Yes, this is the one![explanation]Yay![/explanation][/answer]
14 * [wrong]Maybe this one[explanation]Keep trying[/explanation][/wrong]
15 * [wrong]How about this one?[explanation]Try again[/explanation][/wrong]
16 * [/quiz]
17 *
18 * Can also be wrapped in [quiz-wrapper] to display all quizzes together.
19 */
20 class Quiz_Shortcode {
21
22 /**
23 * Parameters admitted by [quiz] shortcode.
24 *
25 * @since 4.5.0
26 *
27 * @var array
28 */
29 private static $quiz_params = array();
30
31 /**
32 * Whether the [quiz-wrapper] shortcode is used.
33 *
34 * @since 10.1
35 *
36 * @var bool
37 */
38 private static $quiz_wrapper = false;
39
40 /**
41 * Whether the scripts were enqueued.
42 *
43 * @since 4.5.0
44 *
45 * @var bool
46 */
47 private static $scripts_enqueued = false;
48
49 /**
50 * In a8c training, store user currently logged in.
51 *
52 * @since 4.5.0
53 *
54 * @var null
55 */
56 private static $username = null;
57
58 /**
59 * Whether the noscript tag was already printed.
60 *
61 * @since 4.5.0
62 *
63 * @var bool
64 */
65 private static $noscript_info_printed = false;
66
67 /**
68 * Whether JavaScript is available.
69 *
70 * @since 4.5.0
71 *
72 * @var null
73 */
74 private static $javascript_unavailable = null;
75
76 /**
77 * Register all shortcodes.
78 *
79 * @since 4.5.0
80 */
81 public static function init() {
82 add_shortcode( 'quiz-wrapper', array( __CLASS__, 'shortcode_wrapper' ) );
83 add_shortcode( 'quiz', array( __CLASS__, 'shortcode' ) );
84 add_shortcode( 'question', array( __CLASS__, 'question_shortcode' ) );
85 add_shortcode( 'answer', array( __CLASS__, 'answer_shortcode' ) );
86 add_shortcode( 'wrong', array( __CLASS__, 'wrong_shortcode' ) );
87 add_shortcode( 'explanation', array( __CLASS__, 'explanation_shortcode' ) );
88 }
89
90 /**
91 * Enqueue assets needed by the quiz,
92 *
93 * @since 4.5.0
94 */
95 private static function enqueue_scripts() {
96 wp_enqueue_style( 'quiz', plugins_url( 'css/quiz.css', __FILE__ ), array(), JETPACK__VERSION );
97 wp_enqueue_script(
98 'quiz',
99 Assets::get_file_url_for_environment( '_inc/build/shortcodes/js/quiz.min.js', 'modules/shortcodes/js/quiz.js' ),
100 array( 'jquery' ),
101 JETPACK__VERSION,
102 true
103 );
104 }
105
106 /**
107 * Check if this is a feed and thus JS is unavailable.
108 *
109 * @since 4.5.0
110 *
111 * @return bool|null
112 */
113 private static function is_javascript_unavailable() {
114 if ( self::$javascript_unavailable !== null ) {
115 return self::$javascript_unavailable;
116 }
117
118 if ( is_feed() ) {
119 self::$javascript_unavailable = true;
120 return self::$javascript_unavailable;
121 }
122
123 self::$javascript_unavailable = false;
124 return self::$javascript_unavailable;
125 }
126
127 /**
128 * Display message when JS is not available.
129 *
130 * @since 4.5.0
131 *
132 * @return string
133 */
134 private static function noscript_info() {
135 if ( self::$noscript_info_printed ) {
136 return '';
137 }
138 self::$noscript_info_printed = true;
139 return '<noscript><div><i>' . esc_html__( 'Please view this post in your web browser to complete the quiz.', 'jetpack' ) . '</i></div></noscript>';
140 }
141
142 /**
143 * Check if we're in WordPress.com.
144 *
145 * @since 4.5.0
146 *
147 * @return bool
148 */
149 public static function is_wpcom() {
150 return defined( 'IS_WPCOM' ) && IS_WPCOM;
151 }
152
153 /**
154 * Parse shortcode arguments and render its output.
155 *
156 * @since 4.5.0
157 *
158 * @param array $atts Shortcode parameters.
159 * @param string $content Content enclosed by shortcode tags.
160 *
161 * @return string
162 */
163 public static function shortcode( $atts, $content = null ) {
164
165 // There's nothing to do if there's nothing enclosed.
166 if ( empty( $content ) ) {
167 return '';
168 }
169
170 $id = '';
171
172 if ( self::is_javascript_unavailable() ) {
173 // in an e-mail print the question and the info sentence once per question, too.
174 self::$noscript_info_printed = false;
175 } else {
176
177 if ( ! self::$scripts_enqueued ) {
178 // lazy enqueue cannot use the wp_enqueue_scripts action anymore.
179 self::enqueue_scripts();
180 self::$scripts_enqueued = true;
181 }
182
183 $default_atts = self::is_wpcom()
184 ? array(
185 'trackid' => '',
186 'a8ctraining' => '',
187 )
188 : array(
189 'trackid' => '',
190 );
191
192 self::$quiz_params = shortcode_atts( $default_atts, $atts );
193
194 if ( ! empty( self::$quiz_params['trackid'] ) ) {
195 $id .= ' data-trackid="' . esc_attr( self::$quiz_params['trackid'] ) . '"';
196 }
197 if ( self::is_wpcom() && ! empty( self::$quiz_params['a8ctraining'] ) ) {
198 if ( self::$username === null ) {
199 self::$username = wp_get_current_user()->user_login;
200 }
201 $id .= ' data-a8ctraining="' . esc_attr( self::$quiz_params['a8ctraining'] ) . '" data-username="' . esc_attr( self::$username ) . '"';
202 }
203 }
204
205 $quiz = self::do_shortcode( $content );
206 $quiz_options = '';
207
208 if ( self::$quiz_wrapper ) {
209 $quiz_options = '<div class="jetpack-quiz-options">
210 <span class="jetpack-quiz-count"></span>
211 <a class="jetpack-quiz-option-button" data-quiz-option="previous" role="button" aria-label="' . esc_attr__( 'Previous quiz', 'jetpack' ) . '">
212 <svg viewBox="0 0 24 24" class="quiz-gridicon">
213 <g><path d="M14 20l-8-8 8-8 1.414 1.414L8.828 12l6.586 6.586"></path></g></svg></a>
214 <a class="jetpack-quiz-option-button" data-quiz-option="next" role="button" aria-label="' . esc_attr__( 'Next quiz', 'jetpack' ) . '">
215 <svg viewBox="0 0 24 24" class="quiz-gridicon">
216 <g><path d="M10 20l8-8-8-8-1.414 1.414L15.172 12l-6.586 6.586"></path></g></svg></a>
217 </div>';
218 }
219
220 return '<div class="jetpack-quiz quiz"' . $id . '>' . $quiz . $quiz_options . '</div>';
221 }
222
223 /**
224 * Wrap shortcode contents.
225 *
226 * @since 10.1
227 *
228 * @param array $atts Shortcode parameters.
229 * @param string $content Content enclosed by shortcode tags.
230 *
231 * @return string
232 */
233 public static function shortcode_wrapper( $atts, $content = null ) {
234 self::$quiz_wrapper = true;
235 return '<div class="jetpack-quiz-wrapper">' . self::do_shortcode( $content ) . '</div>';
236 }
237
238 /**
239 * Strip line breaks, restrict allowed HTML to a few allowed tags and execute nested shortcodes.
240 *
241 * @since 4.5.0
242 *
243 * @param string $content Post content.
244 *
245 * @return mixed|string
246 */
247 private static function do_shortcode( $content ) {
248 // strip autoinserted line breaks.
249 $content = preg_replace( '#(<(?:br /|/?p)>\n?)*(\[/?[a-z]+\])(<(?:br /|/?p)>\n?)*#', '$2', $content );
250
251 // Add internal parameter so it's only rendered when it has it.
252 $content = preg_replace( '/\[(question|answer|wrong|explanation)\]/i', '[$1 quiz_item="true"]', $content );
253 $content = do_shortcode( $content );
254 $content = wp_kses(
255 $content,
256 array(
257 'tt' => array(),
258 'a' => array(
259 'href' => true,
260 'class' => true,
261 'data-quiz-option' => true,
262 'aria-label' => true,
263 'role' => 'button',
264 ),
265 'pre' => array(),
266 'strong' => array(),
267 'i' => array(),
268 'svg' => array(),
269 'g' => array(),
270 'path' => array( 'd' => true ),
271 'br' => array(),
272 'span' => array( 'class' => true ),
273 'img' => array( 'src' => true ),
274 'div' => array(
275 'class' => true,
276 'data-correct' => 1,
277 'data-track-id' => 1,
278 'data-a8ctraining' => 1,
279 'data-username' => 1,
280 'tabindex' => false,
281 ),
282 )
283 );
284 return $content;
285 }
286
287 /**
288 * Render question.
289 *
290 * @since 4.5.0
291 *
292 * @param array $atts Shortcode attributes.
293 * @param null $content Post content.
294 *
295 * @return string
296 */
297 public static function question_shortcode( $atts, $content = null ) {
298 return isset( $atts['quiz_item'] )
299 ? '<div class="jetpack-quiz-question question" tabindex="-1">' . self::do_shortcode( $content ) . '</div>'
300 : '';
301 }
302
303 /**
304 * Render correct answer.
305 *
306 * @since 4.5.0
307 *
308 * @param array $atts Shortcode attributes.
309 * @param null $content Post content.
310 *
311 * @return string
312 */
313 public static function answer_shortcode( $atts, $content = null ) {
314 if ( self::is_javascript_unavailable() ) {
315 return self::noscript_info();
316 }
317
318 return isset( $atts['quiz_item'] )
319 ? '<div class="jetpack-quiz-answer answer" data-correct="1">' . self::do_shortcode( $content ) . '</div>'
320 : '';
321 }
322
323 /**
324 * Render wrong response.
325 *
326 * @since 4.5.0
327 *
328 * @param array $atts Shortcode attributes.
329 * @param null $content Post content.
330 *
331 * @return string
332 */
333 public static function wrong_shortcode( $atts, $content = null ) {
334 if ( self::is_javascript_unavailable() ) {
335 return self::noscript_info();
336 }
337
338 return isset( $atts['quiz_item'] )
339 ? '<div class="jetpack-quiz-answer answer">' . self::do_shortcode( $content ) . '</div>'
340 : '';
341 }
342
343 /**
344 * Render explanation for wrong or right answer.
345 *
346 * @since 4.5.0
347 *
348 * @param array $atts Shortcode attributes.
349 * @param null $content Post content.
350 *
351 * @return string
352 */
353 public static function explanation_shortcode( $atts, $content = null ) {
354 if ( self::is_javascript_unavailable() ) {
355 return self::noscript_info();
356 }
357
358 return isset( $atts['quiz_item'] )
359 ? '<div class="jetpack-quiz-explanation explanation">' . self::do_shortcode( $content ) . '</div>'
360 : '';
361 }
362 }
363
364 Quiz_Shortcode::init();
365