PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.4
Tutor LMS – eLearning and online course solution v4.0.4
4.0.4 4.0.3 4.0.2 4.0.1 4.0.0 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / components / StarRatingInput.php
tutor / components Last commit date
Constants 1 month ago Accordion.php 2 weeks ago Alert.php 2 weeks ago AttachmentCard.php 2 weeks ago Avatar.php 2 weeks ago Badge.php 2 weeks ago BaseComponent.php 1 month ago Button.php 2 weeks ago ConfirmationModal.php 2 weeks ago CourseFilter.php 2 weeks ago DateFilter.php 2 weeks ago DropdownFilter.php 2 weeks ago EmptyState.php 2 weeks ago FileUploader.php 2 weeks ago InputField.php 2 weeks ago Modal.php 2 weeks ago Nav.php 2 weeks ago Pagination.php 2 weeks ago Popover.php 2 weeks ago PreviewTrigger.php 2 weeks ago Progress.php 2 weeks ago SearchFilter.php 2 weeks ago Sorting.php 2 weeks ago StarRating.php 2 weeks ago StarRatingInput.php 2 weeks ago StatusSelect.php 2 weeks ago SvgIcon.php 2 weeks ago Table.php 2 weeks ago Tabs.php 2 weeks ago Tooltip.php 2 weeks ago WPEditor.php 2 weeks ago
StarRatingInput.php
294 lines
1 <?php
2 /**
3 * StarRatingInput Component Class.
4 *
5 * Renders an interactive star rating input using Alpine.js.
6 *
7 * @package Tutor\Components
8 * @author Themeum
9 * @link https://themeum.com
10 * @since 4.0.0
11 */
12
13 namespace Tutor\Components;
14
15 defined( 'ABSPATH' ) || exit;
16
17 use TUTOR\Icon;
18 use Tutor\Components\Constants\Size;
19
20 /**
21 * Class StarRatingInput
22 *
23 * Example Usage:
24 * ```php
25 * // Basic star input (no initial rating)
26 * StarRatingInput::make()
27 * ->field_name( 'rating' )
28 * ->render();
29 *
30 * // With a pre-selected rating
31 * StarRatingInput::make()
32 * ->field_name( 'rating' )
33 * ->current_rating( 4.0 )
34 * ->render();
35 *
36 * // With Alpine.js onChange callback
37 * StarRatingInput::make()
38 * ->field_name( 'rating' )
39 * ->current_rating( 3.0 )
40 * ->on_change( 'handleRatingChange' )
41 * ->render();
42 *
43 * // With Alpine.js form register binding (for validation)
44 * StarRatingInput::make()
45 * ->field_name( 'rating' )
46 * ->register( "register('rating', { required: 'Please rate this course' })" )
47 * ->render();
48 *
49 * // Emoji view (renders emoji buttons instead of/alongside stars)
50 * StarRatingInput::make()
51 * ->field_name( 'course_rating' )
52 * ->view( 'emoji' )
53 * ->render();
54 *
55 * // Retrieve HTML without echoing
56 * $html = StarRatingInput::make()->field_name( 'rating' )->current_rating( 5.0 )->get();
57 * ```
58 *
59 * @since 4.0.0
60 */
61 class StarRatingInput extends BaseComponent {
62
63 /**
64 * Form field name
65 *
66 * @since 4.0.0
67 *
68 * @var string
69 */
70 protected $field_name = 'rating';
71
72 /**
73 * Current rating value
74 *
75 * @since 4.0.0
76 *
77 * @var float
78 */
79 protected $current_rating = 0;
80
81 /**
82 * On change callback function name or js snippet
83 *
84 * @since 4.0.0
85 *
86 * @var string
87 */
88 protected $on_change = '';
89
90 /**
91 * Alpine register function binding
92 *
93 * @since 4.0.0
94 *
95 * @var string
96 */
97 protected $register = '';
98
99 /**
100 * Icon size
101 *
102 * @var int
103 */
104 protected $icon_size = Size::SIZE_20;
105
106 /**
107 * View type (star|emoji)
108 *
109 * @var string
110 */
111 protected $view = 'star';
112
113 /**
114 * Set field name
115 *
116 * @since 4.0.0
117 *
118 * @param string $name field name.
119 *
120 * @return self
121 */
122 public function field_name( string $name ): self {
123 $this->field_name = $name;
124 return $this;
125 }
126
127 /**
128 * Set current rating
129 *
130 * @since 4.0.0
131 *
132 * @param float $rating rating.
133 *
134 * @return self
135 */
136 public function current_rating( float $rating ): self {
137 $this->current_rating = $rating;
138 return $this;
139 }
140
141 /**
142 * Set on change callback
143 *
144 * @since 4.0.0
145 *
146 * @param string $callback callback.
147 *
148 * @return self
149 */
150 public function on_change( string $callback ): self {
151 $this->on_change = $callback;
152 return $this;
153 }
154
155 /**
156 * Set register binding
157 *
158 * @since 4.0.0
159 *
160 * @param string $register register.
161 *
162 * @return self
163 */
164 public function register( string $register ): self {
165 $this->register = $register;
166 return $this;
167 }
168
169 /**
170 * Set view type
171 *
172 * @since 4.0.0
173 *
174 * @param string $view view type.
175 *
176 * @return self
177 */
178 public function view( string $view ): self {
179 $this->view = $view;
180 return $this;
181 }
182
183 /**
184 * Get component content
185 *
186 * @since 4.0.0
187 *
188 * @return string
189 */
190 public function get(): string {
191 $current_rating = $this->current_rating;
192
193 $is_emoji = 'emoji' === $this->view;
194 $emoji_images = array(
195 1 => 'poor.png',
196 2 => 'fair.png',
197 3 => 'okay.png',
198 4 => 'good.png',
199 5 => 'amazing.png',
200 );
201 $emoji_url = tutor()->url . 'assets/images/emojis/';
202
203 $labels = array(
204 1 => __( 'Poor', 'tutor' ),
205 2 => __( 'Fair', 'tutor' ),
206 3 => __( 'Okay', 'tutor' ),
207 4 => __( 'Good', 'tutor' ),
208 5 => __( 'Amazing', 'tutor' ),
209 );
210
211 $star_fill = SvgIcon::make()->name( Icon::STAR_FILL )->size( $is_emoji ? Size::SIZE_32 : Size::SIZE_24 )->ignore_kids()->get();
212 $star_half = SvgIcon::make()->name( Icon::STAR_HALF )->size( $is_emoji ? Size::SIZE_32 : Size::SIZE_24 )->ignore_kids()->get();
213 $star = SvgIcon::make()->name( Icon::STAR_LINE )->size( $is_emoji ? Size::SIZE_32 : Size::SIZE_24 )->ignore_kids()->get();
214
215 ob_start();
216 ?>
217 <div
218 class="tutor-star-rating-container <?php echo $is_emoji ? 'is-emoji-view' : ''; ?>"
219 x-data="tutorStarRatingInput({
220 initialRating: <?php echo esc_attr( $current_rating ); ?>,
221 fieldName: '<?php echo esc_attr( $this->field_name ); ?>'
222 })"
223 >
224 <input
225 type="hidden"
226 name="<?php echo esc_attr( $this->field_name ); ?>"
227 x-bind="register('<?php echo esc_attr( $this->field_name ); ?>' )"
228 >
229
230 <?php if ( $is_emoji ) : ?>
231 <div class="tutor-flex tutor-items-center tutor-gap-4 tutor-justify-center">
232 <?php
233 $rating_classes = array(
234 1 => 'is-poor',
235 2 => 'is-fair',
236 3 => 'is-okay',
237 4 => 'is-good',
238 5 => 'is-amazing',
239 );
240 ?>
241 <?php foreach ( $emoji_images as $i => $image ) : ?>
242 <button
243 type="button"
244 class="tutor-star-rating-emoji-btn <?php echo esc_attr( $rating_classes[ $i ] ); ?>"
245 :class="{'is-active': rating == <?php echo (int) $i; ?>}"
246 @click="setRating(<?php echo esc_attr( $i ); ?>, (rating) => setValue('<?php echo esc_attr( $this->field_name ); ?>', rating))"
247 >
248 <img src="<?php echo esc_url( $emoji_url . $image ); ?>" alt="<?php echo esc_attr( $labels[ $i ] ); ?>" class="tutor-rating-emoji-img" width="32" height="32">
249 <span class="tutor-rating-label">
250 <?php echo esc_html( $labels[ $i ] ); ?>
251 </span>
252 </button>
253 <?php endforeach; ?>
254 </div>
255 <?php endif; ?>
256
257 <div class="tutor-flex tutor-items-center tutor-gap-2 tutor-justify-center" @mouseleave="hoverRating = 0">
258 <?php for ( $i = 1; $i <= 5; $i++ ) : ?>
259 <button
260 type="button"
261 class="tutor-star-rating-icon-btn tutor-btn tutor-p-none tutor-min-h-0 tutor-bg-transparent"
262 @click="setRating(<?php echo esc_attr( $i ); ?>, (rating) => setValue('<?php echo esc_attr( $this->field_name ); ?>', rating))"
263 @mouseenter="hoverRating = <?php echo esc_attr( $i ); ?>"
264 >
265 <template x-if="effectiveRating >= <?php echo esc_attr( $i ); ?>">
266 <span class="tutor-icon-exception4 tutor-flex">
267 <?php echo $star_fill; // phpcs:ignore ?>
268 </span>
269 </template>
270 <template x-if="effectiveRating > <?php echo esc_attr( $i - 1 ); ?> && effectiveRating < <?php echo esc_attr( $i ); ?>">
271 <span class="tutor-icon-exception4 tutor-flex">
272 <?php echo $star_half; // phpcs:ignore ?>
273 </span>
274 </template>
275 <template x-if="effectiveRating <= <?php echo esc_attr( $i - 1 ); ?>">
276 <span class="tutor-icon-exception4 tutor-flex">
277 <?php echo $star; // phpcs:ignore ?>
278 </span>
279 </template>
280 </button>
281 <?php endfor; ?>
282 </div>
283
284 <?php if ( ! $is_emoji ) : ?>
285 <span class="tutor-small tutor-font-medium" x-text="feedback"></span>
286 <?php endif; ?>
287 </div>
288 <?php
289
290 $this->component_string = ob_get_clean();
291 return $this->component_string;
292 }
293 }
294