Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/tutor-pro/addons/h5p/src/Results.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 + /**
3 + * Handle H5P Results
4 + *
5 + * @package TutorPro\Addons
6 + * @subpackage H5P
7 + * @author Themeum <support@themeum.com>
8 + * @link https://themeum.com
9 + * @since 3.0.0
10 + */
11 +
12 + namespace TutorPro\H5P;
13 +
14 + if ( ! defined( 'ABSPATH' ) ) {
15 + exit;
16 + }
17 + /**
18 + * Result class
19 + */
20 + class Results {
21 +
22 + /**
23 + * Provide the result response of h5p statements.
24 + *
25 + * @since 3.0.0
26 + *
27 + * @param object $statement the statement object.
28 + * @param array $choices possible choices for result.
29 + * @param string $correct_response_pattern correct response pattern.
30 + * @param array $h5p_targets possible targets for result.
31 + *
32 + * @return array
33 + */
34 + public static function get_h5p_statement_result_response( $statement, $choices, $correct_response_pattern, $h5p_targets ) {
35 + $response_results = array();
36 + if ( ! str_contains( $correct_response_pattern, '[,]' ) && str_contains( $correct_response_pattern, ',' ) ) {
37 + $correct_responses = explode( ',', $correct_response_pattern );
38 + $correct_response_pattern = implode( '[,]', $correct_responses );
39 + }
40 +
41 + if ( is_array( $choices ) && count( $choices ) ) {
42 +
43 + $all_choices = array_column( $choices, 'description', 'id' );
44 +
45 + if ( str_contains( $correct_response_pattern, '[,]' ) && ! str_contains( $correct_response_pattern, '[.]' ) ) {
46 + $correct_response_ids = explode( '[,]', $correct_response_pattern );
47 + $user_response_ids = explode( '[,]', $statement->result_response );
48 +
49 + self::prepare_choices_statements_correct_response_results( $correct_response_ids, $user_response_ids, $response_results, $all_choices, $choices );
50 +
51 + if ( count( $choices ) === count( $user_response_ids ) ) {
52 + self::get_sequencing_statements_result_response( $response_results, $user_response_ids );
53 + } else {
54 + self::get_choices_statements_user_result_response( $user_response_ids, $response_results );
55 + }
56 + }
57 +
58 + if ( ! str_contains( $correct_response_pattern, '[,]' ) && ! str_contains( $correct_response_pattern, '[.]' ) ) {
59 + $user_response = $statement->result_response;
60 +
61 + if ( isset( $statement->activity_interaction_type ) && 'true-false' === $statement->activity_interaction_type ) {
62 + self::get_true_false_statement_response( $correct_response_pattern, $user_response, $response_results );
63 + } else {
64 + self::get_choices_statement_response( $all_choices, $correct_response_pattern, $user_response, $response_results );
65 + }
66 + }
67 +
68 + if ( str_contains( $correct_response_pattern, '[.]' ) ) {
69 + self::get_drag_and_drop_statements_result_response( $correct_response_pattern, $statement, $h5p_targets, $choices, $all_choices, $response_results );
70 + }
71 + }
72 + if ( isset( $correct_response_pattern ) && ! isset( $choices ) ) {
73 + if ( str_contains( $correct_response_pattern, '[,]' ) && ! str_contains( $correct_response_pattern, '[.]' ) ) {
74 + $correct_responses = explode( '[,]', $correct_response_pattern );
75 + $user_responses = explode( '[,]', $statement->result_response );
76 +
77 + if ( count( $correct_responses ) === count( $user_responses ) ) {
78 + if ( isset( $statement->activity_interaction_type ) && 'fill-in' === $statement->activity_interaction_type ) {
79 + self::get_fill_in_statement_response( $statement, $user_responses, $correct_responses, $response_results );
80 + } else {
81 + self::get_sequencing_statements_result_response( $response_results, $user_responses );
82 + }
83 + } else {
84 + self::prepare_choices_statements_correct_response_results( $correct_responses, $user_responses, $response_results );
85 + self::get_choices_statements_user_result_response( $user_responses, $response_results );
86 + }
87 + }
88 +
89 + if ( ! str_contains( $correct_response_pattern, '[,]' ) && ! str_contains( $correct_response_pattern, '[.]' ) ) {
90 + $user_response = $statement->result_response;
91 +
92 + if ( isset( $statement->activity_interaction_type ) && 'true-false' === $statement->activity_interaction_type ) {
93 + self::get_true_false_statement_response( $correct_response_pattern, $user_response, $response_results );
94 + }
95 + }
96 + }
97 +
98 + if ( isset( $statement->activity_interaction_type ) && 'long-fill-in' === $statement->activity_interaction_type ) {
99 + self::get_essay_statement_response( $statement, $response_results );
100 + }
101 +
102 + return $response_results;
103 + }
104 +
105 + /**
106 + * Provide the correct response for choices h5p statement in response result array.
107 + *
108 + * @since 3.0.0
109 + *
110 + * @param array $correct_responses the correct responses for the h5p content.
111 + * @param array $user_responses the user provided responses for the content.
112 + * @param array $response_results the final response result.
113 + * @param array $all_choices possible choices for h5p content that could be correct.
114 + * @param array $choices possible choices for the h5p content.
115 + *
116 + * @return void
117 + */
118 + public static function prepare_choices_statements_correct_response_results( $correct_responses, $user_responses, &$response_results, $all_choices = null, $choices = null ) {
119 +
120 + if ( isset( $all_choices ) && isset( $choices ) ) {
121 + foreach ( $correct_responses as $response_id ) {
122 + if ( isset( $all_choices[ $response_id ] ) && count( $choices ) === count( $user_responses ) ) {
123 + $response_results[ $response_id ] = (object) array(
124 + 'is_correct' => true,
125 + 'description' => Utils::get_xpi_locale_property( $all_choices[ $response_id ] ),
126 + );
127 + unset( $all_choices[ $response_id ] );
128 + } elseif ( isset( $all_choices[ $response_id ] ) ) {
129 + $response_results[ $response_id ] = (object) array(
130 + 'is_solution' => true,
131 + 'description' => Utils::get_xpi_locale_property( $all_choices[ $response_id ] ),
132 + );
133 + unset( $all_choices[ $response_id ] );
134 + }
135 + }
136 +
137 + foreach ( $all_choices as $choice_id => $choice ) {
138 + $response_results[ $choice_id ] = (object) array(
139 + 'description' => Utils::get_xpi_locale_property( $all_choices[ $choice_id ] ),
140 + );
141 + }
142 + } else {
143 + foreach ( $correct_responses as $response_id => $response ) {
144 + if ( count( $correct_responses ) === count( $user_responses ) ) {
145 + $response_results[ $response ] = (object) array(
146 + 'is_correct' => true,
147 + 'description' => $response,
148 + );
149 + unset( $correct_responses[ $response_id ] );
150 + } else {
151 + $response_results[ $response ] = (object) array(
152 + 'is_solution' => true,
153 + 'description' => $response,
154 + );
155 + unset( $correct_responses[ $response_id ] );
156 + }
157 + }
158 +
159 + foreach ( $correct_responses as $response ) {
160 + $response_results[ $response ] = (object) array(
161 + 'description' => $response,
162 + );
163 + }
164 + }
165 + }
166 +
167 + /**
168 + * Provide the user result formatted for final result for choices type h5p content.
169 + *
170 + * @since 3.0.0
171 + *
172 + * @param array $user_responses the user provided responses for the h5p content.
173 + * @param array $response_results the final result returned.
174 + *
175 + * @return void
176 + */
177 + public static function get_choices_statements_user_result_response( $user_responses, &$response_results ) {
178 + foreach ( $user_responses as $user_id ) {
179 + $correct_response = $response_results[ $user_id ];
180 + if ( ! property_exists( $correct_response, 'is_correct' ) && ! property_exists( $correct_response, 'is_solution' ) ) {
181 + $correct_response = (array) $correct_response;
182 + $correct_response['is_correct'] = false;
183 + $response_results[ $user_id ] = (object) $correct_response;
184 + } elseif ( ! property_exists( $correct_response, 'is_correct' ) && property_exists( $correct_response, 'is_solution' ) ) {
185 + $correct_response = (array) $correct_response;
186 + $correct_response['is_correct'] = true;
187 + unset( $correct_response['is_solution'] );
188 + $response_results[ $user_id ] = (object) $correct_response;
189 + }
190 + }
191 + }
192 +
193 + /**
194 + * Sequencing type h5p content result response.
195 + *
196 + * @since 3.0.0
197 + *
198 + * @param array $response_results the final response result array.
199 + * @param array $user_responses the user provided response for the h5p content.
200 + *
201 + * @return void
202 + */
203 + public static function get_sequencing_statements_result_response( &$response_results, $user_responses ) {
204 + $idx = 0;
205 + foreach ( $response_results as $result_id => $result ) {
206 + // taking only the number portion from the value that contains the id.
207 + $user_response = (int) filter_var( $user_responses[ $idx ], FILTER_SANITIZE_NUMBER_INT );
208 + if ( $idx !== $user_response ) {
209 + $result->is_correct = false;
210 + $response_results[ $result_id ] = $result;
211 + }
212 + ++$idx;
213 + }
214 + }
215 +
216 + /**
217 + * Drag and drop type h5p content result response.
218 + *
219 + * @since 3.0.0
220 + *
221 + * @param string $correct_response_pattern the correct response pattern for the content.
222 + * @param object $statement the h5p statement object.
223 + * @param array $h5p_targets the possible targets for the h5p content.
224 + * @param array $choices the choices for the h5p content.
225 + * @param array $all_choices all possible choices for the h5p content.
226 + * @param array $response_results final response result array.
227 + *
228 + * @return void
229 + */
230 + public static function get_drag_and_drop_statements_result_response( $correct_response_pattern, $statement, $h5p_targets, $choices, $all_choices, &$response_results ) {
231 +
232 + $correct_responses = explode( '[,]', $correct_response_pattern );
233 + $user_responses = explode( '[,]', $statement->result_response );
234 + $all_targets = is_array( $h5p_targets ) && count( $h5p_targets ) ? array_column( $h5p_targets, 'description', 'id' ) : null;
235 +
236 + foreach ( $correct_responses as $correct_response ) {
237 +
238 + $correct_response = explode( '[.]', $correct_response );
239 + $correct_response = $correct_response[1] . '[.]' . $correct_response[0];
240 +
241 + $correct_response = explode( '[.]', $correct_response );
242 + $matches = (object) array(
243 + 'description' => Utils::get_xpi_locale_property( $all_choices[ $correct_response[0] ] ),
244 + 'match_id' => $correct_response[1],
245 + 'match_description' => is_array( $all_targets ) && count( $all_targets ) > 1 ? Utils::get_xpi_locale_property( $all_targets[ $correct_response[1] ] ) : Utils::get_xpi_locale_property( $all_targets[0] ),
246 + 'is_match' => true,
247 + );
248 + $response_results[ $correct_response[0] ] = $matches;
249 + }
250 +
251 + $final_response = array();
252 + foreach ( $user_responses as $user_response ) {
253 + $user_response = explode( '[.]', $user_response );
254 + $user_response = $user_response[1] . '[.]' . $user_response[0];
255 +
256 + $user_response = explode( '[.]', $user_response );
257 + $response = isset( $response_results[ $user_response[0] ] ) ? $response_results[ $user_response[0] ] : null;
258 + if ( $response ) {
259 + if ( $response->match_id !== $user_response[1] && count( $all_choices ) <= count( $all_targets ) ) {
260 + $matches = (object) array(
261 + 'description' => Utils::get_xpi_locale_property( $all_choices[ $user_response[0] ] ),
262 + 'match_id' => $user_response[1],
263 + 'match_description' => is_array( $all_targets ) && count( $all_targets ) > 1 ? Utils::get_xpi_locale_property( $all_targets[ $user_response[1] ] ) : Utils::get_xpi_locale_property( $all_targets[0] ?? $all_choices[ $user_response[1] ] ?? $choices[ $user_response[1] ]->description ),
264 + 'is_match' => false,
265 + );
266 + $response_results[ $user_response[0] ] = $matches;
267 + array_push( $final_response, $response_results[ $user_response[0] ] );
268 + } elseif ( $response->match_id !== $user_response[1] ) {
269 + $matches = (object) array(
270 + 'description' => Utils::get_xpi_locale_property( $all_choices[ $user_response[0] ] ),
271 + 'match_id' => $user_response[1],
272 + 'match_description' => is_array( $all_targets ) && count( $all_targets ) > 1 ? Utils::get_xpi_locale_property( $all_targets[ $user_response[1] ] ) : Utils::get_xpi_locale_property( $all_targets[0] ?? $all_choices[ $user_response[1] ] ?? $choices[ $user_response[1] ]->description ),
273 + 'is_match' => false,
274 + );
275 + array_push( $final_response, $matches );
276 + } else {
277 + array_push( $final_response, $response );
278 + }
279 + } else {
280 + $matches = (object) array(
281 + 'description' => Utils::get_xpi_locale_property( $all_choices[ $user_response[0] ] ),
282 + 'match_id' => $user_response[1],
283 + 'match_description' => is_array( $all_targets ) && count( $all_targets ) > 1 ? Utils::get_xpi_locale_property( $all_targets[ $user_response[1] ] ) : Utils::get_xpi_locale_property( $all_targets[0] ?? $all_choices[ $user_response[1] ] ?? $choices[ $user_response[1] ]->description ),
284 + 'is_match' => false,
285 + );
286 + array_push( $final_response, $matches );
287 + }
288 + }
289 + $response_results = $final_response;
290 + }
291 +
292 + /**
293 + * Get statement result response for choice type question
294 + * such as multiple choice, single choice etc.
295 + *
296 + * @since 3.0.0
297 + *
298 + * @param array $all_choices the possible choices for h5p result.
299 + * @param string $correct_response_pattern correct response pattern.
300 + * @param string $user_response user given response pattern.
301 + * @param array $response_results the returned response result.
302 + *
303 + * @return void
304 + */
305 + public static function get_choices_statement_response( $all_choices, $correct_response_pattern, $user_response, &$response_results ) {
306 + if ( isset( $all_choices[ $correct_response_pattern ] ) ) {
307 + $response_results[ $correct_response_pattern ] = (object) array(
308 + 'is_correct' => true,
309 + 'description' => Utils::get_xpi_locale_property( $all_choices[ $correct_response_pattern ] ),
310 + );
311 + unset( $all_choices[ $correct_response_pattern ] );
312 + }
313 +
314 + foreach ( $all_choices as $choice_id => $choice ) {
315 + $response_results[ $choice_id ] = (object) array(
316 + 'description' => Utils::get_xpi_locale_property( $all_choices[ $choice_id ] ),
317 + );
318 + }
319 +
320 + $correct_response = (array) $response_results[ $user_response ];
321 + if ( ! isset( $correct_response['is_correct'] ) ) {
322 + $correct_response['is_correct'] = false;
323 + }
324 +
325 + $response_results[ $user_response ] = (object) $correct_response;
326 + }
327 +
328 + /**
329 + * Get statement result for true false type h5p content.
330 + *
331 + * @since 3.0.0
332 + *
333 + * @param string $correct_response_pattern the correct response pattern.
334 + * @param string $user_response the user provided response pattern.
335 + * @param array $response_results the final returned response result.
336 + *
337 + * @return void
338 + */
339 + public static function get_true_false_statement_response( $correct_response_pattern, $user_response, &$response_results ) {
340 + $response_results = array(
341 + 'true' => (object) array(
342 + 'description' => __( 'True', 'tutor-pro' ),
343 + ),
344 + 'false' => (object) array(
345 + 'description' => __( 'False', 'tutor-pro' ),
346 + ),
347 + );
348 +
349 + $correct_response = (array) $response_results[ $correct_response_pattern ];
350 + $correct_response['is_correct'] = true;
351 + $response_results[ $correct_response_pattern ] = (object) $correct_response;
352 +
353 + $correct_response = (array) $response_results[ $user_response ];
354 +
355 + if ( ! isset( $correct_response['is_correct'] ) ) {
356 + $correct_response['is_correct'] = false;
357 + }
358 +
359 + $response_results[ $user_response ] = (object) $correct_response;
360 + }
361 +
362 + /**
363 + * Get response result for fill in the blank type h5p content.
364 + *
365 + * @since 3.0.0
366 + *
367 + * @param object $statement the statement object.
368 + * @param array $user_responses the user provided response array.
369 + * @param array $correct_responses the possible correct response array.
370 + * @param array $response_results the returned response result.
371 + *
372 + * @return void
373 + */
374 + public static function get_fill_in_statement_response( $statement, $user_responses, $correct_responses, &$response_results ) {
375 + $content = Utils::addon_config()->h5p_plugin->get_content( $statement->content_id );
376 + $content_settings = Utils::addon_config()->h5p_plugin->get_content_settings( $content );
377 + $main_content = isset( json_decode( $content_settings['jsonContent'] )->content ) ? json_decode( $content_settings['jsonContent'] )->content : null;
378 + if ( isset( $main_content ) ) {
379 + // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
380 + $correct_responses = $main_content->blanksList;
381 + foreach ( $user_responses as $key => $user_response ) {
382 + $haystack = (object) $correct_responses[ $key ];
383 + // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
384 + $haystack = html_entity_decode( $haystack->correctAnswerText );
385 + $haystack = explode( '/', $haystack );
386 + if ( in_array( $user_response, $haystack, true ) ) {
387 + array_push(
388 + $response_results,
389 + (object) array(
390 + 'description' => $user_response,
391 + 'is_correct' => true,
392 + )
393 + );
394 + } else {
395 + array_push(
396 + $response_results,
397 + (object) array(
398 + 'description' => $user_response,
399 + 'is_correct' => false,
400 + )
401 + );
402 + }
403 + }
404 + } else {
405 + foreach ( $user_responses as $key => $user_response ) {
406 + $correct_answer = strtolower( preg_replace( '/\{[^{]+\}/', '', $correct_responses[ $key ] ) );
407 + $correct_answer = str_replace( ' ', '', preg_replace( '/[^a-zA-Z0-9]+/', '', $correct_answer ) );
408 + $user_answer = strtolower( str_replace( ' ', '', preg_replace( '/[^a-zA-Z0-9]+/', '', $user_response ) ) );
409 + if ( $correct_answer === $user_answer ) {
410 + array_push(
411 + $response_results,
412 + (object) array(
413 + 'description' => $user_answer,
414 + 'is_correct' => true,
415 + )
416 + );
417 + } else {
418 + array_push(
419 + $response_results,
420 + (object) array(
421 + 'description' => $user_answer,
422 + 'is_correct' => false,
423 + )
424 + );
425 + }
426 + }
427 + }
428 + }
429 +
430 + /**
431 + * Get essay type h5p content statement result.
432 + *
433 + * @since 3.0.0
434 + *
435 + * @param object $statement the statement object.
436 + * @param array $response_results the final returned response result.
437 + *
438 + * @return void
439 + */
440 + public static function get_essay_statement_response( $statement, &$response_results ) {
441 + $content = Utils::addon_config()->h5p_plugin->get_content( $statement->content_id );
442 + $content_settings = Utils::addon_config()->h5p_plugin->get_content_settings( $content );
443 + $essay_keywords = isset( json_decode( $content_settings['jsonContent'] )->keywords ) ? json_decode( $content_settings['jsonContent'] )->keywords : null;
444 +
445 + if ( isset( $statement->activity_interaction_type ) && 'long-fill-in' === $statement->activity_interaction_type ) {
446 + $user_answer = $statement->result_response;
447 + if ( isset( $essay_keywords ) ) {
448 + foreach ( $essay_keywords as $essay_keyword ) {
449 + if ( isset( $essay_keyword->keyword ) ) {
450 + $user_answer = str_replace(
451 + preg_replace( '/[^a-zA-Z]+/', '', $essay_keyword->keyword ),
452 + "<span class='tutor-fw-bold tutor-color-success'>" . esc_attr( preg_replace( '/[^a-zA-Z]+/', '', $essay_keyword->keyword ) ) . '</span>',
453 + $user_answer
454 + );
455 + }
456 + if ( isset( $essay_keyword->alternatives ) ) {
457 + foreach ( $essay_keyword->alternatives as $alternative ) {
458 + $user_answer = str_replace(
459 + preg_replace( '/[^a-zA-Z]+/', '', $alternative ),
460 + "<span class='tutor-fw-bold tutor-color-success'>" . esc_attr( preg_replace( '/[^a-zA-Z]+/', '', $alternative ) ) . '</span>',
461 + $user_answer
462 + );
463 + }
464 + }
465 + }
466 + array_push(
467 + $response_results,
468 + array(
469 + 'essay_result' => $user_answer,
470 + )
471 + );
472 + }
473 + }
474 + }
475 + }
476 +