PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.10
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.10
4.4.10 4.4.9.1 4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 All 142 releases
← All changes | inc/question/class-lp-question-fill-in-blanks.php +466 -466 4.3.8 → 4.4.10 View file →
@@ -1,466 +1,466 @@
1 -<?php
2 -/**
3 - * LP_Question_Fill_In_Blanks
4 - *
5 - * @author ThimPress
6 - * @package LearnPress/Templates
7 - * @version 4.0.0
8 - * @extends LP_Question
9 - */
10 -
11 -defined( 'ABSPATH' ) || exit();
12 -
13 -if ( ! class_exists( 'LP_Question_Fill_In_Blanks' ) ) {
14 -
15 - /**
16 - * Class LP_Question_Fill_In_Blanks
17 - */
18 - class LP_Question_Fill_In_Blanks extends LP_Question {
19 - /**
20 - * Type of this question.
21 - *
22 - * @var string
23 - */
24 - protected $_question_type = 'fill_in_blanks';
25 -
26 - /**
27 - * @var bool
28 - */
29 - protected $_answer_options = false;
30 -
31 - /**
32 - * LP_Question_Fill_In_Blanks constructor.
33 - *
34 - * @param null $the_question
35 - * @param null $args
36 - *
37 - * @throws Exception
38 - */
39 - public function __construct( $the_question = null, $args = null ) {
40 - parent::__construct( $the_question, $args );
41 -
42 - add_filter(
43 - 'learn-press/question-editor/localize-script',
44 - array( $this, 'sanitize_question_answers' ),
45 - 1000
46 - );
47 -
48 - add_action( 'learn-press/before-clear-question', array( $this, 'clear_question_answer_meta' ) );
49 -
50 - add_filter(
51 - 'learn-press/quiz-editor/question-answers-data',
52 - array( $this, 'admin_editor_question_answers' ),
53 - 10,
54 - 3
55 - );
56 - add_filter(
57 - 'learn-press/question-editor/question-answers-data',
58 - array( $this, 'admin_editor_question_answers' ),
59 - 10,
60 - 3
61 - );
62 -
63 - add_filter( 'learn-press/question/fib/regex-content', array( $this, 'match_shortcode_api' ), 10, 4 );
64 - }
65 -
66 - public function fib_get_ids( $content ) {
67 - $output = array();
68 -
69 - if ( ! empty( $content ) ) {
70 - preg_match_all(
71 - '/' . get_shortcode_regex( array( 'fib' ) ) . '/',
72 - $content,
73 - $all_shortcode,
74 - PREG_SET_ORDER
75 - );
76 -
77 - if ( ! empty( $all_shortcode ) ) {
78 - foreach ( $all_shortcode as $shortcode ) {
79 - $atts = shortcode_parse_atts( $shortcode[0] );
80 -
81 - if ( empty( $atts['id'] ) ) {
82 - $ida = explode( '=', str_replace( ']', '', $atts[1] ) );
83 - $ids = isset( $ida[1] ) ? str_replace( '"', '', $ida[1] ) : '';
84 - } else {
85 - $ids = $atts['id'];
86 - }
87 -
88 - $output[] = $ids;
89 - }
90 - }
91 - }
92 -
93 - return $output;
94 - }
95 -
96 - public function match_shortcode_api( $content, $answer_id, $show_answer = false, $answered = '' ) {
97 - if ( ! empty( $content ) ) {
98 - preg_match_all(
99 - '/' . get_shortcode_regex( array( 'fib' ) ) . '/',
100 - $content,
101 - $all_shortcode,
102 - PREG_SET_ORDER
103 - );
104 -
105 - if ( ! empty( $all_shortcode ) ) {
106 - foreach ( $all_shortcode as $shortcode ) {
107 - $atts = shortcode_parse_atts( $shortcode[0] );
108 -
109 - if ( empty( $atts['id'] ) ) {
110 - $ida = explode( '=', str_replace( ']', '', $atts[1] ) );
111 - $ids = isset( $ida[1] ) ? str_replace( '"', '', $ida[1] ) : '';
112 - } else {
113 - $ids = $atts['id'];
114 - }
115 -
116 - $fill = $atts['fill'] ?? '';
117 -
118 - $new_str = ' {{FIB_' . esc_attr( $ids ) . '}} ';
119 -
120 - $content = str_replace( $shortcode[0], $new_str, $content );
121 - }
122 - }
123 - }
124 -
125 - return $content;
126 - }
127 -
128 - public function get_answer_data( $content, $answer_id, $answered = '' ) {
129 - $output = array();
130 -
131 - if ( ! empty( $content ) ) {
132 - preg_match_all(
133 - '/' . get_shortcode_regex( array( 'fib' ) ) . '/',
134 - $content,
135 - $all_shortcode,
136 - PREG_SET_ORDER
137 - );
138 -
139 - if ( ! empty( $all_shortcode ) ) {
140 - foreach ( $all_shortcode as $shortcode ) {
141 - $atts = shortcode_parse_atts( $shortcode[0] );
142 -
143 - if ( empty( $atts['id'] ) ) {
144 - $ida = explode( '=', str_replace( ']', '', $atts[1] ) );
145 - $ids = isset( $ida[1] ) ? str_replace( '"', '', $ida[1] ) : '';
146 - } else {
147 - $ids = $atts['id'];
148 - }
149 -
150 - $fill = $atts['fill'] ?? '';
151 -
152 - if ( is_array( $answered ) ) {
153 - $answer = $answered[ $ids ] ?? '';
154 - } else {
155 - $answer = '';
156 - }
157 -
158 - $is_correct = false;
159 -
160 - $blanks = learn_press_get_question_answer_meta( $answer_id, '_blanks', true );
161 -
162 - if ( ! empty( $blanks ) ) {
163 - $is_correct = $this->check_answer( $blanks[ $ids ] ?? [], $answer );
164 - }
165 -
166 - $output[ $ids ]['is_correct'] = $is_correct;
167 - $output[ $ids ]['answer'] = $answer;
168 - $output[ $ids ]['correct'] = $fill;
169 - }
170 - }
171 - }
172 -
173 - return $output;
174 - }
175 -
176 - public function sanitize_question_answers( $data ) {
177 - global $post;
178 -
179 - if ( $post && ( $post->ID == $this->get_id() ) && isset( $data['root'] ) ) {
180 - if ( isset( $data['root']['answers'] ) ) {
181 - $answers = array();
182 - $old_answers = reset( $data['root']['answers'] );
183 -
184 - foreach ( $old_answers as $k => $v ) {
185 - if ( $k == '0' ) {
186 - $answers['title'] = str_replace( array( '=\"', '\"' ), array( '="', '"' ), $v );
187 - } else {
188 - $answers[ $k ] = $v;
189 - }
190 - }
191 - $data['root']['answers'] = array( $answers );
192 - }
193 - }
194 -
195 - return $data;
196 - }
197 -
198 - public function admin_editor_question_answers( $answers, $question_id, $quiz_id ) {
199 - $question = learn_press_get_question( $question_id );
200 -
201 - if ( ! $question ) {
202 - return $answers;
203 - }
204 -
205 - if ( 'fill_in_blanks' !== $question->get_type() ) {
206 - return $answers;
207 - }
208 -
209 - if ( $answers ) {
210 - foreach ( $answers as $k => $answer ) {
211 - $blanks = learn_press_get_question_answer_meta(
212 - $answer['question_answer_id'],
213 - '_blanks',
214 - true
215 - );
216 - $answers[ $k ]['blanks'] = ! empty( $blanks ) ? array_values( $blanks ) : array();
217 - }
218 - }
219 -
220 - return $answers;
221 - }
222 -
223 - /**
224 - * Clear answer meta of the question
225 - *
226 - * @param $question_id
227 - *
228 - * @since 4.0.0
229 - * @version 1.0.1
230 - */
231 - public function clear_question_answer_meta( $question_id ) {
232 - try {
233 - $question = LP_Question::get_question( $question_id );
234 - $answers = $question->get_answers();
235 -
236 - foreach ( $answers as $answer ) {
237 - $answer_id = $answer->get_id();
238 - $lp_db = LP_Database::getInstance();
239 - $filter = new LP_Question_Answermeta_Filter();
240 - $filter->collection = $lp_db->tb_lp_question_answermeta;
241 - $filter->where[] = $lp_db->wpdb->prepare( "AND learnpress_question_answer_id = %s", $answer_id );
242 - $lp_db->delete_execute( $filter );
243 - }
244 - } catch ( Throwable $e ) {
245 - error_log( __METHOD__ . ': ' . $e->getMessage() );
246 - }
247 - }
248 -
249 - /**
250 - * Get answer options of the question
251 - *
252 - * @param array $args - Optional.
253 - *
254 - * @return mixed
255 - */
256 - public function get_answer_options( $args = array() ) {
257 -
258 - $args = wp_parse_args(
259 - $args,
260 - array(
261 - 'exclude' => '',
262 - 'map' => '',
263 - 'answer' => '',
264 - )
265 - );
266 -
267 - if ( $args['exclude'] && is_string( $args['exclude'] ) ) {
268 - $exclude = array_map( 'trim', explode( ',', $args['exclude'] ) );
269 - } else {
270 - $exclude = $args['exclude'];
271 - }
272 -
273 - $map = $args['map'];
274 -
275 - $options = $this->get_data( 'answer_options' );
276 -
277 - // Remove key if it present in $exclude.
278 - if ( $options && ( $exclude || $map ) ) {
279 - $exclude = array_flip( $exclude );
280 -
281 - foreach ( $options as $k => $option ) {
282 - $is_true = ! isset( $exclude['is_true'] );
283 - $fib_answer = ! empty( $args['answer'] ) ? $args['answer'] : '';
284 - $title = $option['title'];
285 - $option['title'] = apply_filters( 'learn-press/question/fib/regex-content', $title, $option['question_answer_id'], $is_true, $fib_answer );
286 - $option['ids'] = $this->fib_get_ids( $title );
287 - $option['title_api'] = wp_strip_all_tags( $this->match_shortcode_api( $title, $option['question_answer_id'], $is_true, $fib_answer ) );
288 - $option['answers'] = $is_true ? $this->get_answer_data( $title, $option['question_answer_id'], $fib_answer ) : array();
289 -
290 - foreach ( $map as $k_map => $v_map ) {
291 - if ( array_key_exists( $k_map, $option ) ) {
292 - $option[ $v_map ] = $option[ $k_map ];
293 - $exclude[ $k_map ] = 1;
294 - }
295 - }
296 -
297 - $options[ $k ] = array_diff_key( $option, $exclude );
298 - }
299 - }
300 -
301 - return apply_filters( 'learn-press/question/answer-options', $options, $this->get_id() );
302 - }
303 -
304 -
305 - public function get_editor_settings() {
306 - $blanks = $this->get_data( 'answer_options' );
307 -
308 - global $post;
309 -
310 - return array_merge(
311 - parent::get_editor_settings(),
312 - array(
313 - 'id' => $post->ID,
314 - 'instantParseBlanks' => true,
315 - 'blankOptions' => $blanks ? array_values( $blanks ) : array(),
316 - 'blankFillsStyle' => get_post_meta( $post->ID, '_lp_blank_fills_style', true ),
317 - 'blanksStyle' => get_post_meta( $post->ID, '_lp_blanks_style', true ),
318 - )
319 - );
320 - }
321 -
322 - /**
323 - * Get input name.
324 - *
325 - * @param $fill
326 - *
327 - * @return string
328 - */
329 - public function get_input_name( $fill ) {
330 - return '_' . md5( wp_create_nonce( $fill ) );
331 - }
332 -
333 - /**
334 - * Set text format.
335 - *
336 - * @param $text
337 - *
338 - * @return string
339 - */
340 - private function _format_text( $text ) {
341 - return trim( preg_replace( '!\s+!', ' ', $text ) );
342 - }
343 -
344 - public function get_default_answers() {
345 - $default = array(
346 - array(
347 - 'is_true' => 'yes',
348 - 'value' => '',
349 - 'title' => '',
350 - ),
351 - );
352 -
353 - return $default;
354 - }
355 -
356 - /**
357 - * Check user answer.
358 - *
359 - * @param null $user_answer
360 - *
361 - * @return array
362 - */
363 - public function check( $user_answer = null ) {
364 - $return = parent::check();
365 - settype( $user_answer, 'array' );
366 - $answers = $this->get_answers();
367 -
368 - if ( $answers ) {
369 - foreach ( $answers as $key => $option ) {
370 - $blanks = $option->get_meta( '_blanks' );
371 - $return['blanks'] = array();
372 - $return['answered'] = array();
373 -
374 - if ( ! empty( $blanks ) ) {
375 - $total_field_input = count( $blanks );
376 - $total_answer_correct = 0;
377 -
378 - foreach ( $user_answer as $answer_id => $answer_value ) {
379 - $answer_id = trim( $answer_id );
380 -
381 - foreach ( $blanks as $blank ) {
382 - if ( $answer_id === $blank['id'] ) {
383 - $user_fill = trim( $answer_value );
384 - $blank_correct = $this->check_answer( $blank, $answer_value );
385 -
386 - $return['blanks'][ $answer_id ] = $blank_correct;
387 - $return['answered'][ $answer_id ] = $user_fill;
388 -
389 - if ( $blank_correct ) {
390 - $total_answer_correct++;
391 - }
392 - }
393 - }
394 - }
395 -
396 - if ( $total_answer_correct === $total_field_input ) {
397 - $return['correct'] = true;
398 - $return['mark'] = $this->get_mark();
399 - }
400 - }
401 - }
402 - }
403 -
404 - $question = $this;
405 - $data = compact( 'user_answer', 'answers', 'question' );
406 -
407 - return apply_filters( 'learn-press/question/fill-in-blank/check', $return, $data );
408 - }
409 -
410 - /**
411 - * Check answer fill in blank
412 - *
413 - * @param array $blank
414 - * @param $user_fill
415 - *
416 - * @return bool
417 - */
418 - public function check_answer( array $blank, $user_fill ): bool {
419 - $fill = trim( $blank['fill'] ?? '' );
420 - $comparison = ! empty( $blank['comparison'] ) ? $blank['comparison'] : false;
421 - $match_case = ! empty( $blank['match_case'] );
422 - $user_fill = trim( $user_fill );
423 -
424 - $blank_correct = false;
425 -
426 - switch ( $comparison ) {
427 - case 'range':
428 - if ( is_numeric( $user_fill ) ) {
429 - $fill = explode( ',', $fill );
430 - $words = array_map( 'trim', $fill );
431 - $words = array_map( 'floatval', $fill );
432 - $user_fill = floatval( $user_fill );
433 -
434 - if ( count( $words ) == 2 ) {
435 - $blank_correct = $words[0] <= $user_fill && $user_fill <= $words[1];
436 - }
437 - }
438 - break;
439 -
440 - case 'any':
441 - $fill = explode( ',', $fill );
442 - $words = array_map( 'trim', $fill );
443 -
444 - if ( ! $match_case ) {
445 - $words = array_map( 'strtolower', $words );
446 - $user_fill = strtolower( $user_fill );
447 - }
448 -
449 - $blank_correct = in_array( $user_fill, $words );
450 - break;
451 -
452 - default:
453 - if ( $match_case ) {
454 - $blank_correct = strcmp( $user_fill, $fill ) == 0;
455 - } else {
456 - $blank_correct = strcasecmp( mb_strtolower( $user_fill, 'UTF-8' ), mb_strtolower( $fill, 'UTF-8' ) ) == 0;
457 - }
458 - }
459 -
460 - $data = compact( 'blank', 'user_fill' );
461 -
462 - return apply_filters( 'learn-press/question/fill-in-blank/check_answer', $blank_correct, $data );
463 - }
464 - }
465 -}
466 -
1 +<?php
2 +/**
3 + * LP_Question_Fill_In_Blanks
4 + *
5 + * @author ThimPress
6 + * @package LearnPress/Templates
7 + * @version 4.0.0
8 + * @extends LP_Question
9 + */
10 +
11 +defined( 'ABSPATH' ) || exit();
12 +
13 +if ( ! class_exists( 'LP_Question_Fill_In_Blanks' ) ) {
14 +
15 + /**
16 + * Class LP_Question_Fill_In_Blanks
17 + */
18 + class LP_Question_Fill_In_Blanks extends LP_Question {
19 + /**
20 + * Type of this question.
21 + *
22 + * @var string
23 + */
24 + protected $_question_type = 'fill_in_blanks';
25 +
26 + /**
27 + * @var bool
28 + */
29 + protected $_answer_options = false;
30 +
31 + /**
32 + * LP_Question_Fill_In_Blanks constructor.
33 + *
34 + * @param null $the_question
35 + * @param null $args
36 + *
37 + * @throws Exception
38 + */
39 + public function __construct( $the_question = null, $args = null ) {
40 + parent::__construct( $the_question, $args );
41 +
42 + add_filter(
43 + 'learn-press/question-editor/localize-script',
44 + array( $this, 'sanitize_question_answers' ),
45 + 1000
46 + );
47 +
48 + add_action( 'learn-press/before-clear-question', array( $this, 'clear_question_answer_meta' ) );
49 +
50 + add_filter(
51 + 'learn-press/quiz-editor/question-answers-data',
52 + array( $this, 'admin_editor_question_answers' ),
53 + 10,
54 + 3
55 + );
56 + add_filter(
57 + 'learn-press/question-editor/question-answers-data',
58 + array( $this, 'admin_editor_question_answers' ),
59 + 10,
60 + 3
61 + );
62 +
63 + add_filter( 'learn-press/question/fib/regex-content', array( $this, 'match_shortcode_api' ), 10, 4 );
64 + }
65 +
66 + public function fib_get_ids( $content ) {
67 + $output = array();
68 +
69 + if ( ! empty( $content ) ) {
70 + preg_match_all(
71 + '/' . get_shortcode_regex( array( 'fib' ) ) . '/',
72 + $content,
73 + $all_shortcode,
74 + PREG_SET_ORDER
75 + );
76 +
77 + if ( ! empty( $all_shortcode ) ) {
78 + foreach ( $all_shortcode as $shortcode ) {
79 + $atts = shortcode_parse_atts( $shortcode[0] );
80 +
81 + if ( empty( $atts['id'] ) ) {
82 + $ida = explode( '=', str_replace( ']', '', $atts[1] ) );
83 + $ids = isset( $ida[1] ) ? str_replace( '"', '', $ida[1] ) : '';
84 + } else {
85 + $ids = $atts['id'];
86 + }
87 +
88 + $output[] = $ids;
89 + }
90 + }
91 + }
92 +
93 + return $output;
94 + }
95 +
96 + public function match_shortcode_api( $content, $answer_id, $show_answer = false, $answered = '' ) {
97 + if ( ! empty( $content ) ) {
98 + preg_match_all(
99 + '/' . get_shortcode_regex( array( 'fib' ) ) . '/',
100 + $content,
101 + $all_shortcode,
102 + PREG_SET_ORDER
103 + );
104 +
105 + if ( ! empty( $all_shortcode ) ) {
106 + foreach ( $all_shortcode as $shortcode ) {
107 + $atts = shortcode_parse_atts( $shortcode[0] );
108 +
109 + if ( empty( $atts['id'] ) ) {
110 + $ida = explode( '=', str_replace( ']', '', $atts[1] ) );
111 + $ids = isset( $ida[1] ) ? str_replace( '"', '', $ida[1] ) : '';
112 + } else {
113 + $ids = $atts['id'];
114 + }
115 +
116 + $fill = $atts['fill'] ?? '';
117 +
118 + $new_str = ' {{FIB_' . esc_attr( $ids ) . '}} ';
119 +
120 + $content = str_replace( $shortcode[0], $new_str, $content );
121 + }
122 + }
123 + }
124 +
125 + return $content;
126 + }
127 +
128 + public function get_answer_data( $content, $answer_id, $answered = '' ) {
129 + $output = array();
130 +
131 + if ( ! empty( $content ) ) {
132 + preg_match_all(
133 + '/' . get_shortcode_regex( array( 'fib' ) ) . '/',
134 + $content,
135 + $all_shortcode,
136 + PREG_SET_ORDER
137 + );
138 +
139 + if ( ! empty( $all_shortcode ) ) {
140 + foreach ( $all_shortcode as $shortcode ) {
141 + $atts = shortcode_parse_atts( $shortcode[0] );
142 +
143 + if ( empty( $atts['id'] ) ) {
144 + $ida = explode( '=', str_replace( ']', '', $atts[1] ) );
145 + $ids = isset( $ida[1] ) ? str_replace( '"', '', $ida[1] ) : '';
146 + } else {
147 + $ids = $atts['id'];
148 + }
149 +
150 + $fill = $atts['fill'] ?? '';
151 +
152 + if ( is_array( $answered ) ) {
153 + $answer = $answered[ $ids ] ?? '';
154 + } else {
155 + $answer = '';
156 + }
157 +
158 + $is_correct = false;
159 +
160 + $blanks = learn_press_get_question_answer_meta( $answer_id, '_blanks', true );
161 +
162 + if ( ! empty( $blanks ) ) {
163 + $is_correct = $this->check_answer( $blanks[ $ids ] ?? [], $answer );
164 + }
165 +
166 + $output[ $ids ]['is_correct'] = $is_correct;
167 + $output[ $ids ]['answer'] = $answer;
168 + $output[ $ids ]['correct'] = $fill;
169 + }
170 + }
171 + }
172 +
173 + return $output;
174 + }
175 +
176 + public function sanitize_question_answers( $data ) {
177 + global $post;
178 +
179 + if ( $post && ( $post->ID == $this->get_id() ) && isset( $data['root'] ) ) {
180 + if ( isset( $data['root']['answers'] ) ) {
181 + $answers = array();
182 + $old_answers = reset( $data['root']['answers'] );
183 +
184 + foreach ( $old_answers as $k => $v ) {
185 + if ( $k == '0' ) {
186 + $answers['title'] = str_replace( array( '=\"', '\"' ), array( '="', '"' ), $v );
187 + } else {
188 + $answers[ $k ] = $v;
189 + }
190 + }
191 + $data['root']['answers'] = array( $answers );
192 + }
193 + }
194 +
195 + return $data;
196 + }
197 +
198 + public function admin_editor_question_answers( $answers, $question_id, $quiz_id ) {
199 + $question = learn_press_get_question( $question_id );
200 +
201 + if ( ! $question ) {
202 + return $answers;
203 + }
204 +
205 + if ( 'fill_in_blanks' !== $question->get_type() ) {
206 + return $answers;
207 + }
208 +
209 + if ( $answers ) {
210 + foreach ( $answers as $k => $answer ) {
211 + $blanks = learn_press_get_question_answer_meta(
212 + $answer['question_answer_id'],
213 + '_blanks',
214 + true
215 + );
216 + $answers[ $k ]['blanks'] = ! empty( $blanks ) ? array_values( $blanks ) : array();
217 + }
218 + }
219 +
220 + return $answers;
221 + }
222 +
223 + /**
224 + * Clear answer meta of the question
225 + *
226 + * @param $question_id
227 + *
228 + * @since 4.0.0
229 + * @version 1.0.1
230 + */
231 + public function clear_question_answer_meta( $question_id ) {
232 + try {
233 + $question = LP_Question::get_question( $question_id );
234 + $answers = $question->get_answers();
235 +
236 + foreach ( $answers as $answer ) {
237 + $answer_id = $answer->get_id();
238 + $lp_db = LP_Database::getInstance();
239 + $filter = new LP_Question_Answermeta_Filter();
240 + $filter->collection = $lp_db->tb_lp_question_answermeta;
241 + $filter->where[] = $lp_db->wpdb->prepare( "AND learnpress_question_answer_id = %s", $answer_id );
242 + $lp_db->delete_execute( $filter );
243 + }
244 + } catch ( Throwable $e ) {
245 + error_log( __METHOD__ . ': ' . $e->getMessage() );
246 + }
247 + }
248 +
249 + /**
250 + * Get answer options of the question
251 + *
252 + * @param array $args - Optional.
253 + *
254 + * @return mixed
255 + */
256 + public function get_answer_options( $args = array() ) {
257 +
258 + $args = wp_parse_args(
259 + $args,
260 + array(
261 + 'exclude' => '',
262 + 'map' => '',
263 + 'answer' => '',
264 + )
265 + );
266 +
267 + if ( $args['exclude'] && is_string( $args['exclude'] ) ) {
268 + $exclude = array_map( 'trim', explode( ',', $args['exclude'] ) );
269 + } else {
270 + $exclude = $args['exclude'];
271 + }
272 +
273 + $map = $args['map'];
274 +
275 + $options = $this->get_data( 'answer_options' );
276 +
277 + // Remove key if it present in $exclude.
278 + if ( $options && ( $exclude || $map ) ) {
279 + $exclude = array_flip( $exclude );
280 +
281 + foreach ( $options as $k => $option ) {
282 + $is_true = ! isset( $exclude['is_true'] );
283 + $fib_answer = ! empty( $args['answer'] ) ? $args['answer'] : '';
284 + $title = $option['title'];
285 + $option['title'] = apply_filters( 'learn-press/question/fib/regex-content', $title, $option['question_answer_id'], $is_true, $fib_answer );
286 + $option['ids'] = $this->fib_get_ids( $title );
287 + $option['title_api'] = wp_strip_all_tags( $this->match_shortcode_api( $title, $option['question_answer_id'], $is_true, $fib_answer ) );
288 + $option['answers'] = $is_true ? $this->get_answer_data( $title, $option['question_answer_id'], $fib_answer ) : array();
289 +
290 + foreach ( $map as $k_map => $v_map ) {
291 + if ( array_key_exists( $k_map, $option ) ) {
292 + $option[ $v_map ] = $option[ $k_map ];
293 + $exclude[ $k_map ] = 1;
294 + }
295 + }
296 +
297 + $options[ $k ] = array_diff_key( $option, $exclude );
298 + }
299 + }
300 +
301 + return apply_filters( 'learn-press/question/answer-options', $options, $this->get_id() );
302 + }
303 +
304 +
305 + public function get_editor_settings() {
306 + $blanks = $this->get_data( 'answer_options' );
307 +
308 + global $post;
309 +
310 + return array_merge(
311 + parent::get_editor_settings(),
312 + array(
313 + 'id' => $post->ID,
314 + 'instantParseBlanks' => true,
315 + 'blankOptions' => $blanks ? array_values( $blanks ) : array(),
316 + 'blankFillsStyle' => get_post_meta( $post->ID, '_lp_blank_fills_style', true ),
317 + 'blanksStyle' => get_post_meta( $post->ID, '_lp_blanks_style', true ),
318 + )
319 + );
320 + }
321 +
322 + /**
323 + * Get input name.
324 + *
325 + * @param $fill
326 + *
327 + * @return string
328 + */
329 + public function get_input_name( $fill ) {
330 + return '_' . md5( wp_create_nonce( $fill ) );
331 + }
332 +
333 + /**
334 + * Set text format.
335 + *
336 + * @param $text
337 + *
338 + * @return string
339 + */
340 + private function _format_text( $text ) {
341 + return trim( preg_replace( '!\s+!', ' ', $text ) );
342 + }
343 +
344 + public function get_default_answers() {
345 + $default = array(
346 + array(
347 + 'is_true' => 'yes',
348 + 'value' => '',
349 + 'title' => '',
350 + ),
351 + );
352 +
353 + return $default;
354 + }
355 +
356 + /**
357 + * Check user answer.
358 + *
359 + * @param null $user_answer
360 + *
361 + * @return array
362 + */
363 + public function check( $user_answer = null ) {
364 + $return = parent::check();
365 + settype( $user_answer, 'array' );
366 + $answers = $this->get_answers();
367 +
368 + if ( $answers ) {
369 + foreach ( $answers as $key => $option ) {
370 + $blanks = $option->get_meta( '_blanks' );
371 + $return['blanks'] = array();
372 + $return['answered'] = array();
373 +
374 + if ( ! empty( $blanks ) ) {
375 + $total_field_input = count( $blanks );
376 + $total_answer_correct = 0;
377 +
378 + foreach ( $user_answer as $answer_id => $answer_value ) {
379 + $answer_id = trim( $answer_id );
380 +
381 + foreach ( $blanks as $blank ) {
382 + if ( $answer_id === $blank['id'] ) {
383 + $user_fill = trim( $answer_value );
384 + $blank_correct = $this->check_answer( $blank, $answer_value );
385 +
386 + $return['blanks'][ $answer_id ] = $blank_correct;
387 + $return['answered'][ $answer_id ] = $user_fill;
388 +
389 + if ( $blank_correct ) {
390 + $total_answer_correct++;
391 + }
392 + }
393 + }
394 + }
395 +
396 + if ( $total_answer_correct === $total_field_input ) {
397 + $return['correct'] = true;
398 + $return['mark'] = $this->get_mark();
399 + }
400 + }
401 + }
402 + }
403 +
404 + $question = $this;
405 + $data = compact( 'user_answer', 'answers', 'question' );
406 +
407 + return apply_filters( 'learn-press/question/fill-in-blank/check', $return, $data );
408 + }
409 +
410 + /**
411 + * Check answer fill in blank
412 + *
413 + * @param array $blank
414 + * @param $user_fill
415 + *
416 + * @return bool
417 + */
418 + public function check_answer( array $blank, $user_fill ): bool {
419 + $fill = trim( $blank['fill'] ?? '' );
420 + $comparison = ! empty( $blank['comparison'] ) ? $blank['comparison'] : false;
421 + $match_case = ! empty( $blank['match_case'] );
422 + $user_fill = trim( $user_fill );
423 +
424 + $blank_correct = false;
425 +
426 + switch ( $comparison ) {
427 + case 'range':
428 + if ( is_numeric( $user_fill ) ) {
429 + $fill = explode( ',', $fill );
430 + $words = array_map( 'trim', $fill );
431 + $words = array_map( 'floatval', $fill );
432 + $user_fill = floatval( $user_fill );
433 +
434 + if ( count( $words ) == 2 ) {
435 + $blank_correct = $words[0] <= $user_fill && $user_fill <= $words[1];
436 + }
437 + }
438 + break;
439 +
440 + case 'any':
441 + $fill = explode( ',', $fill );
442 + $words = array_map( 'trim', $fill );
443 +
444 + if ( ! $match_case ) {
445 + $words = array_map( 'strtolower', $words );
446 + $user_fill = strtolower( $user_fill );
447 + }
448 +
449 + $blank_correct = in_array( $user_fill, $words );
450 + break;
451 +
452 + default:
453 + if ( $match_case ) {
454 + $blank_correct = strcmp( $user_fill, $fill ) == 0;
455 + } else {
456 + $blank_correct = strcasecmp( mb_strtolower( $user_fill, 'UTF-8' ), mb_strtolower( $fill, 'UTF-8' ) ) == 0;
457 + }
458 + }
459 +
460 + $data = compact( 'blank', 'user_fill' );
461 +
462 + return apply_filters( 'learn-press/question/fill-in-blank/check_answer', $blank_correct, $data );
463 + }
464 + }
465 +}
466 +