STRATO-apps/wordpress_03/app/wp-content/plugins/fluentformpro/src/classes/Quiz/QuizController.php

SHA-256: f16c09f7c3227d24381b08caea0ca1e22920cb4c9c65673cdcc470627759eac7
<?php


namespace FluentFormPro\classes\Quiz;

use FluentForm\App\Helpers\Helper;
use FluentForm\App\Modules\Acl\Acl;
use FluentForm\App\Modules\Form\FormFieldsParser;
use FluentForm\App\Services\FormBuilder\ShortCodeParser;
use FluentForm\Framework\Helpers\ArrayHelper as Arr;

class QuizController
{
    public $metaKey = '_quiz_settings';
    public $key = 'quiz_addon';
    protected $app;
    
    public function init($app)
    {
        $this->app = $app;
        $enabled = $this->isEnabled();
        
        $this->addToGlobalMenu($enabled);
        
        if (!$enabled) {
            return;
        }
        $this->addToFormSettingsMenu();

        $this->maybeRandomize();
        
        $this->registerAjaxHandlers();
        
        add_filter('fluentform/all_editor_shortcodes', function ($shortCodes) {
            $shortCodes[] = [
                'title' => __('Quiz', 'fluentformpro'),
                'shortcodes' => [
                    '{quiz_result}' => 'Quiz Result Table'
                ]
            ];
            return $shortCodes;
        });
        
        new QuizScoreComponent();
        add_filter('safe_style_css', function ($styles) {
            $style_tags = ['display'];
            $style_tags = apply_filters('fluentform/allowed_css_properties', $style_tags);
            foreach ($style_tags as $tag) {
                $styles[] = $tag;
            }
            return $styles;
        });
        add_filter('fluentform/shortcode_parser_callback_quiz_result', [$this, 'getQuizResultTable'], 10, 2);

        add_filter('fluentform/form_submission_confirmation', [$this, 'maybeAppendResult'], 10, 3);
        
        add_filter('fluentform/submission_cards', [$this, 'pushQuizResult'], 10, 3);
    }
    
    public function registerAjaxHandlers()
    {
        $this->app->addAdminAjaxAction('ff_get_quiz_module_settings', [$this, 'getSettingsAjax']);
        $this->app->addAdminAjaxAction('ff_store_quiz_module_settings', [$this, 'saveSettingsAjax']);
        $this->app->addAdminAjaxAction('ff_delete_quiz_module_settings', [$this, 'deleteSettingsAjax']);
    }
    
    public function getSettingsAjax()
    {
        $formId = intval($this->app->request->get('form_id'));
        Acl::verify('fluentform_forms_manager', $formId);
        $settings = $this->getSettings($formId);
        wp_send_json_success([
            'settings' => $settings,
            'quiz_fields' => $this->getQuizFields($formId),
            'settings_fields' => QuizController::getIntegrationFields(),
        ]);
    }
    
    public function saveSettingsAjax()
    {
        $formId = intval($this->app->request->get('form_id'));
        Acl::verify('fluentform_forms_manager', $formId);
        $settings = $this->app->request->get('settings');
        
        $sanitizeMap = [
            'enabled' => 'rest_sanitize_boolean',
            'randomize_answer' => 'rest_sanitize_boolean',
            'append_result' => 'rest_sanitize_boolean',
            'randomize_question' => 'rest_sanitize_boolean',
        ];
        $settings = fluentform_backend_sanitizer($settings, $sanitizeMap);
        
        $formattedSettings = wp_unslash($settings);
        Helper::setFormMeta($formId, $this->metaKey, $formattedSettings);
        
        wp_send_json_success([
            'message' => __('Settings successfully updated', 'fluentformpro'),
        ]);
    }

    public function deleteSettingsAjax()
    {
        $formId = intval($this->app->request->get('form_id'));
        Acl::verify('fluentform_forms_manager', $formId);
        Helper::deleteFormMeta($formId, $this->metaKey);

        wp_send_json_success([
            'message' => __('Settings deleted successfully', 'fluentformpro'),
        ]);
    }
    
    public function getSettings($formId)
    {
        $settings = Helper::getFormMeta($formId, $this->metaKey, []);
        $form = $this->getForm($formId);
        $fields = $this->getQuizFields($form);
        $resultType = self::getScoreType($form);
    
        $defaults = [
            'enabled'            => false,
            'randomize_answer'   => false,
            'append_result'      => true,
            'randomize_question' => false,
            'saved_quiz_fields'  => $fields,
            'grades'             => [
                [
                    'label' => 'A',
                    'min'   => 90,
                    'max'   => 100,
                ],
                [
                    'label' => 'B',
                    'min'   => 80,
                    'max'   => 89,
                ],
                [
                    'label' => 'C',
                    'min'   => 70,
                    'max'   => 79,
                ],
            ]
        ];
        
        $settings = $this->removeDeletedFields($settings, $fields);
        
        $settings = wp_parse_args($settings, $defaults);
        $settings['saved_quiz_fields'] = empty($settings['saved_quiz_fields']) ? [] : $settings['saved_quiz_fields'];
        $settings['result_type'] = $resultType;
        return $settings;
    }
    
    protected function getForm($formId)
    {
        return wpFluent()->table('fluentform_forms')->find($formId);
    }
    
    public static function getIntegrationFields()
    {
        return [
            [
                'key' => 'append_result',
                'label' => 'Append Result',
                'component' => 'checkbox-single',
                'checkbox_label' => __('Show Result on confirmation page', 'fluentformpro')
            
            ],
            [
                'key' => 'randomize_question',
                'label' => 'Randomize Questions',
                'checkbox_label' => __('Questions will be randomized each time its loaded', 'fluentformpro'),
                'component' => 'checkbox-single'
            ],
            [
                'key' => 'randomize_answer',
                'label' => 'Randomize Options',
                'checkbox_label' => __('Options will be randomized each time its loaded', 'fluentformpro'),
                'component' => 'checkbox-single'
            ],
        
        ];
    }
    
    public function isEnabled()
    {
        $globalModules = get_option('fluentform_global_modules_status');
        $quizAddon = Arr::get($globalModules, $this->key);
        
        if ($quizAddon == 'yes') {
            return true;
        }
        
        return false;
    }
    
    public function addToGlobalMenu($enabled)
    {
        add_filter('fluentform/global_addons', function ($addOns) use ($enabled) {
            $addOns[$this->key] = [
                'title' => 'Quiz Module',
                'description' => __('With this module, you can create quizzes and show scores with grades, points, fractions, or percentages', 'fluentformpro'),
                'logo' => fluentFormMix('img/integrations/quiz-icon.svg'),
                'enabled' => ($enabled) ? 'yes' : 'no',
                'config_url' => '',
                'category' => ''
            ];
            
            return $addOns;
        }, 9);
    }
    
    public function addToFormSettingsMenu()
    {
        add_filter('fluentform/form_settings_menu', function ($menu) {
            $menu['quiz_settings'] = [
                'title' => __('Quiz Settings', 'fluentform'),
                'slug' => 'form_settings',
                'hash' => 'quiz_settings',
                'route' => '/quiz_settings'
            ];
            
            return $menu;
        });
    }
    
    /**
     * Maybe Randomize Questions and Answers
     *
     * @return void
     */
    public function maybeRandomize()
    {
        
        add_filter('fluentform/rendering_form', function ($form) {
            $settings = $this->getSettings($form->id);
            $enabled = $settings['enabled'] == 'yes';
            if (!$enabled) {
                return $form;
            }
            if ($settings['randomize_answer']) {
                $this->randomizeCheckableInputs();
            }
            if (!$settings['randomize_question']) {
                return $form;
            }
            $fields = $form->fields;
    
            $quizFields = $this->getQuizFields($form);
            $quizFieldsKeys = array_keys($quizFields);
            $formQuizFields = array_filter($fields['fields'], function ($field) use ($quizFieldsKeys) {
                return in_array(Arr::get($field, 'attributes.name'), $quizFieldsKeys);
            });
            if (empty($formQuizFields)) {
                return $form;
            }
            $quizGroup = [];
            $i = 0;
            foreach ($formQuizFields as $key => $field) {
                $inSequence = isset($formQuizFields[$key + 1]) ? $formQuizFields[$key + 1] : false;
                if ($inSequence) {
                    $quizGroup[$i][$key] = $field;
                } else {
                    $quizGroup[$i][$key] = $field;
                    $i++;
                }
            }
            //shuffle groups and replace their positions in the original array
            foreach ($quizGroup as $group) {
                $startIndex = Arr::get(array_keys($group), '0');
                shuffle($group);
                $length = count($group);
                array_splice($fields['fields'], $startIndex, $length, $group);
            }
    
            $form->fields = $fields;
            
            return $form;
        }, 10, 1);
    }
    
    
    /**
     * Generate Quiz Result Table
     *
     * @param $shortCode
     * @param ShortCodeParser $parser
     *
     * @return string|void
     */
    public function getQuizResultTable($shortCode, ShortCodeParser $parser)
    {
        $form = $parser::getForm();
        $entry = $parser::getEntry();
        $quizSettings = $this->getSettings($form->id);
        $quizFields = Arr::get($quizSettings,'saved_quiz_fields');
    
        if (!$entry || !$form || $quizSettings['enabled'] != 'yes') {
            return;
        }
       
        $scoreType = self::getScoreType($form);
        $response = json_decode($entry->response, true);
        $results = $this->getFormattedResults($quizSettings, $response, $form);
        
        /* For full width in single entry page */
        $width = defined('FLUENTFORM_RENDERING_ENTRIES') ? '' : ' width="600"';
        $html = '<table class="table ff_quiz_result_table"  ' . $width . ' cellpadding="0" cellspacing="0" style="min-width: 100%"><tbody>';
        $hasRightWrongAns = !in_array($scoreType, ['total_point', 'personality']) ? true : false;
        $rightWrongHtml = '';
        $forPdf = method_exists($parser, 'getProvider') && 'pdfFeed' === $parser::getProvider();
        
        foreach ($results as $name => $result) {
    
            if( !in_array($name,array_keys($quizFields))){
                continue;
            }
            //question
    
            $icon = $result['correct'] == true ? self::getRightIcon($forPdf) : self::getWrongIcon($forPdf);
            $rightWrongHtml = $hasRightWrongAns ? "<div style='width: 20px; margin-right: 10px;'>$icon</div>" : '';
            $html .= "<tr class=\"field-label\">
                        <td style=' align-items: center; padding: 6px 12px; background-color: #f8f8f8; text-align: left; clear: both; display: flex;'>
                           {$rightWrongHtml} <div><b>{$result['label']}</b></div>
                        </td>
                    </tr>";
            //answer
            if ('personality' == $scoreType) {
                $result['user_value'] = static::labelFromValue($result['user_value'], $result['options'], $result, 'user_value');
            }
            $userValueFormatted = is_array($result['user_value']) ? join(', ', $result['user_value']) : $result['user_value'];
            $userValueFormatted = empty($userValueFormatted) ? '-' :$userValueFormatted;
            if (is_string($userValueFormatted)) {
                $userValueFormatted = isset($result['options'][$userValueFormatted]) ? $result['options'][$userValueFormatted] : $userValueFormatted;
            }
            
            $html .= sprintf(
                "<tr class=\"user-value\"><td style=\"padding: 6px 12px 12px 12px;\"> %s</td>",
                $userValueFormatted
            );
            
            $correctAnsFormatted = is_array($result['correct_value']) ? join(', ', $result['correct_value']) : $result['correct_value'];
            //skip right wrong for when total point is selected
             if ($scoreType == 'total_point') {
                $score = 0;
                if ($result['has_advance_scoring'] == 'yes') {
                    $score = $result['advance_points_score'];
                } else {
                    if ($result['correct']) {
                        $score = $result['points'];
                    }
                }
                
                $html .= sprintf(
                    "<tr class=\"field-value\"><td style=\"padding: 6px 12px 12px 12px;\">%s : %s</td>",
                    __('Point', 'fluentformpro'),
                    $score
                );
             }
             else if (!$result['correct'] && $scoreType != 'total_point' && $scoreType != 'personality') {
                 $conditionText = '';
                 if ($result['correct_ans_condition'] == 'not_includes') {
                     $conditionText = 'does Not includes ';
                 } elseif ($result['correct_ans_condition'] == 'includes_any') {
                     $conditionText = 'any of the following ';
                 } elseif ($result['correct_ans_condition'] == 'includes_all') {
                     $conditionText = 'all of the following ';
                 }
                 if($rightWrongHtml){
                     $html .= sprintf(
                         "<tr class=\"field-value\"><td style=\"padding: 6px 12px 12px 12px;\">%s %s: %s</td>",
                         __('Correct answer', 'fluentformpro'),
                         $conditionText,
                         $correctAnsFormatted
                     );
                 }
    
             }
            $html .= '</tr>';
        }
        if ($scoreType == 'personality') {
    
            $scoreInput = self::getScoreInput($form);
    
            $personalityResult = $this->getUserSelectedValues($results);
            $result = QuizScoreComponent::determinePersonality($personalityResult, $scoreInput, $form);
            $result = Arr::get($scoreInput, "raw.options.$result", $result);
            $personalityLabel = apply_filters('fluentform/quiz_personality_label',__('Personality', 'fluentformpro'),$form);
            $html .= sprintf(
                "<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>",
                $personalityLabel
            );
    
            $html .= sprintf(
                "<tr class=\"field-value\"><td style=\"padding: 6px 12px 12px 12px;\">%s</td>",
                $result
            );
            $html .= '</tr>';
    
        }
    
        $html .= '</tbody></table>';
        return apply_filters('fluentform/quiz_result_table_html', $html, $form, $results, $quizSettings, $entry);
    }
    
    
    /**
     * Get Available Quiz Fields
     *
     * @param $form
     *
     * @return array|mixed
     */
    protected function getQuizFields($form)
    {
        $fields = FormFieldsParser::getEntryInputs($form, ['admin_label', 'label', 'element', 'options']);
        $supportedQuizFields = [
            'input_text',
            'input_radio',
            'input_checkbox',
            'select',
            'input_number',
            'input_date',
            'rangeslider'
        ];
        $fields = array_filter($fields, function ($field) use ($supportedQuizFields) {
            return in_array($field['element'], $supportedQuizFields);
        });
    
        foreach ($fields as $name => $value) {
            $fields[$name]['enabled'] = false;
            $fields[$name]['points'] = 1;
            $fields[$name]['correct_answer'] = [];
            $fields[$name]['condition'] = 'equal';
            $fields[$name]['has_advance_scoring'] = 'no';
            $fields[$name]['advance_points'] = $this->advancePoints($fields[$name]);
        }
        return $fields;
    }
    
    /**
     * Remove Deleted inputs
     *
     * @param $settings
     * @param $fields
     *
     * @return mixed
     */
    protected function removeDeletedFields($settings, $fields)
    {
        if (!isset($settings['saved_quiz_fields'])) {
            return $settings;
        }
        $savedFields = $settings['saved_quiz_fields'];
        foreach ($savedFields as $fieldKey => $value) {
            if (!isset($fields[$fieldKey])) {
                unset($savedFields[$fieldKey]);
            }
            if (Arr::exists($fields,$fieldKey) && Arr::exists($fields[$fieldKey], 'options')) {
                $savedFields[$fieldKey]['options'] = Arr::get($fields[$fieldKey], 'options');
            }
        }
        $settings['saved_quiz_fields'] = $savedFields;
        
        return $settings;
    }
    
    
    /**
     * Validate Answer
     *
     * @param $settings
     * @param $userValue
     * @param $correctValue
     *
     * @return bool
     */

    protected function isCorrect($settings, $userValue, $correctValue = '', $options = [])
    {
        $isCorrect = false;
        $element = $settings['element'];
        switch ($element) {
            case 'input_radio':
                if (!$userValue) {
                    break;
                }
                
                if (in_array($userValue, $correctValue)) {
                    $isCorrect = true;
                }
                
                break;
            case 'select':
            case 'input_text':
            case 'rangeslider':
            case 'input_date':
            case 'input_checkbox':
            case 'input_number':
                if (!$userValue) {
                    break;
                }
                $hasAdvanceScoring = $settings['has_advance_scoring'] === 'yes';
                if ($hasAdvanceScoring) {
                    //check if select is not a multiselect
                    if ($element == 'select' && is_string($correctValue)) {
                        $isCorrect = $userValue == $correctValue;
                        break;
                    }

                    //if it has advance scoring then for right answer match all value greater than 0 with user values
                    //else assume as wrong answer but count the scores
                    $correctValues = static::labelFromValue($correctValue, $options, $settings, 'correct_value');
                  
                    return count(array_intersect($userValue, $correctValues)) == count($userValue);
                }
                $condition = Arr::get($settings, 'condition');
            
                if ($condition == 'equal') {
                    if (is_array($correctValue)) {
                        $correctValue = array_shift($correctValue);
                    }
                    if (is_array($userValue)) {
                        $userValue = array_shift($userValue);
                    }
                    if (apply_filters('fluentform/quiz_case_sensitive_off', __return_false())) {
                        $userValue = strtolower($userValue);
                        $correctValue = strtolower($correctValue);
                    }
                    if ($userValue == $correctValue) {
                        $isCorrect = true;
                    }
                } elseif ($condition == 'includes_any') {
                    //check if any user values exists in correct answers
                    if (!is_array($userValue)) {
                        $userValue = [$userValue];
                    }
                    $isCorrect = (bool)array_intersect($correctValue, $userValue);
                } elseif ($condition == 'includes_all') {
                    //check if all user values exists in correct answers
                    if (!is_array($userValue)) {
                        $userValue = [$userValue];
                    }
                    $commonValue = array_intersect($correctValue, $userValue);
                    $isCorrect = $commonValue && count($commonValue) == count($userValue) && count($correctValue) == count($commonValue);
                } elseif ($condition == 'not_includes') {
                    //check if all user values not exists in correct answers
                    if (!is_array($userValue)) {
                        $userValue = [$userValue];
                    }
                    $isCorrect = !array_intersect($correctValue, $userValue);
                }
                break;
        }
        
        return $isCorrect;
    }
    
    /**
     * Get Formatted Quiz Result
     *
     * @param $quizFields
     * @param $response
     *
     * @return array
     */
    public function getFormattedResults($quizSettings, $response, $form)
    {
        $quizFields = $quizSettings['saved_quiz_fields'];
        $quizType = Arr::get($quizSettings,'result_type');
        $inputs = FormFieldsParser::getInputs($form, ['element', 'options', 'label']);
        $quizResults = [];
        $quizFields = $this->arrayReposition($quizFields, array_keys($inputs));
        foreach ($quizFields as $key => $settings) {
            if ($settings['enabled'] != true) {
                continue;
            }
            $correctValue = Arr::get($settings, 'correct_answer');
            $userValue = Arr::get($response, $key, '');
            $options = Arr::get($inputs, $key . '.options');
            $quizResults[$key] = [
                'correct'               => $this->isCorrect($settings, $userValue, $correctValue, $options),
                'correct_value'         => static::labelFromValue($correctValue, $options, $settings, 'correct_value'),
                'correct_ans_condition' => $settings['condition'],
                'options'               => $options,
                'user_value'            => ($quizType != 'personality') ? static::labelFromValue($userValue, $options, $settings, 'user_value') : $userValue,
                'points'                => $settings['points'],
                'label'                 => Arr::get($inputs, $key . '.label'),
                'has_advance_scoring'   => $settings['has_advance_scoring'],
                'advance_points'        => array_reduce($settings['advance_points'], function ($sum, $itemScore) {
                    $sum += $itemScore;
                    return $sum;
                }),
                'advance_points_score'  => $this->calcAdvancePoints($settings, $userValue),
            ];
        }
        return $quizResults;
    }
    
    /**
     * Calculate user selected values from quiz results.
     *
     * @param array $quizResults
     * @return array
     */
    public function getUserSelectedValues($quizResults)
    {
        $userSelectedValues = [];
        foreach ($quizResults as $result) {
            if(empty($result['user_value'])){
                continue;
            }
            if (is_array($result['user_value'])) {
                // If 'user_value' is an array
                $userSelectedValues = array_merge($userSelectedValues, $result['user_value']);
            } else {
                // If 'user_value' is a string, convert it to an array
                $userSelectedValues[] = $result['user_value'];
            }
        }
        
        return $userSelectedValues;
    }
    /**
     * Array Restructured to get Form Fields structure
     * @param $array
     * @param $keys
     * @return array
     */
    protected function arrayReposition($array, $keys)
    {
        $returnArray = [];
        foreach ($keys as $key) {
            if (Arr::get($array, $key)) {
                $returnArray[$key] = Arr::get($array, $key);
            }
        }

        return $returnArray;
    }
    
    /**
     * Get input label from value
     *
     * @param $targetValues
     * @param $options
     * @param $settings
     * @param $type
     * @return array|mixed
     */
    private static function labelFromValue($targetValues, $options, $settings, $type)
    {
        $hasAdvanceScoring = $settings['has_advance_scoring'] === 'yes';
        if ($hasAdvanceScoring && $type == 'correct_value') {
            $advanceScores = Arr::get($settings, 'advance_points');
            $correctOptions = [];
            foreach ($advanceScores as $label => $score) {
                if ($score >= 1) {
                    $correctOptions[] = $label;
                }
            }
            return $correctOptions;
        }
        if (is_array($targetValues)) {
            $formattedValue = [];
            foreach ($targetValues as $value) {
                $formattedValue[] = isset($options[$value]) ? $options[$value] : $value;
            }
            $targetValues = $formattedValue;
        } else {
            $targetValues = isset($options[$targetValues]) ? $options[$targetValues] : $targetValues;
        }
        return $targetValues;
    }
    
    /**
     * Maybe Append quiz result
     *
     * @param $data
     * @param $formData
     * @param $form
     *
     * @return mixed
     */
    public function maybeAppendResult($data, $formData, $form)
    {
        $settings = $this->getSettings($form->id);
        if ($settings['append_result'] == true) {
            $data['messageToShow'] .= '{quiz_result}';
        }
        
        return $data;
    }
    
    
    /**
     * Adds quiz result in the single entry page
     * @param $cards
     * @param $entryData
     * @param $submission
     * @return array|mixed
     */
    public function pushQuizResult($cards, $entryData, $submission)
    {
        $formId = $submission->form_id;
        
        $settings = $this->getSettings($formId);
        
        if (($settings['enabled'] != 'yes')) {
            return $cards;
        }
        $form = $this->getForm($formId);
        
        $contents = '<p>{quiz_result}</p>';
        $resultHtml = ShortCodeParser::parse(
            $contents,
            $submission->id,
            $entryData,
            $form
        );
        $widgetData = [
            'title' => __('Quiz Result', 'fluentformpro'),
            'content' => $resultHtml
        ];
        
        $cards['quiz_result'] = $widgetData;
        
        return $cards;
    }
    
    /**
     * Wrong Answer Icon
     *
     * @return string
     */
    protected static function getWrongIcon($forPdf)
    {
        $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>';
        if ($forPdf) {
            $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>';
        }
        return apply_filters('fluentform/quiz_wrong_ans_icon', $icon);
    }
    
    /**
     * Right Answer Icon
     *
     * @return string
     */
    protected static function getRightIcon($forPdf)
    {
        $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>';
        if ($forPdf) {
            $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>';
        }
        return apply_filters('fluentform/quiz_right_ans_icon', $icon);
    }
    
    public function advancePoints($options)
    {
        if (!isset($options['options'])) {
            return (object)[];
        }
        $formattedOptions = [];
        foreach ($options['options'] as $key => $value) {
            $formattedOptions[$key] = 0;
        }
        return $formattedOptions;
    }
    
    private function calcAdvancePoints($settings, $userValue)
    {
        $hasAdvancePoint = Arr::get($settings, 'has_advance_scoring');
        if ($hasAdvancePoint) {
            $advancePoints = Arr::get($settings, 'advance_points');
            $userValue = is_array($userValue) ? $userValue : [$userValue];
            $total = 0;
            foreach ($userValue as $value) {
                $value = Arr::get($advancePoints, $value, 0);
                if (!is_numeric($value)) {
                    continue;
                }
                $total += $value;
            }
            return $total;
        } else {
            return Arr::get($settings, 'points');
        }
    }
    
    private static function getScoreType($form)
    {
        $scoreType = '';
        $scoreInput = self::getScoreInput($form);
        if ($scoreInput) {
            $scoreType = Arr::get($scoreInput, 'raw.settings.result_type');
        }
        return $scoreType;
    }
    public static function getScoreInput($form){
        $scoreInput = \FluentForm\App\Modules\Form\FormFieldsParser::getInputsByElementTypes($form,['quiz_score'],['raw']);
        if ($scoreInput) {
           return array_shift($scoreInput);
        }
        return false;
    }
    
    public function randomizeCheckableInputs()
    {
        add_filter('fluentform/rendering_field_data_input_checkbox', function ($data) {
            $options = $data['settings']['advanced_options'];
            shuffle($options);
            $data['settings']['advanced_options'] = $options;
        
            return $data;
        }, 10, 1);
    
        add_filter('fluentform/rendering_field_data_input_radio', function ($data) {
            $options = $data['settings']['advanced_options'];
            shuffle($options);
            $data['settings']['advanced_options'] = $options;
        
            return $data;
        }, 10, 1);
    }
    
}