| @@ -2,58 +2,114 @@ | ||
| 2 | 2 | |
| 3 | 3 | namespace FluentForm\App\Services\FormBuilder\Components; |
| 4 | 4 | |
| 5 | 5 | use FluentForm\App\Helpers\Helper; |
| 6 | +use FluentForm\App\Services\FormBuilder\RatingIcon; | |
| 6 | 7 | use FluentForm\Framework\Helpers\ArrayHelper; |
| 7 | 8 | |
| 8 | 9 | class Rating extends BaseComponent |
| 9 | 10 | { |
| 10 | - /** | |
| 11 | - * Compile and echo the html element | |
| 12 | - * @param array $data [element data] | |
| 13 | - * @param stdClass $form [Form Object] | |
| 14 | - * @return viod | |
| 15 | - */ | |
| 16 | - public function compile($data, $form) | |
| 17 | - { | |
| 11 | + /** | |
| 12 | + * Compile and echo the html element | |
| 13 | + * | |
| 14 | + * @param array $data [element data] | |
| 15 | + * @param \stdClass $form [Form Object] | |
| 16 | + * | |
| 17 | + * @return void | |
| 18 | + */ | |
| 19 | + public function compile($data, $form) | |
| 20 | + { | |
| 18 | 21 | $elementName = $data['element']; |
| 19 | - $data = apply_filters('fluenform_rendering_field_data_'.$elementName, $data, $form); | |
| 20 | 22 | |
| 23 | + $data = apply_filters_deprecated( | |
| 24 | + 'fluentform_rendering_field_data_' . $elementName, | |
| 25 | + [ | |
| 26 | + $data, | |
| 27 | + $form | |
| 28 | + ], | |
| 29 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 30 | + 'fluentform/rendering_field_data_' . $elementName, | |
| 31 | + 'Use fluentform/rendering_field_data_' . $elementName . ' instead of fluentform_rendering_field_data_' . $elementName | |
| 32 | + ); | |
| 33 | + | |
| 34 | + $data = apply_filters('fluentform/rendering_field_data_' . $elementName, $data, $form); | |
| 35 | + | |
| 21 | 36 | $data['attributes']['type'] = 'radio'; |
| 22 | 37 | |
| 23 | - $defaultValues = (array) $this->extractValueFromAttributes($data); | |
| 38 | + $defaultValues = (array) $this->extractValueFromAttributes($data); | |
| 24 | 39 | |
| 25 | - $elMarkup = "<div class='ff-el-ratings jss-ff-el-ratings'>"; | |
| 26 | - $ratingText = ""; | |
| 40 | + $iconSettings = RatingIcon::resolveSettings($data); | |
| 41 | + $iconSvg = RatingIcon::getResolvedIconSvg($data, [ | |
| 42 | + 'class' => 'ff-rating-icon-svg jss-ff-svg ff-svg', | |
| 43 | + ]); | |
| 44 | + $ratingStyles = sprintf( | |
| 45 | + '--ff-rating-inactive-color: %s; --ff-rating-active-color: %s;', | |
| 46 | + esc_attr($iconSettings['inactive_color']), | |
| 47 | + esc_attr($iconSettings['active_color']) | |
| 48 | + ); | |
| 27 | 49 | |
| 28 | - foreach ( $data['options'] as $value => $label ) { | |
| 29 | - $starred = ''; | |
| 30 | - if(in_array($value, $defaultValues)) { | |
| 31 | - $data['attributes']['checked'] = true; | |
| 32 | - $starred = 'active'; | |
| 33 | - } else { | |
| 34 | - $data['attributes']['checked'] = false; | |
| 35 | - } | |
| 50 | + $firstTabIndex = Helper::getNextTabIndex(); | |
| 51 | + $elMarkup = "<div class='ff-el-ratings jss-ff-el-ratings' role='radiogroup' style='" . $ratingStyles . "' data-rating-icon-source='" . esc_attr($iconSettings['icon_source']) . "' data-rating-icon-type='" . esc_attr($iconSettings['icon_type']) . "' data-base-tabindex='" . esc_attr($firstTabIndex ?: 0) . "'>"; | |
| 52 | + $ratingText = ''; | |
| 53 | + $selectedValues = array_filter(array_map('strval', $defaultValues), function ($value) { | |
| 54 | + return $value !== ''; | |
| 55 | + }); | |
| 56 | + $hasSelectedValue = !empty($selectedValues); | |
| 57 | + $optionIndex = 0; | |
| 36 | 58 | |
| 37 | - if($tabIndex = \FluentForm\App\Helpers\Helper::getNextTabIndex()) { | |
| 38 | - $data['attributes']['tabindex'] = $tabIndex; | |
| 59 | + foreach ((array) ArrayHelper::get($data, 'options', []) as $value => $label) { | |
| 60 | + $starred = ''; | |
| 61 | + $isSelected = in_array((string) $value, $selectedValues, true); | |
| 62 | + | |
| 63 | + if ($isSelected) { | |
| 64 | + $data['attributes']['checked'] = true; | |
| 65 | + $starred = 'active'; | |
| 66 | + } else { | |
| 67 | + $data['attributes']['checked'] = false; | |
| 39 | 68 | } |
| 40 | 69 | |
| 41 | - $atts = $this->buildAttributes($data['attributes']); | |
| 42 | - $id = $this->getUniqueid(str_replace(['[', ']'], ['', ''], $data['attributes']['name'])); | |
| 43 | - | |
| 44 | - $elMarkup .= "<label class='{$starred}'><input {$atts} id={$id} value='{$value}'>"; | |
| 45 | - $elMarkup .= '<?xml version="1.0" encoding="iso-8859-1"?><svg class="jss-ff-svg ff-svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 53.867 53.867" style="enable-background:new 0 0 53.867 53.867;" xml:space="preserve"><polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></svg>'; | |
| 46 | - $elMarkup .= '</label>'; | |
| 70 | + $data['attributes']['tabindex'] = -1; | |
| 71 | + $atts = $this->buildAttributes($data['attributes']); | |
| 72 | + $id = esc_attr($this->getUniqueId(str_replace(['[', ']'], ['', ''], $data['attributes']['name']))); | |
| 47 | 73 | |
| 48 | - if (ArrayHelper::get($data, 'settings.show_text') == 'yes') { | |
| 49 | - $displayDefaultText = in_array($value, $defaultValues) ? 'display: inline-block' : 'display: none'; | |
| 50 | - $ratingText .= "<span style='{$displayDefaultText}' class='ff-el-rating-text' data-id='{$id}'>{$label}</span>"; | |
| 51 | - } | |
| 52 | - }; | |
| 74 | + $ariaRequired = 'false'; | |
| 75 | + if (ArrayHelper::get($data, 'settings.validation_rules.required.value')) { | |
| 76 | + $ariaRequired = 'true'; | |
| 77 | + } | |
| 53 | 78 | |
| 54 | - $elMarkup .= "</div>".$ratingText; | |
| 79 | + $labelTabIndex = -1; | |
| 80 | + if ($isSelected || (!$hasSelectedValue && $optionIndex === 0)) { | |
| 81 | + $labelTabIndex = $firstTabIndex ?: 0; | |
| 82 | + } | |
| 55 | 83 | |
| 56 | - $html = $this->buildElementMarkup($elMarkup, $data, $form); | |
| 57 | - echo apply_filters('fluenform_rendering_field_html_'.$elementName, $html, $data, $form); | |
| 84 | + $checked = $isSelected ? 'true' : 'false'; | |
| 85 | + $elMarkup .= "<label for={$id} class='{$starred}' role='radio' aria-checked='{$checked}' aria-label='" . esc_attr(wp_strip_all_tags($label)) . "' tabindex='" . esc_attr($labelTabIndex) . "'><input {$atts} id={$id} aria-valuenow='" . esc_attr($value) . "' value='" . esc_attr($value) . "' aria-required={$ariaRequired} aria-invalid='false'>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $starred, $atts, $id are escaped before being passed in. | |
| 86 | + $elMarkup .= "<span class='ff-rating-icon' aria-hidden='true'>{$iconSvg}</span>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- SVG is sanitized before output. | |
| 87 | + $elMarkup .= '</label>'; | |
| 88 | + | |
| 89 | + if ('yes' == ArrayHelper::get($data, 'settings.show_text')) { | |
| 90 | + $displayDefaultText = $isSelected ? 'display: inline-block' : 'display: none'; | |
| 91 | + $ratingText .= "<span style='{$displayDefaultText}' class='ff-el-rating-text' data-id='{$id}'>" . fluentform_sanitize_html($label) . '</span>'; | |
| 92 | + } | |
| 93 | + | |
| 94 | + $optionIndex++; | |
| 95 | + }; | |
| 96 | + | |
| 97 | + $elMarkup .= '</div>' . $ratingText; | |
| 98 | + | |
| 99 | + $html = $this->buildElementMarkup($elMarkup, $data, $form); | |
| 100 | + | |
| 101 | + $html = apply_filters_deprecated( | |
| 102 | + 'fluentform_rendering_field_html_' . $elementName, | |
| 103 | + [ | |
| 104 | + $html, | |
| 105 | + $data, | |
| 106 | + $form | |
| 107 | + ], | |
| 108 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 109 | + 'fluentform/rendering_field_html_' . $elementName, | |
| 110 | + 'Use fluentform/rendering_field_html_' . $elementName . ' instead of fluentform_rendering_field_html_' . $elementName | |
| 111 | + ); | |
| 112 | + | |
| 113 | + $this->printContent('fluentform/rendering_field_html_' . $elementName, $html, $data, $form); | |
| 58 | 114 | } |
| 59 | 115 | } |