Quiz_Shortcode

Quiz shortcode.

Defined (1)

The class is defined in the following location(s).

/modules/shortcodes/quiz.php  
  1. class Quiz_Shortcode { 
  2.  
  3. /** 
  4. * Parameters admitted by [quiz] shortcode. 
  5. * @since 4.5.0 
  6. * @var array 
  7. */ 
  8. private static $quiz_params = array(); 
  9.  
  10. /** 
  11. * Whether the scripts were enqueued. 
  12. * @since 4.5.0 
  13. * @var bool 
  14. */ 
  15. private static $scripts_enqueued = false; 
  16.  
  17. /** 
  18. * In a8c training, store user currently logged in. 
  19. * @since 4.5.0 
  20. * @var null 
  21. */ 
  22. private static $username = null; 
  23.  
  24. /** 
  25. * Whether the noscript tag was already printed. 
  26. * @since 4.5.0 
  27. * @var bool 
  28. */ 
  29. private static $noscript_info_printed = false; 
  30.  
  31. /** 
  32. * Whether JavaScript is available. 
  33. * @since 4.5.0 
  34. * @var null 
  35. */ 
  36. private static $javascript_unavailable = null; 
  37.  
  38. /** 
  39. * Register all shortcodes. 
  40. * @since 4.5.0 
  41. */ 
  42. public static function init() { 
  43. add_shortcode( 'quiz', array( __CLASS__, 'shortcode' ) ); 
  44. add_shortcode( 'question', array( __CLASS__, 'question_shortcode' ) ); 
  45. add_shortcode( 'answer', array( __CLASS__, 'answer_shortcode' ) ); 
  46. add_shortcode( 'wrong', array( __CLASS__, 'wrong_shortcode' ) ); 
  47. add_shortcode( 'explanation', array( __CLASS__, 'explanation_shortcode' ) ); 
  48.  
  49. /** 
  50. * Enqueue assets needed by the quiz,  
  51. * @since 4.5.0 
  52. */ 
  53. private static function enqueue_scripts() { 
  54. wp_enqueue_style( 'quiz', plugins_url( 'css/quiz.css', __FILE__ ) ); 
  55. wp_enqueue_script( 'quiz', plugins_url( 'js/quiz.js', __FILE__ ), array( 'jquery' ), null, true ); 
  56.  
  57. /** 
  58. * Check if this is a feed and thus JS is unavailable. 
  59. * @since 4.5.0 
  60. * @return bool|null 
  61. */ 
  62. private static function is_javascript_unavailable() { 
  63. if ( ! is_null( self::$javascript_unavailable ) ) { 
  64. return self::$javascript_unavailable; 
  65.  
  66. if ( is_feed() ) { 
  67. return self::$javascript_unavailable = true; 
  68.  
  69. return self::$javascript_unavailable = false; 
  70.  
  71. /** 
  72. * Display message when JS is not available. 
  73. * @since 4.5.0 
  74. * @return string 
  75. */ 
  76. private static function noscript_info() { 
  77. if ( self::$noscript_info_printed ) { 
  78. return ''; 
  79. self::$noscript_info_printed = true; 
  80. return '<noscript><div><i>' . esc_html__( 'Please view this post in your web browser to complete the quiz.', 'jetpack' ) . '</i></div></noscript>'; 
  81.  
  82. /** 
  83. * Check if we're in WordPress.com. 
  84. * @since 4.5.0 
  85. * @return bool 
  86. */ 
  87. public static function is_wpcom() { 
  88. return defined( 'IS_WPCOM' ) && IS_WPCOM; 
  89.  
  90. /** 
  91. * Parse shortcode arguments and render its output. 
  92. * @since 4.5.0 
  93. * @param array $atts Shortcode parameters. 
  94. * @param string $content Content enclosed by shortcode tags. 
  95. * @return string 
  96. */ 
  97. public static function shortcode( $atts, $content = null ) { 
  98.  
  99. // There's nothing to do if there's nothing enclosed. 
  100. if ( null == $content ) { 
  101. return ''; 
  102.  
  103. $id = ''; 
  104.  
  105. if ( self::is_javascript_unavailable() ) { 
  106. // in an e-mail print the question and the info sentence once per question, too 
  107. self::$noscript_info_printed = false; 
  108. } else { 
  109.  
  110. if ( ! self::$scripts_enqueued ) { 
  111. // lazy enqueue cannot use the wp_enqueue_scripts action anymore 
  112. self::enqueue_scripts(); 
  113. self::$scripts_enqueued = true; 
  114.  
  115. $default_atts = self::is_wpcom() 
  116. ? array( 
  117. 'trackid' => '',  
  118. 'a8ctraining' => '',  
  119. : array( 
  120. 'trackid' => '',  
  121. ); 
  122.  
  123.  
  124. self::$quiz_params = shortcode_atts( $default_atts, $atts ); 
  125.  
  126. if ( ! empty( self::$quiz_params[ 'trackid' ] ) ) { 
  127. $id .= ' data-trackid="' . esc_attr( self::$quiz_params[ 'trackid' ] ) . '"'; 
  128. if ( self::is_wpcom() && ! empty( self::$quiz_params[ 'a8ctraining' ] ) ) { 
  129. if ( is_null( self::$username ) ) { 
  130. self::$username = wp_get_current_user()->user_login; 
  131. $id .= ' data-a8ctraining="'. esc_attr( self::$quiz_params[ 'a8ctraining' ] ) . '" data-username="' . esc_attr( self::$username ) . '"'; 
  132.  
  133. $quiz = self::do_shortcode( $content ); 
  134. return '<div class="jetpack-quiz quiz"' . $id . '>' . $quiz . '</div>'; 
  135.  
  136. /** 
  137. * Strip line breaks, restrict allowed HTML to a few whitelisted tags and execute nested shortcodes. 
  138. * @since 4.5.0 
  139. * @param string $content 
  140. * @return mixed|string 
  141. */ 
  142. private static function do_shortcode( $content ) { 
  143. // strip autoinserted line breaks 
  144. $content = preg_replace( '#(<(?:br /|/?p)>\n?)*(\[/?[a-z]+\])(<(?:br /|/?p)>\n?)*#', '$2', $content ); 
  145.  
  146. // Add internal parameter so it's only rendered when it has it 
  147. $content = preg_replace( '/\[(question|answer|wrong|explanation)\]/i', '[$1 quiz_item="true"]', $content ); 
  148. $content = do_shortcode( $content ); 
  149. $content = wp_kses( $content, array( 
  150. 'tt' => array(),  
  151. 'pre' => array(),  
  152. 'strong' => array(),  
  153. 'i' => array(),  
  154. 'br' => array(),  
  155. 'img' => array( 'src' => true),  
  156. 'div' => array( 'class' => true, 'data-correct' => 1, 'data-track-id' => 1, 'data-a8ctraining' => 1, 'data-username' => 1 ),  
  157. ) ); 
  158. return $content; 
  159.  
  160. /** 
  161. * Render question. 
  162. * @since 4.5.0 
  163. * @param array $atts 
  164. * @param null $content 
  165. * @return string 
  166. */ 
  167. public static function question_shortcode( $atts, $content = null ) { 
  168. return isset( $atts['quiz_item'] ) 
  169. ? '<div class="jetpack-quiz-question question">' . self::do_shortcode( $content ) . '</div>' 
  170. : ''; 
  171.  
  172. /** 
  173. * Render correct answer. 
  174. * @since 4.5.0 
  175. * @param array $atts 
  176. * @param null $content 
  177. * @return string 
  178. */ 
  179. public static function answer_shortcode( $atts, $content = null ) { 
  180. if ( self::is_javascript_unavailable() ) { 
  181. return self::noscript_info(); 
  182.  
  183. return isset( $atts['quiz_item'] ) 
  184. ? '<div class="jetpack-quiz-answer answer" data-correct="1">' . self::do_shortcode( $content ) . '</div>' 
  185. : ''; 
  186.  
  187. /** 
  188. * Render wrong response. 
  189. * @since 4.5.0 
  190. * @param array $atts 
  191. * @param null $content 
  192. * @return string 
  193. */ 
  194. public static function wrong_shortcode( $atts, $content = null ) { 
  195. if ( self::is_javascript_unavailable() ) { 
  196. return self::noscript_info(); 
  197.  
  198. return isset( $atts['quiz_item'] ) 
  199. ? '<div class="jetpack-quiz-answer answer">' . self::do_shortcode( $content ) . '</div>' 
  200. : ''; 
  201.  
  202. /** 
  203. * Render explanation for wrong or right answer. 
  204. * @since 4.5.0 
  205. * @param array $atts 
  206. * @param null $content 
  207. * @return string 
  208. */ 
  209. public static function explanation_shortcode( $atts, $content = null ) { 
  210. if ( self::is_javascript_unavailable() ) { 
  211. return self::noscript_info(); 
  212.  
  213. return isset( $atts['quiz_item'] ) 
  214. ? '<div class="jetpack-quiz-explanation explanation">' . self::do_shortcode( $content ) . '</div>' 
  215. : '';