This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
0 ignored issues
–
show
|
|||
2 | if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly |
||
3 | |||
4 | /** |
||
5 | * Sensei Question Class |
||
6 | * |
||
7 | * All functionality pertaining to the questions post type in Sensei. |
||
8 | * |
||
9 | * @package Assessment |
||
10 | * @author Automattic |
||
11 | * |
||
12 | * @since 1.0.0 |
||
13 | */ |
||
14 | class Sensei_Question { |
||
15 | public $token; |
||
16 | public $meta_fields; |
||
17 | |||
18 | /** |
||
19 | * Constructor. |
||
20 | * @since 1.0.0 |
||
21 | */ |
||
22 | public function __construct () { |
||
23 | $this->token = 'question'; |
||
24 | $this->question_types = $this->question_types(); |
||
25 | $this->meta_fields = array( 'question_right_answer', 'question_wrong_answers' ); |
||
26 | if ( is_admin() ) { |
||
27 | // Custom Write Panel Columns |
||
28 | add_filter( 'manage_edit-question_columns', array( $this, 'add_column_headings' ), 10, 1 ); |
||
29 | add_action( 'manage_posts_custom_column', array( $this, 'add_column_data' ), 10, 2 ); |
||
30 | add_action( 'add_meta_boxes', array( $this, 'question_edit_panel_metabox' ), 10, 2 ); |
||
31 | |||
32 | // Quesitno list table filters |
||
33 | add_action( 'restrict_manage_posts', array( $this, 'filter_options' ) ); |
||
34 | add_filter( 'request', array( $this, 'filter_actions' ) ); |
||
35 | |||
36 | add_action( 'save_post', array( $this, 'save_question' ), 10, 1 ); |
||
37 | } // End If Statement |
||
38 | } // End __construct() |
||
39 | |||
40 | public function question_types() { |
||
41 | $types = array( |
||
42 | 'multiple-choice' => __( 'Multiple Choice', 'woothemes-sensei' ), |
||
43 | 'boolean' => __( 'True/False', 'woothemes-sensei' ), |
||
44 | 'gap-fill' => __( 'Gap Fill', 'woothemes-sensei' ), |
||
45 | 'single-line' => __( 'Single Line', 'woothemes-sensei' ), |
||
46 | 'multi-line' => __( 'Multi Line', 'woothemes-sensei' ), |
||
47 | 'file-upload' => __( 'File Upload', 'woothemes-sensei' ), |
||
48 | ); |
||
49 | |||
50 | return apply_filters( 'sensei_question_types', $types ); |
||
51 | } |
||
52 | |||
53 | /** |
||
54 | * Add column headings to the "lesson" post list screen. |
||
55 | * @access public |
||
56 | * @since 1.3.0 |
||
57 | * @param array $defaults |
||
58 | * @return array $new_columns |
||
59 | */ |
||
60 | View Code Duplication | public function add_column_headings ( $defaults ) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
61 | $new_columns['cb'] = '<input type="checkbox" />'; |
||
62 | $new_columns['title'] = _x( 'Question', 'column name', 'woothemes-sensei' ); |
||
63 | $new_columns['question-type'] = _x( 'Type', 'column name', 'woothemes-sensei' ); |
||
64 | $new_columns['question-category'] = _x( 'Categories', 'column name', 'woothemes-sensei' ); |
||
65 | if ( isset( $defaults['date'] ) ) { |
||
66 | $new_columns['date'] = $defaults['date']; |
||
67 | } |
||
68 | |||
69 | return $new_columns; |
||
70 | } // End add_column_headings() |
||
71 | |||
72 | /** |
||
73 | * Add data for our newly-added custom columns. |
||
74 | * @access public |
||
75 | * @since 1.3.0 |
||
76 | * @param string $column_name |
||
77 | * @param int $id |
||
78 | * @return void |
||
79 | */ |
||
80 | public function add_column_data ( $column_name, $id ) { |
||
81 | global $wpdb, $post; |
||
82 | |||
83 | switch ( $column_name ) { |
||
84 | |||
85 | case 'id': |
||
86 | echo $id; |
||
87 | break; |
||
88 | |||
89 | case 'question-type': |
||
90 | $question_type = strip_tags( get_the_term_list( $id, 'question-type', '', ', ', '' ) ); |
||
91 | $output = '—'; |
||
92 | if( isset( $this->question_types[ $question_type ] ) ) { |
||
93 | $output = $this->question_types[ $question_type ]; |
||
94 | } |
||
95 | echo $output; |
||
96 | break; |
||
97 | |||
98 | case 'question-category': |
||
99 | $output = strip_tags( get_the_term_list( $id, 'question-category', '', ', ', '' ) ); |
||
100 | if( ! $output ) { |
||
101 | $output = '—'; |
||
102 | } |
||
103 | echo $output; |
||
104 | break; |
||
105 | |||
106 | default: |
||
107 | break; |
||
108 | |||
109 | } |
||
110 | |||
111 | } // End add_column_data() |
||
112 | |||
113 | public function question_edit_panel_metabox( $post_type, $post ) { |
||
114 | if( in_array( $post_type, array( 'question', 'multiple_question' ) ) ) { |
||
115 | |||
116 | $metabox_title = __( 'Question', 'woothemes-sensei' ); |
||
117 | |||
118 | if( isset( $post->ID ) ) { |
||
119 | |||
120 | $question_type = Sensei()->question->get_question_type( $post->ID ); |
||
121 | |||
122 | if( $question_type ) { |
||
123 | $type = $this->question_types[ $question_type ]; |
||
124 | if( $type ) { |
||
125 | $metabox_title = $type; |
||
126 | } |
||
127 | } |
||
128 | } |
||
129 | add_meta_box( 'question-edit-panel', $metabox_title, array( $this, 'question_edit_panel' ), 'question', 'normal', 'high' ); |
||
130 | add_meta_box( 'question-lessons-panel', __( 'Quizzes', 'woothemes-sensei' ), array( $this, 'question_lessons_panel' ), 'question', 'side', 'default' ); |
||
131 | add_meta_box( 'multiple-question-lessons-panel', __( 'Quizzes', 'woothemes-sensei' ), array( $this, 'question_lessons_panel' ), 'multiple_question', 'side', 'default' ); |
||
132 | } |
||
133 | } |
||
134 | |||
135 | public function question_edit_panel() { |
||
136 | global $post, $pagenow; |
||
137 | |||
138 | add_action( 'admin_enqueue_scripts', array( Sensei()->lesson, 'enqueue_scripts' ) ); |
||
139 | add_action( 'admin_enqueue_scripts', array( Sensei()->lesson, 'enqueue_styles' ) ); |
||
140 | |||
141 | $html = '<div id="lesson-quiz" class="single-question"><div id="add-question-main">'; |
||
142 | |||
143 | if( 'post-new.php' == $pagenow ) { |
||
144 | |||
145 | $html .= '<div id="add-question-actions">'; |
||
146 | $html .= Sensei()->lesson->quiz_panel_add( 'question' ); |
||
147 | $html .= '</div>'; |
||
148 | |||
149 | } else { |
||
150 | $question_id = $post->ID; |
||
151 | |||
152 | $question_type = Sensei()->question->get_question_type( $post->ID ); |
||
153 | |||
154 | $html .= '<div id="add-question-metadata"><table class="widefat">'; |
||
155 | $html .= Sensei()->lesson->quiz_panel_question( $question_type, 0, $question_id, 'question' ); |
||
156 | $html .= '</table></div>'; |
||
157 | } |
||
158 | |||
159 | $html .= '</div></div>'; |
||
160 | |||
161 | echo $html; |
||
162 | } |
||
163 | |||
164 | public function question_lessons_panel() { |
||
165 | global $post; |
||
166 | |||
167 | $no_lessons = sprintf( __( '%1$sThis question does not appear in any quizzes yet.%2$s', 'woothemes-sensei' ), '<em>', '</em>' ); |
||
168 | |||
169 | if( ! isset( $post->ID ) ) { |
||
170 | echo $no_lessons; |
||
171 | return; |
||
172 | } |
||
173 | |||
174 | // This retrieves those quizzes the question is directly connected to. |
||
175 | $quizzes = get_post_meta( $post->ID, '_quiz_id', false ); |
||
176 | |||
177 | // Collate all 'multiple_question' quizzes the question is part of. |
||
178 | $categories_of_question = wp_get_post_terms( $post->ID, 'question-category', array( 'fields' => 'ids' ) ); |
||
179 | if ( ! empty( $categories_of_question ) ) { |
||
180 | foreach ( $categories_of_question as $term_id ) { |
||
181 | $qargs = array( |
||
182 | 'fields' => 'ids', |
||
183 | 'post_type' => 'multiple_question', |
||
184 | 'posts_per_page' => -1, |
||
185 | 'meta_query' => array( |
||
186 | array( |
||
187 | 'key' => 'category', |
||
188 | 'value' => $term_id, |
||
189 | ), |
||
190 | ), |
||
191 | 'post_status' => 'any', |
||
192 | 'suppress_filters' => 0, |
||
193 | ); |
||
194 | $cat_question_ids = get_posts( $qargs ); |
||
195 | foreach( $cat_question_ids as $cat_question_id ) { |
||
196 | $cat_quizzes = get_post_meta( $cat_question_id, '_quiz_id', false ); |
||
197 | $quizzes = array_merge( $quizzes, $cat_quizzes ); |
||
198 | } |
||
199 | } |
||
200 | $quizzes = array_unique( array_filter( $quizzes ) ); |
||
201 | } |
||
202 | |||
203 | if( 0 == count( $quizzes ) ) { |
||
204 | echo $no_lessons; |
||
205 | return; |
||
206 | } |
||
207 | |||
208 | $lessons = false; |
||
209 | |||
210 | foreach( $quizzes as $quiz ) { |
||
211 | |||
212 | $lesson_id = get_post_meta( $quiz, '_quiz_lesson', true ); |
||
213 | |||
214 | if( ! $lesson_id ) continue; |
||
215 | |||
216 | $lessons[ $lesson_id ]['title'] = get_the_title( $lesson_id ); |
||
217 | $lessons[ $lesson_id ]['link'] = admin_url( 'post.php?post=' . $lesson_id . '&action=edit' ); |
||
218 | } |
||
219 | |||
220 | if( ! $lessons ) { |
||
221 | echo $no_lessons; |
||
222 | return; |
||
223 | } |
||
224 | |||
225 | $html = '<ul>'; |
||
226 | |||
227 | foreach( $lessons as $id => $lesson ) { |
||
228 | $html .= '<li><a href="' . esc_url( $lesson['link'] ) . '">' . esc_html( $lesson['title'] ) . '</a></li>'; |
||
229 | } |
||
230 | |||
231 | $html .= '</ul>'; |
||
232 | |||
233 | echo $html; |
||
234 | |||
235 | } |
||
236 | |||
237 | public function save_question( $post_id = 0 ) { |
||
238 | |||
239 | if( ! isset( $_POST['post_type'] |
||
240 | ) || 'question' != $_POST['post_type'] ) { |
||
241 | return; |
||
242 | } |
||
243 | |||
244 | |||
245 | |||
246 | //setup the data for saving |
||
247 | $data = $_POST ; |
||
248 | $data['quiz_id'] = 0; |
||
249 | $data['question_id'] = $post_id; |
||
250 | |||
251 | if ( ! wp_is_post_revision( $post_id ) ){ |
||
252 | |||
253 | // Unhook function to prevent infinite loops |
||
254 | remove_action( 'save_post', array( $this, 'save_question' ) ); |
||
255 | |||
256 | // Update question data |
||
257 | $question_id = Sensei()->lesson->lesson_save_question( $data, 'question' ); |
||
258 | |||
259 | // Re-hook same function |
||
260 | add_action( 'save_post', array( $this, 'save_question' ) ); |
||
261 | } |
||
262 | |||
263 | return; |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * Add options to filter the questions list table |
||
268 | * @return void |
||
269 | */ |
||
270 | public function filter_options() { |
||
271 | global $typenow; |
||
272 | |||
273 | if( is_admin() && 'question' == $typenow ) { |
||
274 | |||
275 | $output = ''; |
||
276 | |||
277 | // Question type |
||
278 | $selected = isset( $_GET['question_type'] ) ? $_GET['question_type'] : ''; |
||
279 | $type_options = '<option value="">' . __( 'All types', 'woothemes-sensei' ) . '</option>'; |
||
280 | foreach( $this->question_types as $label => $type ) { |
||
281 | $type_options .= '<option value="' . esc_attr( $label ) . '" ' . selected( $selected, $label, false ) . '>' . esc_html( $type ) . '</option>'; |
||
282 | } |
||
283 | |||
284 | $output .= '<select name="question_type" id="dropdown_question_type">'; |
||
285 | $output .= $type_options; |
||
286 | $output .= '</select>'; |
||
287 | |||
288 | // Question category |
||
289 | $cats = get_terms( 'question-category', array( 'hide_empty' => false ) ); |
||
290 | if ( ! empty( $cats ) && ! is_wp_error( $cats ) ) { |
||
291 | $selected = isset( $_GET['question_cat'] ) ? $_GET['question_cat'] : ''; |
||
292 | $cat_options = '<option value="">' . __( 'All categories', 'woothemes-sensei' ) . '</option>'; |
||
293 | foreach( $cats as $cat ) { |
||
294 | $cat_options .= '<option value="' . esc_attr( $cat->slug ) . '" ' . selected( $selected, $cat->slug, false ) . '>' . esc_html( $cat->name ) . '</option>'; |
||
295 | } |
||
296 | |||
297 | $output .= '<select name="question_cat" id="dropdown_question_cat">'; |
||
298 | $output .= $cat_options; |
||
299 | $output .= '</select>'; |
||
300 | } |
||
301 | |||
302 | echo $output; |
||
303 | } |
||
304 | } |
||
305 | |||
306 | /** |
||
307 | * Filter questions list table |
||
308 | * @param array $request Current request |
||
309 | * @return array Modified request |
||
310 | */ |
||
311 | public function filter_actions( $request ) { |
||
312 | global $typenow; |
||
313 | |||
314 | if( is_admin() && 'question' == $typenow ) { |
||
315 | |||
316 | // Question type |
||
317 | $question_type = isset( $_GET['question_type'] ) ? $_GET['question_type'] : ''; |
||
318 | View Code Duplication | if( $question_type ) { |
|
319 | $type_query = array( |
||
320 | 'taxonomy' => 'question-type', |
||
321 | 'terms' => $question_type, |
||
322 | 'field' => 'slug', |
||
323 | ); |
||
324 | $request['tax_query'][] = $type_query; |
||
325 | } |
||
326 | |||
327 | // Question category |
||
328 | $question_cat = isset( $_GET['question_cat'] ) ? $_GET['question_cat'] : ''; |
||
329 | View Code Duplication | if( $question_cat ) { |
|
330 | $cat_query = array( |
||
331 | 'taxonomy' => 'question-category', |
||
332 | 'terms' => $question_cat, |
||
333 | 'field' => 'slug', |
||
334 | ); |
||
335 | $request['tax_query'][] = $cat_query; |
||
336 | } |
||
337 | } |
||
338 | |||
339 | return $request; |
||
340 | } |
||
341 | |||
342 | /** |
||
343 | * Get the type of question by id |
||
344 | * |
||
345 | * This function uses the post terms to determine which question type |
||
346 | * the passed question id belongs to. |
||
347 | * |
||
348 | * @since 1.7.4 |
||
349 | * |
||
350 | * @param int $question_id |
||
351 | * |
||
352 | * @return string $question_type | bool |
||
353 | */ |
||
354 | public function get_question_type( $question_id ){ |
||
355 | |||
356 | View Code Duplication | if( empty( $question_id ) || ! intval( $question_id ) > 0 |
|
357 | || 'question' != get_post_type( $question_id ) ){ |
||
358 | return false; |
||
359 | } |
||
360 | |||
361 | $question_type = 'multiple-choice'; |
||
362 | $question_types = wp_get_post_terms( $question_id, 'question-type' ); |
||
363 | foreach( $question_types as $type ) { |
||
364 | $question_type = $type->slug; |
||
365 | } |
||
366 | |||
367 | return $question_type; |
||
368 | |||
369 | }// end get_question_type |
||
370 | |||
371 | /** |
||
372 | * Given a question ID, return the grade that can be achieved. |
||
373 | * |
||
374 | * @since 1.9 |
||
375 | * |
||
376 | * @param int $question_id |
||
377 | * |
||
378 | * @return int $question_grade | bool |
||
379 | */ |
||
380 | public function get_question_grade( $question_id ) { |
||
381 | |||
382 | View Code Duplication | if ( empty( $question_id ) || ! intval( $question_id ) > 0 |
|
383 | || 'question' != get_post_type( $question_id ) ) { |
||
384 | return false; |
||
385 | } |
||
386 | |||
387 | $question_grade_raw = get_post_meta( $question_id, '_question_grade', true ); |
||
388 | // If not set then default to 1... |
||
389 | if ( false === $question_grade_raw || $question_grade_raw == '' ) { |
||
390 | $question_grade = 1; |
||
391 | } |
||
392 | // ...but allow a grade of 0 for non-marked questions |
||
393 | else { |
||
394 | $question_grade = intval( $question_grade_raw ); |
||
395 | } |
||
396 | return $question_grade; |
||
397 | |||
398 | } // end get_question_grade |
||
399 | |||
400 | |||
401 | /** |
||
402 | * This function simply loads the question type template |
||
403 | * |
||
404 | * @since 1.9.0 |
||
405 | * @param $question_type |
||
406 | */ |
||
407 | public static function load_question_template( $question_type ){ |
||
408 | |||
409 | Sensei_Templates::get_template ( 'single-quiz/question_type-' . $question_type . '.php' ); |
||
410 | } |
||
411 | |||
412 | /** |
||
413 | * Echo the sensei question title. |
||
414 | * |
||
415 | * @uses WooThemes_Sensei_Question::get_the_question_title |
||
416 | * |
||
417 | * @since 1.9.0 |
||
418 | * @param $question_id |
||
419 | */ |
||
420 | public static function the_question_title( $question_id ){ |
||
421 | |||
422 | echo self::get_the_question_title( $question_id ); |
||
423 | |||
424 | }// end the_question_title |
||
425 | |||
426 | /** |
||
427 | * Generate the question title with it's grade. |
||
428 | * |
||
429 | * @since 1.9.0 |
||
430 | * |
||
431 | * @param $question_id |
||
432 | * @return string |
||
433 | */ |
||
434 | public static function get_the_question_title( $question_id ){ |
||
435 | |||
436 | /** |
||
437 | * Filter the sensei question title |
||
438 | * |
||
439 | * @since 1.3.0 |
||
440 | * @param $question_title |
||
441 | */ |
||
442 | $title = apply_filters( 'sensei_question_title', get_the_title( $question_id ) ); |
||
443 | |||
444 | /** |
||
445 | * hook document in class-woothemes-sensei-message.php the_title() |
||
446 | */ |
||
447 | $title = apply_filters( 'sensei_single_title', $title, 'question'); |
||
448 | |||
449 | $title_html = '<span class="question question-title">'; |
||
450 | $title_html .= $title; |
||
451 | $title_html .= '<span class="grade"><?php sensi_the_question_grade()?></span>'; |
||
452 | $title_html .='</span>'; |
||
453 | |||
454 | return $title_html; |
||
455 | } |
||
456 | |||
457 | /** |
||
458 | * Tech the question description |
||
459 | * |
||
460 | * @param $question_id |
||
461 | * @return string |
||
462 | */ |
||
463 | public static function get_the_question_description( $question_id ){ |
||
464 | |||
465 | $question = get_post( $question_id ); |
||
466 | |||
467 | /** |
||
468 | * Already documented within WordPress Core |
||
469 | */ |
||
470 | return apply_filters( 'the_content', $question->post_content ); |
||
471 | |||
472 | } |
||
473 | |||
474 | /** |
||
475 | * Output the question description |
||
476 | * |
||
477 | * @since 1.9.0 |
||
478 | * @param $question_id |
||
479 | */ |
||
480 | public static function the_question_description( $question_id ){ |
||
481 | |||
482 | echo self::get_the_question_description( $question_id ); |
||
483 | |||
484 | } |
||
485 | |||
486 | /** |
||
487 | * Get the questions media markup |
||
488 | * |
||
489 | * @since 1.9.0 |
||
490 | * @param $question_id |
||
491 | * @return string |
||
492 | */ |
||
493 | public static function get_the_question_media( $question_id ){ |
||
494 | |||
495 | $question_media = get_post_meta( $question_id, '_question_media', true ); |
||
496 | $question_media_link = ''; |
||
497 | if( 0 < intval( $question_media ) ) { |
||
498 | $mimetype = get_post_mime_type( $question_media ); |
||
499 | if( $mimetype ) { |
||
500 | $mimetype_array = explode( '/', $mimetype); |
||
501 | if( isset( $mimetype_array[0] ) && $mimetype_array[0] ) { |
||
502 | $question_media_type = $mimetype_array[0]; |
||
503 | $question_media_url = wp_get_attachment_url( $question_media ); |
||
504 | $attachment = get_post( $question_media ); |
||
505 | $question_media_title = $attachment->post_title; |
||
506 | $question_media_description = $attachment->post_content; |
||
507 | switch( $question_media_type ) { |
||
508 | case 'image': |
||
509 | $image_size = apply_filters( 'sensei_question_image_size', 'medium', $question_id ); |
||
510 | $attachment_src = wp_get_attachment_image_src( $question_media, $image_size ); |
||
511 | $question_media_link = '<a class="' . esc_attr( $question_media_type ) . '" title="' . esc_attr( $question_media_title ) . '" href="' . esc_url( $question_media_url ) . '" target="_blank"><img src="' . $attachment_src[0] . '" width="' . $attachment_src[1] . '" height="' . $attachment_src[2] . '" /></a>'; |
||
512 | break; |
||
513 | |||
514 | case 'audio': |
||
515 | $question_media_link = wp_audio_shortcode( array( 'src' => $question_media_url ) ); |
||
516 | break; |
||
517 | |||
518 | case 'video': |
||
519 | $question_media_link = wp_video_shortcode( array( 'src' => $question_media_url ) ); |
||
520 | break; |
||
521 | |||
522 | default: |
||
523 | $question_media_filename = basename( $question_media_url ); |
||
524 | $question_media_link = '<a class="' . esc_attr( $question_media_type ) . '" title="' . esc_attr( $question_media_title ) . '" href="' . esc_url( $question_media_url ) . '" target="_blank">' . $question_media_filename . '</a>'; |
||
525 | break; |
||
526 | } |
||
527 | } |
||
528 | } |
||
529 | } |
||
530 | |||
531 | $output = ''; |
||
532 | if( $question_media_link ) { |
||
533 | |||
534 | $output .= '<div class="question_media_display">'; |
||
535 | $output .= $question_media_link; |
||
536 | $output .= '<dl>'; |
||
537 | |||
538 | if( $question_media_title ) { |
||
539 | |||
540 | $output .= '<dt>'. $question_media_title. '</dt>'; |
||
541 | |||
542 | } |
||
543 | |||
544 | if( $question_media_description ) { |
||
545 | |||
546 | $output .= '<dd>' . $question_media_description . '</dd>'; |
||
547 | |||
548 | } |
||
549 | |||
550 | $output .= '</dl>'; |
||
551 | $output .= '</div>'; |
||
552 | |||
553 | |||
554 | } |
||
555 | |||
556 | return $output; |
||
557 | |||
558 | } // end get_the_question_media |
||
559 | |||
560 | |||
561 | /** |
||
562 | * Output the question media |
||
563 | * |
||
564 | * @since 1.9.0 |
||
565 | * @param string $question_id |
||
566 | */ |
||
567 | public static function the_question_media( $question_id ){ |
||
568 | |||
569 | echo self::get_the_question_media( $question_id ); |
||
570 | |||
571 | } |
||
572 | |||
573 | /** |
||
574 | * Output a special field for the question needed for question submission. |
||
575 | * |
||
576 | * @since 1.9.0 |
||
577 | * |
||
578 | * @param $question_id |
||
579 | */ |
||
580 | public static function the_question_hidden_fields( $question_id ){ |
||
581 | ?> |
||
582 | |||
583 | <input type="hidden" name="question_id_<?php $question_id;?>" value="<?php $question_id;?>" /> |
||
584 | <input type="hidden" name="questions_asked[]" value="<?php esc_attr_e( $question_id ); ?>" /> |
||
585 | |||
586 | <?php |
||
587 | } |
||
588 | |||
589 | /** |
||
590 | * This function can only be run withing the single quiz question loop |
||
591 | * |
||
592 | * @since 1.9.0 |
||
593 | * @param $question_id |
||
594 | */ |
||
595 | public static function answer_feedback_notes( $question_id ){ |
||
596 | |||
597 | //IDS |
||
598 | $quiz_id = get_the_ID(); |
||
599 | $lesson_id = Sensei()->quiz->get_lesson_id( $quiz_id ); |
||
600 | |||
601 | // Data to check before showing feedback |
||
602 | $user_lesson_status = Sensei_Utils::user_lesson_status( $lesson_id, get_current_user_id() ); |
||
603 | $user_quiz_grade = Sensei_Quiz::get_user_quiz_grade( $lesson_id, get_current_user_id() ); |
||
604 | $not_empty_user_quiz_grade = !empty( $user_quiz_grade ); |
||
605 | $reset_quiz_allowed = Sensei_Quiz::is_reset_allowed( $lesson_id ); |
||
606 | $lesson_completed = Sensei_Utils::user_completed_lesson( $lesson_id ); |
||
607 | $quiz_grade_type = get_post_meta( $quiz_id , '_quiz_grade_type', true ); |
||
608 | |||
609 | if( ( $lesson_completed && $not_empty_user_quiz_grade ) |
||
610 | || ( $lesson_completed && ! $reset_quiz_allowed && 'auto' == $quiz_grade_type ) |
||
611 | || ( 'auto' == $quiz_grade_type && ! $reset_quiz_allowed && $not_empty_user_quiz_grade ) ) { |
||
612 | |||
613 | $answer_notes = Sensei()->quiz->get_user_question_feedback( $lesson_id, $question_id, get_current_user_id() ); |
||
614 | |||
615 | if( $answer_notes ) { ?> |
||
616 | |||
617 | <div class="sensei-message info info-special answer-feedback"> |
||
618 | |||
619 | <?php |
||
620 | |||
621 | /** |
||
622 | * Filter the answer feedback |
||
623 | * Since 1.9.0 |
||
624 | * |
||
625 | * @param string $answer_notes |
||
626 | * @param string $question_id |
||
627 | * @param string $lesson_id |
||
628 | */ |
||
629 | echo apply_filters( 'sensei_question_answer_notes', $answer_notes, $question_id, $lesson_id ); |
||
630 | |||
631 | ?> |
||
632 | |||
633 | </div> |
||
634 | |||
635 | <?php } |
||
636 | |||
637 | }// end if we can show answer feedback |
||
638 | |||
639 | }// end answer_feedback_notes |
||
640 | |||
641 | /** |
||
642 | * This function has to be run inside the quiz question loop on the single quiz page. |
||
643 | * |
||
644 | * |
||
645 | * @since 1.9.0 |
||
646 | * @param string $question_id |
||
647 | */ |
||
648 | public static function the_answer_result_indication( $question_id ){ |
||
649 | |||
650 | global $post, $current_user, $sensei_question_loop; |
||
651 | |||
652 | // Post Data |
||
653 | $quiz_id = $sensei_question_loop['quiz_id']; |
||
654 | $lesson_id = Sensei()->quiz->get_lesson_id( $quiz_id ); |
||
655 | $question_item = $sensei_question_loop['current_question']; |
||
656 | |||
657 | // Setup variable needed to determine if the message should show and what it should show |
||
658 | $user_quiz_grade = Sensei_Quiz::get_user_quiz_grade( $lesson_id, get_current_user_id() ); |
||
659 | $lesson_complete = Sensei_Utils::user_completed_lesson( $lesson_id, get_current_user_id() ); |
||
660 | $reset_quiz_allowed = Sensei_Quiz::is_reset_allowed( $lesson_id ); |
||
661 | $quiz_grade_type = get_post_meta( $quiz_id, '_quiz_grade_type', true ); |
||
662 | |||
663 | // retrieve the question total grade |
||
664 | $question_grade = Sensei()->question->get_question_grade( $question_id ); |
||
665 | |||
666 | // retrieve grade the user achieved |
||
667 | $user_question_grade = Sensei()->quiz->get_user_question_grade( $lesson_id, $question_id, get_current_user_id() ); |
||
668 | |||
669 | // Question ID |
||
670 | $question_id = $question_item->ID; |
||
671 | |||
672 | // conditions to check |
||
673 | $completed_with_valid_grade = $lesson_complete && $user_quiz_grade != '' ; |
||
674 | $completed_with_valid_grade_and_reset_not_allowed = $lesson_complete && $user_quiz_grade != '' && ! $reset_quiz_allowed ; |
||
675 | $grade_type_auto_a_valid_grade_and_reset_not_allowed = 'auto' == $quiz_grade_type && ! $reset_quiz_allowed && $user_quiz_grade != '' ; |
||
676 | |||
677 | if ( $completed_with_valid_grade |
||
678 | || $completed_with_valid_grade_and_reset_not_allowed |
||
679 | || $grade_type_auto_a_valid_grade_and_reset_not_allowed ) { |
||
680 | |||
681 | $user_correct = false; |
||
682 | $answer_message = __( 'Incorrect', 'woothemes-sensei' ); |
||
683 | $answer_message_class = 'user_wrong'; |
||
684 | // For zero grade mark as 'correct' but add no classes |
||
685 | if ( 0 == $question_grade ) { |
||
686 | |||
687 | $user_correct = true; |
||
688 | $answer_message = ''; |
||
689 | $answer_message_class = ''; |
||
690 | |||
691 | } else if( $user_question_grade > 0 ) { |
||
692 | |||
693 | $user_correct = true; |
||
694 | $answer_message = sprintf( __( 'Grade: %d', 'woothemes-sensei' ), $user_question_grade ); |
||
695 | $answer_message_class = 'user_right'; |
||
696 | |||
697 | } |
||
698 | |||
699 | // attach the correct answer if the question is auto gradable and user got it wrong |
||
700 | if( !$reset_quiz_allowed && !$user_correct ){ |
||
701 | |||
702 | $answer_message .= ' - '. __('Right Answer:','woothemes-sensei') . ' ' . self::get_correct_answer( $question_item->ID ); |
||
703 | |||
704 | } |
||
705 | |||
706 | // answer feedback |
||
707 | $answer_notes = Sensei()->quiz->get_user_question_feedback( $lesson_id, $question_id, $current_user->ID ); |
||
708 | if( $answer_notes ) { |
||
709 | $answer_message_class .= ' has_notes'; |
||
710 | } |
||
711 | ?> |
||
712 | |||
713 | <div class="answer_message <?php esc_attr_e( $answer_message_class ); ?>"> |
||
714 | |||
715 | <span><?php echo $answer_message; ?></span> |
||
716 | |||
717 | </div> |
||
718 | |||
719 | <?php |
||
720 | |||
721 | } // end if user can see all the goodies |
||
722 | |||
723 | }// end the_answer_result_indication |
||
724 | |||
725 | /** |
||
726 | * Generate the question template data and return it as an array. |
||
727 | * |
||
728 | * @since 1.9.0 |
||
729 | * |
||
730 | * @param string $question_id |
||
731 | * @param $quiz_id |
||
732 | * @return array $question_data |
||
733 | */ |
||
734 | public static function get_template_data( $question_id, $quiz_id ){ |
||
735 | |||
736 | $lesson_id = Sensei()->quiz->get_lesson_id( $quiz_id ); |
||
737 | |||
738 | $reset_allowed = get_post_meta( $quiz_id, '_enable_quiz_reset', true ); |
||
739 | //backwards compatibility |
||
740 | if( 'on' == $reset_allowed ) { |
||
741 | $reset_allowed = 1; |
||
742 | } |
||
743 | |||
744 | // Check again that the lesson is complete |
||
745 | $user_lesson_end = Sensei_Utils::user_completed_lesson( Sensei()->quiz->get_lesson_id( $quiz_id), get_current_user_id() ); |
||
746 | $user_lesson_complete = false; |
||
747 | if ( $user_lesson_end ) { |
||
748 | $user_lesson_complete = true; |
||
749 | } |
||
750 | |||
751 | //setup the question data |
||
752 | $data[ 'ID' ] = $question_id; |
||
753 | $data[ 'title' ] = get_the_title( $question_id ); |
||
754 | $data[ 'content' ] = get_post( $question_id )->post_content; |
||
755 | $data[ 'quiz_id' ] = $quiz_id; |
||
756 | $data[ 'lesson_id' ] = Sensei()->quiz->get_lesson_id( $quiz_id ); |
||
757 | $data[ 'type' ] = Sensei()->question->get_question_type( $question_id ); |
||
758 | $data[ 'question_grade' ] = Sensei()->question->get_question_grade( $question_id ); |
||
759 | $data[ 'user_question_grade' ] = Sensei()->quiz->get_user_question_grade( $lesson_id, $question_id , get_current_user_id()); |
||
760 | $data[ 'question_right_answer' ] = get_post_meta( $question_id , '_question_right_answer', true ); |
||
761 | $data[ 'question_wrong_answers' ] = get_post_meta( $question_id , '_question_wrong_answers', true ); |
||
762 | $data[ 'user_answer_entry' ] = Sensei()->quiz->get_user_question_answer( $lesson_id, $question_id , get_current_user_id() ); |
||
763 | $data[ 'lesson_completed' ] = Sensei_Utils::user_completed_course( $lesson_id, get_current_user_id( ) ); |
||
764 | $data[ 'quiz_grade_type' ] = get_post_meta( $quiz_id , '_quiz_grade_type', true ); |
||
765 | $data[ 'reset_quiz_allowed' ] = $reset_allowed; |
||
766 | $data[ 'lesson_complete' ] = $user_lesson_complete; |
||
767 | |||
768 | /** |
||
769 | * Filter the question template data. This filter fires in |
||
770 | * the get_template_data function |
||
771 | * |
||
772 | * @hooked self::boolean_load_question_data |
||
773 | * |
||
774 | * @since 1.9.0 |
||
775 | * |
||
776 | * @param array $data |
||
777 | * @param string $question_id |
||
778 | * @param string $quiz_id |
||
779 | */ |
||
780 | return apply_filters( 'sensei_get_question_template_data', $data, $question_id, $quiz_id ); |
||
781 | |||
782 | } |
||
783 | |||
784 | /** |
||
785 | * Load multiple choice question data on the sensei_get_question_template_data |
||
786 | * filter. |
||
787 | * |
||
788 | * @since 1.9.0 |
||
789 | * |
||
790 | * @param $question_data |
||
791 | * @param $question_id |
||
792 | * @param $quiz_id |
||
793 | * |
||
794 | * @return array() |
||
795 | */ |
||
796 | public static function file_upload_load_question_data ( $question_data, $question_id, $quiz_id ){ |
||
797 | |||
798 | |||
799 | if( 'file-upload' == Sensei()->question->get_question_type( $question_id ) ) { |
||
800 | |||
801 | // Get uploaded file |
||
802 | $attachment_id = $question_data[ 'user_answer_entry' ]; |
||
803 | $answer_media_url = $answer_media_filename = ''; |
||
804 | |||
805 | |||
806 | $question_helptext = ''; |
||
807 | if( isset( $question_data['question_wrong_answers'][0] ) ) { |
||
808 | |||
809 | $question_helptext = $question_data['question_wrong_answers'][0]; |
||
810 | |||
811 | } |
||
812 | |||
813 | |||
814 | if( 0 < intval( $attachment_id ) ) { |
||
815 | |||
816 | $answer_media_url = wp_get_attachment_url( $attachment_id ); |
||
817 | $answer_media_filename = basename( $answer_media_url ); |
||
818 | |||
819 | } |
||
820 | |||
821 | |||
822 | // Get max upload file size, formatted for display |
||
823 | // Code copied from wp-admin/includes/media.php:1515 |
||
824 | $upload_size_unit = $max_upload_size = wp_max_upload_size(); |
||
825 | $sizes = array( 'KB', 'MB', 'GB' ); |
||
826 | for ( $u = -1; $upload_size_unit > 1024 && $u < count( $sizes ) - 1; $u++ ) { |
||
827 | $upload_size_unit /= 1024; |
||
828 | } |
||
829 | if ( $u < 0 ) { |
||
830 | |||
831 | $upload_size_unit = 0; |
||
832 | $u = 0; |
||
833 | |||
834 | } else { |
||
835 | |||
836 | $upload_size_unit = (int) $upload_size_unit; |
||
837 | |||
838 | } |
||
839 | $max_upload_size = sprintf( __( 'Maximum upload file size: %d%s' ), esc_html( $upload_size_unit ), esc_html( $sizes[ $u ] ) ); |
||
840 | |||
841 | // Assemble all the data needed by the file upload template |
||
842 | $question_data[ 'answer_media_url' ] = $answer_media_url; |
||
843 | $question_data[ 'answer_media_filename' ] = $answer_media_filename; |
||
844 | $question_data[ 'max_upload_size' ] = $max_upload_size; |
||
845 | |||
846 | $question_data[ 'question_helptext' ] = $question_helptext; |
||
847 | |||
848 | }// end if is file upload type |
||
849 | |||
850 | return $question_data; |
||
851 | |||
852 | }// end file_upload_load_question_data |
||
853 | |||
854 | /** |
||
855 | * Load multiple choice question data on the sensei_get_question_template_data |
||
856 | * filter. |
||
857 | * |
||
858 | * @since 1.9.0 |
||
859 | * |
||
860 | * @param $question_data |
||
861 | * @param $question_id |
||
862 | * @param $quiz_id |
||
863 | * |
||
864 | * @return array() |
||
865 | */ |
||
866 | public static function multiple_choice_load_question_data( $question_data, $question_id, $quiz_id ){ |
||
867 | |||
868 | if( 'multiple-choice' == Sensei()->question->get_question_type( $question_id ) ) { |
||
869 | |||
870 | |||
871 | $answer_type = 'radio'; |
||
872 | if ( is_array( $question_data[ 'question_right_answer' ] ) && ( 1 < count( $question_data[ 'question_right_answer' ] ) ) ) { |
||
873 | |||
874 | $answer_type = 'checkbox'; |
||
875 | |||
876 | } |
||
877 | |||
878 | // Merge right and wrong answers |
||
879 | if ( is_array( $question_data[ 'question_right_answer' ] ) ) { |
||
880 | |||
881 | $merged_options = array_merge( $question_data[ 'question_wrong_answers' ], $question_data[ 'question_right_answer' ] ); |
||
882 | |||
883 | } else { |
||
884 | |||
885 | array_push( $question_data[ 'question_wrong_answers' ], $question_data[ 'question_right_answer' ] ); |
||
886 | $merged_options = $question_data[ 'question_wrong_answers' ]; |
||
887 | |||
888 | } |
||
889 | |||
890 | // Setup answer options array. |
||
891 | $question_answers_options = array(); |
||
892 | $count = 0; |
||
893 | |||
894 | foreach( $merged_options as $answer ) { |
||
895 | |||
896 | $count++; |
||
897 | $question_option = array(); |
||
898 | |||
899 | if( ( $question_data[ 'lesson_completed' ] && $question_data[ 'user_quiz_grade' ] != '' ) |
||
900 | || ( $question_data[ 'lesson_completed' ] && ! $question_data[ 'reset_quiz_allowed' ] && $question_data[ 'user_quiz_grade' ] != '' ) |
||
901 | || ( 'auto' == $question_data[ 'quiz_grade_type' ] && ! $question_data[ 'reset_quiz_allowed' ] && ! empty( $question_data[ 'user_quiz_grade' ] ) ) ) { |
||
902 | |||
903 | $user_correct = false; |
||
904 | |||
905 | |||
906 | // For zero grade mark as 'correct' but add no classes |
||
907 | if ( 0 == $question_data[ 'question_grade' ] ) { |
||
908 | |||
909 | $user_correct = true; |
||
910 | |||
911 | } else if( $question_data[ 'user_question_grade' ] > 0 ) { |
||
912 | |||
913 | $user_correct = true; |
||
914 | |||
915 | } |
||
916 | |||
917 | } |
||
918 | |||
919 | // setup the option specific classes |
||
920 | $answer_class = ''; |
||
921 | if( isset( $user_correct ) && 0 < $question_data[ 'question_grade' ] ) { |
||
922 | if ( is_array( $question_data['question_right_answer'] ) && in_array($answer, $question_data['question_right_answer']) ) { |
||
923 | |||
924 | $answer_class .= ' right_answer'; |
||
925 | |||
926 | } elseif( !is_array($question_data['question_right_answer']) && $question_data['question_right_answer'] == $answer ) { |
||
927 | |||
928 | $answer_class .= ' right_answer'; |
||
929 | |||
930 | } elseif( ( is_array( $question_data['user_answer_entry'] ) && in_array($answer, $question_data['user_answer_entry'] ) ) |
||
931 | || ( ! $question_data['user_answer_entry'] && $question_data['user_answer_entry'] == $answer ) ) { |
||
932 | |||
933 | $answer_class = 'user_wrong'; |
||
934 | if( $user_correct ) { |
||
935 | |||
936 | $answer_class = 'user_right'; |
||
937 | |||
938 | } |
||
939 | |||
940 | } |
||
941 | |||
942 | } |
||
943 | |||
944 | // determine if the current option must be checked |
||
945 | $checked = ''; |
||
946 | if ( isset( $question_data['user_answer_entry'] ) && 0 < count( $question_data['user_answer_entry'] ) ) { |
||
947 | if ( is_array( $question_data['user_answer_entry'] ) && in_array( $answer, $question_data['user_answer_entry'] ) ) { |
||
948 | |||
949 | $checked = 'checked="checked"'; |
||
950 | |||
951 | } elseif ( !is_array( $question_data['user_answer_entry'] ) ) { |
||
952 | |||
953 | $checked = checked( $answer, $question_data['user_answer_entry'] , false ); |
||
954 | |||
955 | } |
||
956 | |||
957 | } // End If Statement |
||
958 | |||
959 | //Load the answer option data |
||
960 | $question_option[ 'ID' ] = Sensei()->lesson->get_answer_id( $answer ); |
||
961 | $question_option[ 'answer' ] = $answer; |
||
962 | $question_option[ 'option_class'] = $answer_class; |
||
963 | $question_option[ 'checked'] = $checked; |
||
964 | $question_option[ 'count' ] = $count; |
||
965 | $question_option[ 'type' ] = $answer_type; |
||
966 | |||
967 | // add the speci fic option to the list of options for this question |
||
968 | $question_answers_options[$question_option[ 'ID' ]] = $question_option; |
||
969 | |||
970 | } // end for each option |
||
971 | |||
972 | |||
973 | // Shuffle the array depending on the settings |
||
974 | $answer_options_sorted = array(); |
||
975 | $random_order = get_post_meta( $question_data['ID'], '_random_order', true ); |
||
976 | if( $random_order && $random_order == 'yes' ) { |
||
977 | |||
978 | $answer_options_sorted = $question_answers_options; |
||
979 | shuffle( $answer_options_sorted ); |
||
980 | |||
981 | } else { |
||
982 | |||
983 | $answer_order = array(); |
||
984 | $answer_order_string = get_post_meta( $question_data['ID'], '_answer_order', true ); |
||
985 | if( $answer_order_string ) { |
||
986 | |||
987 | $answer_order = array_filter( explode( ',', $answer_order_string ) ); |
||
988 | View Code Duplication | if( count( $answer_order ) > 0 ) { |
|
989 | |||
990 | foreach( $answer_order as $answer_id ) { |
||
991 | |||
992 | if( isset( $question_answers_options[ $answer_id ] ) ) { |
||
993 | |||
994 | $answer_options_sorted[ $answer_id ] = $question_answers_options[ $answer_id ]; |
||
995 | unset( $question_answers_options[ $answer_id ] ); |
||
996 | |||
997 | } |
||
998 | |||
999 | } |
||
1000 | |||
1001 | if( count( $question_answers_options ) > 0 ) { |
||
1002 | foreach( $question_answers_options as $id => $answer ) { |
||
1003 | |||
1004 | $answer_options_sorted[ $id ] = $answer; |
||
1005 | |||
1006 | } |
||
1007 | } |
||
1008 | |||
1009 | }else{ |
||
1010 | |||
1011 | $answer_options_sorted = $question_answers_options; |
||
1012 | |||
1013 | } |
||
1014 | |||
1015 | }else{ |
||
1016 | |||
1017 | $answer_options_sorted = $question_answers_options; |
||
1018 | |||
1019 | } // end if $answer_order_string |
||
1020 | |||
1021 | } // end if random order |
||
1022 | |||
1023 | |||
1024 | // assemble and setup the data for the templates data array |
||
1025 | $question_data[ 'answer_options' ] = $answer_options_sorted; |
||
1026 | |||
1027 | } |
||
1028 | |||
1029 | return $question_data; |
||
1030 | |||
1031 | }// end multiple_choice_load_question_data |
||
1032 | |||
1033 | /** |
||
1034 | * Load the gap fill question data on the sensei_get_question_template_data |
||
1035 | * filter. |
||
1036 | * |
||
1037 | * @since 1.9.0 |
||
1038 | * |
||
1039 | * @param $question_data |
||
1040 | * @param $question_id |
||
1041 | * @param $quiz_id |
||
1042 | * |
||
1043 | * @return array() |
||
1044 | */ |
||
1045 | public static function gap_fill_load_question_data( $question_data, $question_id, $quiz_id ){ |
||
1046 | |||
1047 | if( 'gap-fill' == Sensei()->question->get_question_type( $question_id ) ) { |
||
1048 | |||
1049 | $gapfill_array = explode( '||', $question_data[ 'question_right_answer' ] ); |
||
1050 | $question_data[ 'gapfill_pre' ] = isset( $gapfill_array[0] ) ? $gapfill_array[0] : ''; |
||
1051 | $question_data[ 'gapfill_gap' ] = isset( $gapfill_array[1] ) ? $gapfill_array[1] : ''; |
||
1052 | $question_data[ 'gapfill_post' ] = isset( $gapfill_array[2] ) ? $gapfill_array[2] : ''; |
||
1053 | |||
1054 | } |
||
1055 | |||
1056 | return $question_data; |
||
1057 | |||
1058 | }// end gap_fill_load_question_data |
||
1059 | |||
1060 | |||
1061 | /** |
||
1062 | * Get the correct answer for a question |
||
1063 | * |
||
1064 | * @param $question_id |
||
1065 | * @return string $correct_answer or empty |
||
1066 | */ |
||
1067 | public static function get_correct_answer( $question_id ){ |
||
1068 | |||
1069 | $right_answer = get_post_meta( $question_id, '_question_right_answer', true ); |
||
1070 | $type = Sensei()->question->get_question_type( $question_id ); |
||
1071 | $type_name = __( 'Multiple Choice', 'woothemes-sensei' ); |
||
1072 | $grade_type = 'manual-grade'; |
||
1073 | |||
1074 | if ('boolean'== $type ) { |
||
1075 | |||
1076 | $right_answer = ucfirst($right_answer); |
||
1077 | |||
1078 | }elseif( 'multiple-choice' == $type ) { |
||
1079 | |||
1080 | $right_answer = (array) $right_answer; |
||
1081 | $right_answer = implode( ', ', $right_answer ); |
||
1082 | |||
1083 | }elseif( 'gap-fill' == $type ) { |
||
1084 | |||
1085 | $right_answer_array = explode( '||', $right_answer ); |
||
1086 | if ( isset( $right_answer_array[0] ) ) { $gapfill_pre = $right_answer_array[0]; } else { $gapfill_pre = ''; } |
||
1087 | if ( isset( $right_answer_array[1] ) ) { $gapfill_gap = $right_answer_array[1]; } else { $gapfill_gap = ''; } |
||
1088 | if ( isset( $right_answer_array[2] ) ) { $gapfill_post = $right_answer_array[2]; } else { $gapfill_post = ''; } |
||
1089 | |||
1090 | $right_answer = $gapfill_pre . ' <span class="highlight">' . $gapfill_gap . '</span> ' . $gapfill_post; |
||
1091 | |||
1092 | }else{ |
||
1093 | |||
1094 | // for non auto gradable question types no answer should be returned. |
||
1095 | $right_answer = ''; |
||
1096 | |||
1097 | } |
||
1098 | |||
1099 | return $right_answer; |
||
1100 | |||
1101 | } // get_correct_answer |
||
1102 | |||
1103 | } // End Class |
||
1104 | |||
1105 | /** |
||
1106 | * Class WooThemes_Sensei_Question |
||
1107 | * @ignore only for backward compatibility |
||
1108 | * @since 1.9.0 |
||
1109 | */ |
||
1110 | class WooThemes_Sensei_Question extends Sensei_Question{} |
||
1111 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.