Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/fluentformpro/src/classes/Quiz/QuizController.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
3
+
4
+
namespace FluentFormPro\classes\Quiz;
5
+
6
+
use FluentForm\App\Helpers\Helper;
7
+
use FluentForm\App\Modules\Acl\Acl;
8
+
use FluentForm\App\Modules\Form\FormFieldsParser;
9
+
use FluentForm\App\Services\FormBuilder\ShortCodeParser;
10
+
use FluentForm\Framework\Helpers\ArrayHelper as Arr;
11
+
12
+
class QuizController
13
+
{
14
+
public $metaKey = '_quiz_settings';
15
+
public $key = 'quiz_addon';
16
+
protected $app;
17
+
18
+
public function init($app)
19
+
{
20
+
$this->app = $app;
21
+
$enabled = $this->isEnabled();
22
+
23
+
$this->addToGlobalMenu($enabled);
24
+
25
+
if (!$enabled) {
26
+
return;
27
+
}
28
+
$this->addToFormSettingsMenu();
29
+
30
+
$this->maybeRandomize();
31
+
32
+
$this->registerAjaxHandlers();
33
+
34
+
add_filter('fluentform/all_editor_shortcodes', function ($shortCodes) {
35
+
$shortCodes[] = [
36
+
'title' => __('Quiz', 'fluentformpro'),
37
+
'shortcodes' => [
38
+
'{quiz_result}' => 'Quiz Result Table'
39
+
]
40
+
];
41
+
return $shortCodes;
42
+
});
43
+
44
+
new QuizScoreComponent();
45
+
add_filter('safe_style_css', function ($styles) {
46
+
$style_tags = ['display'];
47
+
$style_tags = apply_filters('fluentform/allowed_css_properties', $style_tags);
48
+
foreach ($style_tags as $tag) {
49
+
$styles[] = $tag;
50
+
}
51
+
return $styles;
52
+
});
53
+
add_filter('fluentform/shortcode_parser_callback_quiz_result', [$this, 'getQuizResultTable'], 10, 2);
54
+
55
+
add_filter('fluentform/form_submission_confirmation', [$this, 'maybeAppendResult'], 10, 3);
56
+
57
+
add_filter('fluentform/submission_cards', [$this, 'pushQuizResult'], 10, 3);
58
+
}
59
+
60
+
public function registerAjaxHandlers()
61
+
{
62
+
$this->app->addAdminAjaxAction('ff_get_quiz_module_settings', [$this, 'getSettingsAjax']);
63
+
$this->app->addAdminAjaxAction('ff_store_quiz_module_settings', [$this, 'saveSettingsAjax']);
64
+
$this->app->addAdminAjaxAction('ff_delete_quiz_module_settings', [$this, 'deleteSettingsAjax']);
65
+
}
66
+
67
+
public function getSettingsAjax()
68
+
{
69
+
$formId = intval($this->app->request->get('form_id'));
70
+
Acl::verify('fluentform_forms_manager', $formId);
71
+
$settings = $this->getSettings($formId);
72
+
wp_send_json_success([
73
+
'settings' => $settings,
74
+
'quiz_fields' => $this->getQuizFields($formId),
75
+
'settings_fields' => QuizController::getIntegrationFields(),
76
+
]);
77
+
}
78
+
79
+
public function saveSettingsAjax()
80
+
{
81
+
$formId = intval($this->app->request->get('form_id'));
82
+
Acl::verify('fluentform_forms_manager', $formId);
83
+
$settings = $this->app->request->get('settings');
84
+
85
+
$sanitizeMap = [
86
+
'enabled' => 'rest_sanitize_boolean',
87
+
'randomize_answer' => 'rest_sanitize_boolean',
88
+
'append_result' => 'rest_sanitize_boolean',
89
+
'randomize_question' => 'rest_sanitize_boolean',
90
+
];
91
+
$settings = fluentform_backend_sanitizer($settings, $sanitizeMap);
92
+
93
+
$formattedSettings = wp_unslash($settings);
94
+
Helper::setFormMeta($formId, $this->metaKey, $formattedSettings);
95
+
96
+
wp_send_json_success([
97
+
'message' => __('Settings successfully updated', 'fluentformpro'),
98
+
]);
99
+
}
100
+
101
+
public function deleteSettingsAjax()
102
+
{
103
+
$formId = intval($this->app->request->get('form_id'));
104
+
Acl::verify('fluentform_forms_manager', $formId);
105
+
Helper::deleteFormMeta($formId, $this->metaKey);
106
+
107
+
wp_send_json_success([
108
+
'message' => __('Settings deleted successfully', 'fluentformpro'),
109
+
]);
110
+
}
111
+
112
+
public function getSettings($formId)
113
+
{
114
+
$settings = Helper::getFormMeta($formId, $this->metaKey, []);
115
+
$form = $this->getForm($formId);
116
+
$fields = $this->getQuizFields($form);
117
+
$resultType = self::getScoreType($form);
118
+
119
+
$defaults = [
120
+
'enabled' => false,
121
+
'randomize_answer' => false,
122
+
'append_result' => true,
123
+
'randomize_question' => false,
124
+
'saved_quiz_fields' => $fields,
125
+
'grades' => [
126
+
[
127
+
'label' => 'A',
128
+
'min' => 90,
129
+
'max' => 100,
130
+
],
131
+
[
132
+
'label' => 'B',
133
+
'min' => 80,
134
+
'max' => 89,
135
+
],
136
+
[
137
+
'label' => 'C',
138
+
'min' => 70,
139
+
'max' => 79,
140
+
],
141
+
]
142
+
];
143
+
144
+
$settings = $this->removeDeletedFields($settings, $fields);
145
+
146
+
$settings = wp_parse_args($settings, $defaults);
147
+
$settings['saved_quiz_fields'] = empty($settings['saved_quiz_fields']) ? [] : $settings['saved_quiz_fields'];
148
+
$settings['result_type'] = $resultType;
149
+
return $settings;
150
+
}
151
+
152
+
protected function getForm($formId)
153
+
{
154
+
return wpFluent()->table('fluentform_forms')->find($formId);
155
+
}
156
+
157
+
public static function getIntegrationFields()
158
+
{
159
+
return [
160
+
[
161
+
'key' => 'append_result',
162
+
'label' => 'Append Result',
163
+
'component' => 'checkbox-single',
164
+
'checkbox_label' => __('Show Result on confirmation page', 'fluentformpro')
165
+
166
+
],
167
+
[
168
+
'key' => 'randomize_question',
169
+
'label' => 'Randomize Questions',
170
+
'checkbox_label' => __('Questions will be randomized each time its loaded', 'fluentformpro'),
171
+
'component' => 'checkbox-single'
172
+
],
173
+
[
174
+
'key' => 'randomize_answer',
175
+
'label' => 'Randomize Options',
176
+
'checkbox_label' => __('Options will be randomized each time its loaded', 'fluentformpro'),
177
+
'component' => 'checkbox-single'
178
+
],
179
+
180
+
];
181
+
}
182
+
183
+
public function isEnabled()
184
+
{
185
+
$globalModules = get_option('fluentform_global_modules_status');
186
+
$quizAddon = Arr::get($globalModules, $this->key);
187
+
188
+
if ($quizAddon == 'yes') {
189
+
return true;
190
+
}
191
+
192
+
return false;
193
+
}
194
+
195
+
public function addToGlobalMenu($enabled)
196
+
{
197
+
add_filter('fluentform/global_addons', function ($addOns) use ($enabled) {
198
+
$addOns[$this->key] = [
199
+
'title' => 'Quiz Module',
200
+
'description' => __('With this module, you can create quizzes and show scores with grades, points, fractions, or percentages', 'fluentformpro'),
201
+
'logo' => fluentFormMix('img/integrations/quiz-icon.svg'),
202
+
'enabled' => ($enabled) ? 'yes' : 'no',
203
+
'config_url' => '',
204
+
'category' => ''
205
+
];
206
+
207
+
return $addOns;
208
+
}, 9);
209
+
}
210
+
211
+
public function addToFormSettingsMenu()
212
+
{
213
+
add_filter('fluentform/form_settings_menu', function ($menu) {
214
+
$menu['quiz_settings'] = [
215
+
'title' => __('Quiz Settings', 'fluentform'),
216
+
'slug' => 'form_settings',
217
+
'hash' => 'quiz_settings',
218
+
'route' => '/quiz_settings'
219
+
];
220
+
221
+
return $menu;
222
+
});
223
+
}
224
+
225
+
/**
226
+
* Maybe Randomize Questions and Answers
227
+
*
228
+
* @return void
229
+
*/
230
+
public function maybeRandomize()
231
+
{
232
+
233
+
add_filter('fluentform/rendering_form', function ($form) {
234
+
$settings = $this->getSettings($form->id);
235
+
$enabled = $settings['enabled'] == 'yes';
236
+
if (!$enabled) {
237
+
return $form;
238
+
}
239
+
if ($settings['randomize_answer']) {
240
+
$this->randomizeCheckableInputs();
241
+
}
242
+
if (!$settings['randomize_question']) {
243
+
return $form;
244
+
}
245
+
$fields = $form->fields;
246
+
247
+
$quizFields = $this->getQuizFields($form);
248
+
$quizFieldsKeys = array_keys($quizFields);
249
+
$formQuizFields = array_filter($fields['fields'], function ($field) use ($quizFieldsKeys) {
250
+
return in_array(Arr::get($field, 'attributes.name'), $quizFieldsKeys);
251
+
});
252
+
if (empty($formQuizFields)) {
253
+
return $form;
254
+
}
255
+
$quizGroup = [];
256
+
$i = 0;
257
+
foreach ($formQuizFields as $key => $field) {
258
+
$inSequence = isset($formQuizFields[$key + 1]) ? $formQuizFields[$key + 1] : false;
259
+
if ($inSequence) {
260
+
$quizGroup[$i][$key] = $field;
261
+
} else {
262
+
$quizGroup[$i][$key] = $field;
263
+
$i++;
264
+
}
265
+
}
266
+
//shuffle groups and replace their positions in the original array
267
+
foreach ($quizGroup as $group) {
268
+
$startIndex = Arr::get(array_keys($group), '0');
269
+
shuffle($group);
270
+
$length = count($group);
271
+
array_splice($fields['fields'], $startIndex, $length, $group);
272
+
}
273
+
274
+
$form->fields = $fields;
275
+
276
+
return $form;
277
+
}, 10, 1);
278
+
}
279
+
280
+
281
+
/**
282
+
* Generate Quiz Result Table
283
+
*
284
+
* @param $shortCode
285
+
* @param ShortCodeParser $parser
286
+
*
287
+
* @return string|void
288
+
*/
289
+
public function getQuizResultTable($shortCode, ShortCodeParser $parser)
290
+
{
291
+
$form = $parser::getForm();
292
+
$entry = $parser::getEntry();
293
+
$quizSettings = $this->getSettings($form->id);
294
+
$quizFields = Arr::get($quizSettings,'saved_quiz_fields');
295
+
296
+
if (!$entry || !$form || $quizSettings['enabled'] != 'yes') {
297
+
return;
298
+
}
299
+
300
+
$scoreType = self::getScoreType($form);
301
+
$response = json_decode($entry->response, true);
302
+
$results = $this->getFormattedResults($quizSettings, $response, $form);
303
+
304
+
/* For full width in single entry page */
305
+
$width = defined('FLUENTFORM_RENDERING_ENTRIES') ? '' : ' width="600"';
306
+
$html = '<table class="table ff_quiz_result_table" ' . $width . ' cellpadding="0" cellspacing="0" style="min-width: 100%"><tbody>';
307
+
$hasRightWrongAns = !in_array($scoreType, ['total_point', 'personality']) ? true : false;
308
+
$rightWrongHtml = '';
309
+
$forPdf = method_exists($parser, 'getProvider') && 'pdfFeed' === $parser::getProvider();
310
+
311
+
foreach ($results as $name => $result) {
312
+
313
+
if( !in_array($name,array_keys($quizFields))){
314
+
continue;
315
+
}
316
+
//question
317
+
318
+
$icon = $result['correct'] == true ? self::getRightIcon($forPdf) : self::getWrongIcon($forPdf);
319
+
$rightWrongHtml = $hasRightWrongAns ? "<div style='width: 20px; margin-right: 10px;'>$icon</div>" : '';
320
+
$html .= "<tr class=\"field-label\">
321
+
<td style=' align-items: center; padding: 6px 12px; background-color: #f8f8f8; text-align: left; clear: both; display: flex;'>
322
+
{$rightWrongHtml} <div><b>{$result['label']}</b></div>
323
+
</td>
324
+
</tr>";
325
+
//answer
326
+
if ('personality' == $scoreType) {
327
+
$result['user_value'] = static::labelFromValue($result['user_value'], $result['options'], $result, 'user_value');
328
+
}
329
+
$userValueFormatted = is_array($result['user_value']) ? join(', ', $result['user_value']) : $result['user_value'];
330
+
$userValueFormatted = empty($userValueFormatted) ? '-' :$userValueFormatted;
331
+
if (is_string($userValueFormatted)) {
332
+
$userValueFormatted = isset($result['options'][$userValueFormatted]) ? $result['options'][$userValueFormatted] : $userValueFormatted;
333
+
}
334
+
335
+
$html .= sprintf(
336
+
"<tr class=\"user-value\"><td style=\"padding: 6px 12px 12px 12px;\"> %s</td>",
337
+
$userValueFormatted
338
+
);
339
+
340
+
$correctAnsFormatted = is_array($result['correct_value']) ? join(', ', $result['correct_value']) : $result['correct_value'];
341
+
//skip right wrong for when total point is selected
342
+
if ($scoreType == 'total_point') {
343
+
$score = 0;
344
+
if ($result['has_advance_scoring'] == 'yes') {
345
+
$score = $result['advance_points_score'];
346
+
} else {
347
+
if ($result['correct']) {
348
+
$score = $result['points'];
349
+
}
350
+
}
351
+
352
+
$html .= sprintf(
353
+
"<tr class=\"field-value\"><td style=\"padding: 6px 12px 12px 12px;\">%s : %s</td>",
354
+
__('Point', 'fluentformpro'),
355
+
$score
356
+
);
357
+
}
358
+
else if (!$result['correct'] && $scoreType != 'total_point' && $scoreType != 'personality') {
359
+
$conditionText = '';
360
+
if ($result['correct_ans_condition'] == 'not_includes') {
361
+
$conditionText = 'does Not includes ';
362
+
} elseif ($result['correct_ans_condition'] == 'includes_any') {
363
+
$conditionText = 'any of the following ';
364
+
} elseif ($result['correct_ans_condition'] == 'includes_all') {
365
+
$conditionText = 'all of the following ';
366
+
}
367
+
if($rightWrongHtml){
368
+
$html .= sprintf(
369
+
"<tr class=\"field-value\"><td style=\"padding: 6px 12px 12px 12px;\">%s %s: %s</td>",
370
+
__('Correct answer', 'fluentformpro'),
371
+
$conditionText,
372
+
$correctAnsFormatted
373
+
);
374
+
}
375
+
376
+
}
377
+
$html .= '</tr>';
378
+
}
379
+
if ($scoreType == 'personality') {
380
+
381
+
$scoreInput = self::getScoreInput($form);
382
+
383
+
$personalityResult = $this->getUserSelectedValues($results);
384
+
$result = QuizScoreComponent::determinePersonality($personalityResult, $scoreInput, $form);
385
+
$result = Arr::get($scoreInput, "raw.options.$result", $result);
386
+
$personalityLabel = apply_filters('fluentform/quiz_personality_label',__('Personality', 'fluentformpro'),$form);
387
+
$html .= sprintf(
388
+
"<tr class=\"field-label\"> <td style=\"display:flex;align-items: center; padding: 6px 12px; background-color: #f8f8f8; text-align: left;\"> <div><b>%s </b></div></td></tr>",
389
+
$personalityLabel
390
+
);
391
+
392
+
$html .= sprintf(
393
+
"<tr class=\"field-value\"><td style=\"padding: 6px 12px 12px 12px;\">%s</td>",
394
+
$result
395
+
);
396
+
$html .= '</tr>';
397
+
398
+
}
399
+
400
+
$html .= '</tbody></table>';
401
+
return apply_filters('fluentform/quiz_result_table_html', $html, $form, $results, $quizSettings, $entry);
402
+
}
403
+
404
+
405
+
/**
406
+
* Get Available Quiz Fields
407
+
*
408
+
* @param $form
409
+
*
410
+
* @return array|mixed
411
+
*/
412
+
protected function getQuizFields($form)
413
+
{
414
+
$fields = FormFieldsParser::getEntryInputs($form, ['admin_label', 'label', 'element', 'options']);
415
+
$supportedQuizFields = [
416
+
'input_text',
417
+
'input_radio',
418
+
'input_checkbox',
419
+
'select',
420
+
'input_number',
421
+
'input_date',
422
+
'rangeslider'
423
+
];
424
+
$fields = array_filter($fields, function ($field) use ($supportedQuizFields) {
425
+
return in_array($field['element'], $supportedQuizFields);
426
+
});
427
+
428
+
foreach ($fields as $name => $value) {
429
+
$fields[$name]['enabled'] = false;
430
+
$fields[$name]['points'] = 1;
431
+
$fields[$name]['correct_answer'] = [];
432
+
$fields[$name]['condition'] = 'equal';
433
+
$fields[$name]['has_advance_scoring'] = 'no';
434
+
$fields[$name]['advance_points'] = $this->advancePoints($fields[$name]);
435
+
}
436
+
return $fields;
437
+
}
438
+
439
+
/**
440
+
* Remove Deleted inputs
441
+
*
442
+
* @param $settings
443
+
* @param $fields
444
+
*
445
+
* @return mixed
446
+
*/
447
+
protected function removeDeletedFields($settings, $fields)
448
+
{
449
+
if (!isset($settings['saved_quiz_fields'])) {
450
+
return $settings;
451
+
}
452
+
$savedFields = $settings['saved_quiz_fields'];
453
+
foreach ($savedFields as $fieldKey => $value) {
454
+
if (!isset($fields[$fieldKey])) {
455
+
unset($savedFields[$fieldKey]);
456
+
}
457
+
if (Arr::exists($fields,$fieldKey) && Arr::exists($fields[$fieldKey], 'options')) {
458
+
$savedFields[$fieldKey]['options'] = Arr::get($fields[$fieldKey], 'options');
459
+
}
460
+
}
461
+
$settings['saved_quiz_fields'] = $savedFields;
462
+
463
+
return $settings;
464
+
}
465
+
466
+
467
+
/**
468
+
* Validate Answer
469
+
*
470
+
* @param $settings
471
+
* @param $userValue
472
+
* @param $correctValue
473
+
*
474
+
* @return bool
475
+
*/
476
+
477
+
protected function isCorrect($settings, $userValue, $correctValue = '', $options = [])
478
+
{
479
+
$isCorrect = false;
480
+
$element = $settings['element'];
481
+
switch ($element) {
482
+
case 'input_radio':
483
+
if (!$userValue) {
484
+
break;
485
+
}
486
+
487
+
if (in_array($userValue, $correctValue)) {
488
+
$isCorrect = true;
489
+
}
490
+
491
+
break;
492
+
case 'select':
493
+
case 'input_text':
494
+
case 'rangeslider':
495
+
case 'input_date':
496
+
case 'input_checkbox':
497
+
case 'input_number':
498
+
if (!$userValue) {
499
+
break;
500
+
}
501
+
$hasAdvanceScoring = $settings['has_advance_scoring'] === 'yes';
502
+
if ($hasAdvanceScoring) {
503
+
//check if select is not a multiselect
504
+
if ($element == 'select' && is_string($correctValue)) {
505
+
$isCorrect = $userValue == $correctValue;
506
+
break;
507
+
}
508
+
509
+
//if it has advance scoring then for right answer match all value greater than 0 with user values
510
+
//else assume as wrong answer but count the scores
511
+
$correctValues = static::labelFromValue($correctValue, $options, $settings, 'correct_value');
512
+
513
+
return count(array_intersect($userValue, $correctValues)) == count($userValue);
514
+
}
515
+
$condition = Arr::get($settings, 'condition');
516
+
517
+
if ($condition == 'equal') {
518
+
if (is_array($correctValue)) {
519
+
$correctValue = array_shift($correctValue);
520
+
}
521
+
if (is_array($userValue)) {
522
+
$userValue = array_shift($userValue);
523
+
}
524
+
if (apply_filters('fluentform/quiz_case_sensitive_off', __return_false())) {
525
+
$userValue = strtolower($userValue);
526
+
$correctValue = strtolower($correctValue);
527
+
}
528
+
if ($userValue == $correctValue) {
529
+
$isCorrect = true;
530
+
}
531
+
} elseif ($condition == 'includes_any') {
532
+
//check if any user values exists in correct answers
533
+
if (!is_array($userValue)) {
534
+
$userValue = [$userValue];
535
+
}
536
+
$isCorrect = (bool)array_intersect($correctValue, $userValue);
537
+
} elseif ($condition == 'includes_all') {
538
+
//check if all user values exists in correct answers
539
+
if (!is_array($userValue)) {
540
+
$userValue = [$userValue];
541
+
}
542
+
$commonValue = array_intersect($correctValue, $userValue);
543
+
$isCorrect = $commonValue && count($commonValue) == count($userValue) && count($correctValue) == count($commonValue);
544
+
} elseif ($condition == 'not_includes') {
545
+
//check if all user values not exists in correct answers
546
+
if (!is_array($userValue)) {
547
+
$userValue = [$userValue];
548
+
}
549
+
$isCorrect = !array_intersect($correctValue, $userValue);
550
+
}
551
+
break;
552
+
}
553
+
554
+
return $isCorrect;
555
+
}
556
+
557
+
/**
558
+
* Get Formatted Quiz Result
559
+
*
560
+
* @param $quizFields
561
+
* @param $response
562
+
*
563
+
* @return array
564
+
*/
565
+
public function getFormattedResults($quizSettings, $response, $form)
566
+
{
567
+
$quizFields = $quizSettings['saved_quiz_fields'];
568
+
$quizType = Arr::get($quizSettings,'result_type');
569
+
$inputs = FormFieldsParser::getInputs($form, ['element', 'options', 'label']);
570
+
$quizResults = [];
571
+
$quizFields = $this->arrayReposition($quizFields, array_keys($inputs));
572
+
foreach ($quizFields as $key => $settings) {
573
+
if ($settings['enabled'] != true) {
574
+
continue;
575
+
}
576
+
$correctValue = Arr::get($settings, 'correct_answer');
577
+
$userValue = Arr::get($response, $key, '');
578
+
$options = Arr::get($inputs, $key . '.options');
579
+
$quizResults[$key] = [
580
+
'correct' => $this->isCorrect($settings, $userValue, $correctValue, $options),
581
+
'correct_value' => static::labelFromValue($correctValue, $options, $settings, 'correct_value'),
582
+
'correct_ans_condition' => $settings['condition'],
583
+
'options' => $options,
584
+
'user_value' => ($quizType != 'personality') ? static::labelFromValue($userValue, $options, $settings, 'user_value') : $userValue,
585
+
'points' => $settings['points'],
586
+
'label' => Arr::get($inputs, $key . '.label'),
587
+
'has_advance_scoring' => $settings['has_advance_scoring'],
588
+
'advance_points' => array_reduce($settings['advance_points'], function ($sum, $itemScore) {
589
+
$sum += $itemScore;
590
+
return $sum;
591
+
}),
592
+
'advance_points_score' => $this->calcAdvancePoints($settings, $userValue),
593
+
];
594
+
}
595
+
return $quizResults;
596
+
}
597
+
598
+
/**
599
+
* Calculate user selected values from quiz results.
600
+
*
601
+
* @param array $quizResults
602
+
* @return array
603
+
*/
604
+
public function getUserSelectedValues($quizResults)
605
+
{
606
+
$userSelectedValues = [];
607
+
foreach ($quizResults as $result) {
608
+
if(empty($result['user_value'])){
609
+
continue;
610
+
}
611
+
if (is_array($result['user_value'])) {
612
+
// If 'user_value' is an array
613
+
$userSelectedValues = array_merge($userSelectedValues, $result['user_value']);
614
+
} else {
615
+
// If 'user_value' is a string, convert it to an array
616
+
$userSelectedValues[] = $result['user_value'];
617
+
}
618
+
}
619
+
620
+
return $userSelectedValues;
621
+
}
622
+
/**
623
+
* Array Restructured to get Form Fields structure
624
+
* @param $array
625
+
* @param $keys
626
+
* @return array
627
+
*/
628
+
protected function arrayReposition($array, $keys)
629
+
{
630
+
$returnArray = [];
631
+
foreach ($keys as $key) {
632
+
if (Arr::get($array, $key)) {
633
+
$returnArray[$key] = Arr::get($array, $key);
634
+
}
635
+
}
636
+
637
+
return $returnArray;
638
+
}
639
+
640
+
/**
641
+
* Get input label from value
642
+
*
643
+
* @param $targetValues
644
+
* @param $options
645
+
* @param $settings
646
+
* @param $type
647
+
* @return array|mixed
648
+
*/
649
+
private static function labelFromValue($targetValues, $options, $settings, $type)
650
+
{
651
+
$hasAdvanceScoring = $settings['has_advance_scoring'] === 'yes';
652
+
if ($hasAdvanceScoring && $type == 'correct_value') {
653
+
$advanceScores = Arr::get($settings, 'advance_points');
654
+
$correctOptions = [];
655
+
foreach ($advanceScores as $label => $score) {
656
+
if ($score >= 1) {
657
+
$correctOptions[] = $label;
658
+
}
659
+
}
660
+
return $correctOptions;
661
+
}
662
+
if (is_array($targetValues)) {
663
+
$formattedValue = [];
664
+
foreach ($targetValues as $value) {
665
+
$formattedValue[] = isset($options[$value]) ? $options[$value] : $value;
666
+
}
667
+
$targetValues = $formattedValue;
668
+
} else {
669
+
$targetValues = isset($options[$targetValues]) ? $options[$targetValues] : $targetValues;
670
+
}
671
+
return $targetValues;
672
+
}
673
+
674
+
/**
675
+
* Maybe Append quiz result
676
+
*
677
+
* @param $data
678
+
* @param $formData
679
+
* @param $form
680
+
*
681
+
* @return mixed
682
+
*/
683
+
public function maybeAppendResult($data, $formData, $form)
684
+
{
685
+
$settings = $this->getSettings($form->id);
686
+
if ($settings['append_result'] == true) {
687
+
$data['messageToShow'] .= '{quiz_result}';
688
+
}
689
+
690
+
return $data;
691
+
}
692
+
693
+
694
+
/**
695
+
* Adds quiz result in the single entry page
696
+
* @param $cards
697
+
* @param $entryData
698
+
* @param $submission
699
+
* @return array|mixed
700
+
*/
701
+
public function pushQuizResult($cards, $entryData, $submission)
702
+
{
703
+
$formId = $submission->form_id;
704
+
705
+
$settings = $this->getSettings($formId);
706
+
707
+
if (($settings['enabled'] != 'yes')) {
708
+
return $cards;
709
+
}
710
+
$form = $this->getForm($formId);
711
+
712
+
$contents = '<p>{quiz_result}</p>';
713
+
$resultHtml = ShortCodeParser::parse(
714
+
$contents,
715
+
$submission->id,
716
+
$entryData,
717
+
$form
718
+
);
719
+
$widgetData = [
720
+
'title' => __('Quiz Result', 'fluentformpro'),
721
+
'content' => $resultHtml
722
+
];
723
+
724
+
$cards['quiz_result'] = $widgetData;
725
+
726
+
return $cards;
727
+
}
728
+
729
+
/**
730
+
* Wrong Answer Icon
731
+
*
732
+
* @return string
733
+
*/
734
+
protected static function getWrongIcon($forPdf)
735
+
{
736
+
$icon = '<svg fill="#e13636" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M17.459,16.014l8.239-8.194c0.395-0.391,0.395-1.024,0-1.414c-0.394-0.391-1.034-0.391-1.428,0 l-8.232,8.187L7.73,6.284c-0.394-0.395-1.034-0.395-1.428,0c-0.394,0.396-0.394,1.037,0,1.432l8.302,8.303l-8.332,8.286 c-0.394,0.391-0.394,1.024,0,1.414c0.394,0.391,1.034,0.391,1.428,0l8.325-8.279l8.275,8.276c0.394,0.395,1.034,0.395,1.428,0 c0.394-0.396,0.394-1.037,0-1.432L17.459,16.014z" /><g/><g/><g/><g/><g/><g/></svg>';
737
+
if ($forPdf) {
738
+
$icon = '<svg height="26" width="26" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g transform="translate(-5,-5)"><path fill="#e13636" d="M17.459,16.014l8.239-8.194c0.395-0.391,0.395-1.024,0-1.414c-0.394-0.391-1.034-0.391-1.428,0 l-8.232,8.187L7.73,6.284c-0.394-0.395-1.034-0.395-1.428,0c-0.394,0.396-0.394,1.037,0,1.432l8.302,8.303l-8.332,8.286 c-0.394,0.391-0.394,1.024,0,1.414c0.394,0.391,1.034,0.391,1.428,0l8.325-8.279l8.275,8.276c0.394,0.395,1.034,0.395,1.428,0 c0.394-0.396,0.394-1.037,0-1.432L17.459,16.014z" /></g></svg>';
739
+
}
740
+
return apply_filters('fluentform/quiz_wrong_ans_icon', $icon);
741
+
}
742
+
743
+
/**
744
+
* Right Answer Icon
745
+
*
746
+
* @return string
747
+
*/
748
+
protected static function getRightIcon($forPdf)
749
+
{
750
+
$icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#1a7efb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check"><polyline points="20 6 9 17 4 12"></polyline></svg>';
751
+
if ($forPdf) {
752
+
$icon = '<svg height="26" width="26" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-check"><polyline fill="none" stroke="#1a7efb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" points="20 6 9 17 4 12"></polyline></svg>';
753
+
}
754
+
return apply_filters('fluentform/quiz_right_ans_icon', $icon);
755
+
}
756
+
757
+
public function advancePoints($options)
758
+
{
759
+
if (!isset($options['options'])) {
760
+
return (object)[];
761
+
}
762
+
$formattedOptions = [];
763
+
foreach ($options['options'] as $key => $value) {
764
+
$formattedOptions[$key] = 0;
765
+
}
766
+
return $formattedOptions;
767
+
}
768
+
769
+
private function calcAdvancePoints($settings, $userValue)
770
+
{
771
+
$hasAdvancePoint = Arr::get($settings, 'has_advance_scoring');
772
+
if ($hasAdvancePoint) {
773
+
$advancePoints = Arr::get($settings, 'advance_points');
774
+
$userValue = is_array($userValue) ? $userValue : [$userValue];
775
+
$total = 0;
776
+
foreach ($userValue as $value) {
777
+
$value = Arr::get($advancePoints, $value, 0);
778
+
if (!is_numeric($value)) {
779
+
continue;
780
+
}
781
+
$total += $value;
782
+
}
783
+
return $total;
784
+
} else {
785
+
return Arr::get($settings, 'points');
786
+
}
787
+
}
788
+
789
+
private static function getScoreType($form)
790
+
{
791
+
$scoreType = '';
792
+
$scoreInput = self::getScoreInput($form);
793
+
if ($scoreInput) {
794
+
$scoreType = Arr::get($scoreInput, 'raw.settings.result_type');
795
+
}
796
+
return $scoreType;
797
+
}
798
+
public static function getScoreInput($form){
799
+
$scoreInput = \FluentForm\App\Modules\Form\FormFieldsParser::getInputsByElementTypes($form,['quiz_score'],['raw']);
800
+
if ($scoreInput) {
801
+
return array_shift($scoreInput);
802
+
}
803
+
return false;
804
+
}
805
+
806
+
public function randomizeCheckableInputs()
807
+
{
808
+
add_filter('fluentform/rendering_field_data_input_checkbox', function ($data) {
809
+
$options = $data['settings']['advanced_options'];
810
+
shuffle($options);
811
+
$data['settings']['advanced_options'] = $options;
812
+
813
+
return $data;
814
+
}, 10, 1);
815
+
816
+
add_filter('fluentform/rendering_field_data_input_radio', function ($data) {
817
+
$options = $data['settings']['advanced_options'];
818
+
shuffle($options);
819
+
$data['settings']['advanced_options'] = $options;
820
+
821
+
return $data;
822
+
}, 10, 1);
823
+
}
824
+
825
+
}
826
+