PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.3
Tutor LMS – eLearning and online course solution v4.0.3
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 / Progress.php
tutor / components Last commit date
Constants 3 weeks ago Accordion.php 1 week ago Alert.php 1 week ago AttachmentCard.php 1 week ago Avatar.php 1 week ago Badge.php 1 week ago BaseComponent.php 3 weeks ago Button.php 1 week ago ConfirmationModal.php 1 week ago CourseFilter.php 1 week ago DateFilter.php 1 week ago DropdownFilter.php 1 week ago EmptyState.php 1 week ago FileUploader.php 1 week ago InputField.php 1 week ago Modal.php 1 week ago Nav.php 1 week ago Pagination.php 1 week ago Popover.php 1 week ago PreviewTrigger.php 1 week ago Progress.php 1 week ago SearchFilter.php 1 week ago Sorting.php 1 week ago StarRating.php 1 week ago StarRatingInput.php 1 week ago StatusSelect.php 1 week ago SvgIcon.php 1 week ago Table.php 1 week ago Tabs.php 1 week ago Tooltip.php 1 week ago WPEditor.php 1 week ago
Progress.php
481 lines
1 <?php
2 /**
3 * Tutor Component: Progress
4 *
5 * Provides a fluent builder for rendering progress bars and progress circles
6 * with different states and animations.
7 *
8 * @package Tutor\Components
9 * @author Themeum
10 * @link https://themeum.com
11 * @since 4.0.0
12 */
13
14 namespace Tutor\Components;
15
16 defined( 'ABSPATH' ) || exit;
17
18 use Tutor\Components\Constants\Size;
19 use Tutor\Components\Constants\Variant;
20
21 /**
22 * Progress Component Class.
23 *
24 * Example usage:
25 * ```php
26 * // Basic animated progress bar (0–100)
27 * Progress::make()
28 * ->type( 'bar' )
29 * ->value( 75 )
30 * ->render();
31 *
32 * // Progress bar without animation
33 * Progress::make()
34 * ->type( 'bar' )
35 * ->value( 50 )
36 * ->animated( false )
37 * ->render();
38 *
39 * // Progress bar with a specific size
40 * Progress::make()
41 * ->type( 'bar' )
42 * ->value( 30 )
43 * ->size( Size::MEDIUM )
44 * ->render();
45 *
46 * // Progress bar with brand variant color
47 * Progress::make()
48 * ->type( 'bar' )
49 * ->value( 60 )
50 * ->variant( Variant::BRAND )
51 * ->render();
52 *
53 * // Progress circle (percentage arc)
54 * Progress::make()
55 * ->type( 'circle' )
56 * ->value( 75 )
57 * ->render();
58 *
59 * // Progress circle — complete state (shows checkmark)
60 * Progress::make()
61 * ->type( 'circle' )
62 * ->complete()
63 * ->render();
64 *
65 * // Progress circle — locked state
66 * Progress::make()
67 * ->type( 'circle' )
68 * ->locked()
69 * ->render();
70 *
71 * // Progress circle without label
72 * Progress::make()
73 * ->type( 'circle' )
74 * ->value( 40 )
75 * ->show_label( false )
76 * ->render();
77 *
78 * // Progress circle with custom label text
79 * Progress::make()
80 * ->type( 'circle' )
81 * ->value( 90 )
82 * ->label( '9/10 done' )
83 * ->render();
84 *
85 * // Progress circle with custom colors and animation duration
86 * Progress::make()
87 * ->type( 'circle' )
88 * ->value( 55 )
89 * ->stroke_color( '#e0e0e0' )
90 * ->progress_stroke_color( '#4CAF50' )
91 * ->duration( 1500 )
92 * ->render();
93 *
94 * // Retrieve HTML without echoing
95 * $html = Progress::make()->type( 'bar' )->value( 80 )->get();
96 * ```
97 *
98 * @since 4.0.0
99 */
100 class Progress extends BaseComponent {
101
102 /**
103 * Progress type (bar|circle).
104 *
105 * @since 4.0.0
106 * @var string
107 */
108 protected $type = 'bar';
109
110 /**
111 * Progress value (0-100).
112 *
113 * @since 4.0.0
114 * @var int
115 */
116 protected $value = 0;
117
118 /**
119 * Whether progress bar is animated.
120 *
121 * @since 4.0.0
122 * @var bool
123 */
124 protected $animated = true;
125
126 /**
127 * Progress circle state (progress|complete).
128 * Only applicable for circle type.
129 *
130 * @since 4.0.0
131 * @var string
132 */
133 protected $state = 'progress';
134
135 /**
136 * Progress size (x-small|small|medium|large).
137 *
138 * @since 4.0.0
139 * @var string
140 */
141 protected $size = Size::SMALL;
142
143 /**
144 * Progress variant style (brand|warning, etc).
145 *
146 * @since 4.0.0
147 *
148 * @see Variant constants
149 *
150 * @var string
151 */
152 protected $variant = '';
153
154 /**
155 * Background color.
156 *
157 * @since 4.0.0
158 * @var string
159 */
160 protected $background = 'none';
161
162 /**
163 * Stroke color (background circle).
164 *
165 * @since 4.0.0
166 * @var string
167 */
168 protected $stroke_color = 'var(--tutor-actions-gray-secondary)';
169
170 /**
171 * Progress stroke color (progress arc).
172 *
173 * @since 4.0.0
174 * @var string
175 */
176 protected $progress_stroke_color = 'var(--tutor-actions-brand-primary)';
177
178 /**
179 * Whether to show label.
180 *
181 * @since 4.0.0
182 * @var bool
183 */
184 protected $show_label = true;
185
186 /**
187 * Custom label text.
188 *
189 * @since 4.0.0
190 * @var string
191 */
192 protected $label = '';
193
194 /**
195 * Animation duration in milliseconds.
196 *
197 * @since 4.0.0
198 * @var int
199 */
200 protected $duration = 1000;
201
202 /**
203 * Set progress type.
204 *
205 * @since 4.0.0
206 *
207 * @param string $type Progress type (bar|circle).
208 * @return $this
209 */
210 public function type( $type ) {
211 $allowed = array( 'bar', 'circle' );
212 if ( in_array( $type, $allowed, true ) ) {
213 $this->type = $type;
214 }
215 return $this;
216 }
217
218 /**
219 * Set progress value (0-100).
220 *
221 * @since 4.0.0
222 *
223 * @param int $value Progress value.
224 * @return $this
225 */
226 public function value( $value ) {
227 $this->value = max( 0, min( 100, (int) $value ) );
228 return $this;
229 }
230
231 /**
232 * Enable animated progress bar.
233 *
234 * @since 4.0.0
235 *
236 * @param bool $animated Whether to animate the progress bar.
237 * @return $this
238 */
239 public function animated( $animated = true ) {
240 $this->animated = (bool) $animated;
241 return $this;
242 }
243
244 /**
245 * Set progress size.
246 *
247 * @since 4.0.0
248 *
249 * @param string $size Progress size (x-small|small|medium|large).
250 * @return $this
251 */
252 public function size( $size ) {
253 $allowed = array( Size::X_SMALL, Size::SMALL, Size::MEDIUM, Size::LARGE );
254 if ( in_array( $size, $allowed, true ) ) {
255 $this->size = $size;
256 }
257 return $this;
258 }
259
260 /**
261 * Set progress variant style.
262 *
263 * @since 4.0.0
264 *
265 * @param string $variant Progress variant (brand|warning, etc).
266 * @return $this
267 */
268 public function variant( $variant ) {
269 $this->variant = sanitize_html_class( $variant );
270 return $this;
271 }
272
273 /**
274 * Set progress state.
275 *
276 * @since 4.0.0
277 *
278 * @param string $state Progress state (progress|complete|locked).
279 * @return $this
280 */
281 public function state( $state ) {
282 $allowed = array( 'progress', 'complete', 'locked' );
283 if ( in_array( $state, $allowed, true ) ) {
284 $this->state = $state;
285 }
286 return $this;
287 }
288
289 /**
290 * Set progress as complete.
291 *
292 * @since 4.0.0
293 * @return $this
294 */
295 public function complete() {
296 return $this->state( 'complete' );
297 }
298
299 /**
300 * Set progress as locked.
301 *
302 * @since 4.0.0
303 * @return $this
304 */
305 public function locked() {
306 return $this->state( 'locked' );
307 }
308
309 /**
310 * Set background color.
311 *
312 * @since 4.0.0
313 *
314 * @param string $background Background color.
315 * @return $this
316 */
317 public function background( $background ) {
318 $this->background = $background;
319 return $this;
320 }
321
322 /**
323 * Set stroke color (background circle).
324 *
325 * @since 4.0.0
326 *
327 * @param string $stroke_color Stroke color.
328 * @return $this
329 */
330 public function stroke_color( $stroke_color ) {
331 $this->stroke_color = $stroke_color;
332 return $this;
333 }
334
335 /**
336 * Set progress stroke color (progress arc).
337 *
338 * @since 4.0.0
339 *
340 * @param string $progress_stroke_color Progress stroke color.
341 * @return $this
342 */
343 public function progress_stroke_color( $progress_stroke_color ) {
344 $this->progress_stroke_color = $progress_stroke_color;
345 return $this;
346 }
347
348 /**
349 * Set whether to show label.
350 *
351 * @since 4.0.0
352 *
353 * @param bool $show_label Whether to show label.
354 * @return $this
355 */
356 public function show_label( $show_label = true ) {
357 $this->show_label = (bool) $show_label;
358 return $this;
359 }
360
361 /**
362 * Set custom label text.
363 *
364 * @since 4.0.0
365 *
366 * @param string $label Custom label text.
367 * @return $this
368 */
369 public function label( $label ) {
370 $this->label = $label;
371 return $this;
372 }
373
374 /**
375 * Set animation duration.
376 *
377 * @since 4.0.0
378 *
379 * @param int $duration Animation duration in milliseconds.
380 * @return $this
381 */
382 public function duration( $duration ) {
383 $this->duration = (int) $duration;
384 return $this;
385 }
386
387 /**
388 * Render progress bar HTML.
389 *
390 * @since 4.0.0
391 *
392 * @return string HTML output.
393 */
394 protected function render_bar() {
395 $classes = 'tutor-progress-bar';
396
397 if ( ! empty( $this->variant ) ) {
398 $classes .= " tutor-progress-bar-{$this->variant}";
399 }
400
401 // Add animated attribute if enabled.
402 if ( $this->animated ) {
403 $this->attributes['data-tutor-animated'] = '';
404 }
405
406 // Merge classes.
407 $this->attributes['class'] = trim( "{$classes} " . ( $this->attributes['class'] ?? '' ) );
408
409 $attributes = $this->get_attributes_string();
410
411 $fixed_offset = $this->value - 10;
412 $proportional = (int) round( $this->value * 0.85 );
413 $animation_from = max( 0, min( $fixed_offset, $proportional ) );
414
415 return sprintf(
416 '<div %s><div class="tutor-progress-bar-fill" style="--tutor-progress-start: %d%%; --tutor-progress-width: %d%%;"></div></div>',
417 $attributes,
418 $animation_from,
419 $this->value
420 );
421 }
422
423 /**
424 * Render progress circle HTML.
425 *
426 * @since 4.0.0
427 *
428 * @return string HTML output.
429 */
430 protected function render_circle() {
431 // Build Alpine.js x-data attribute.
432 $alpine_data = array();
433
434 if ( 'progress' === $this->state ) {
435 $alpine_data['value'] = $this->value;
436 $alpine_data['type'] = 'progress';
437 } else {
438 $alpine_data['type'] = $this->state;
439 }
440
441 $alpine_data['size'] = $this->size;
442 $alpine_data['background'] = $this->background;
443 $alpine_data['strokeColor'] = $this->stroke_color;
444 $alpine_data['progressStrokeColor'] = $this->progress_stroke_color;
445 $alpine_data['showLabel'] = $this->show_label;
446 $alpine_data['label'] = $this->label;
447 $alpine_data['animated'] = $this->animated;
448 $alpine_data['duration'] = $this->duration;
449
450 // Convert to JSON for x-data.
451 $alpine_json = wp_json_encode( $alpine_data );
452
453 // Merge attributes.
454 $this->attributes['x-data'] = sprintf( 'tutorStatics(%s)', $alpine_json );
455
456 $attributes = $this->get_attributes_string();
457
458 return sprintf(
459 '<div %s><div x-html="render()"></div></div>',
460 $attributes
461 );
462 }
463
464 /**
465 * Get the final progress HTML.
466 *
467 * @since 4.0.0
468 *
469 * @return string HTML output.
470 */
471 public function get(): string {
472 if ( 'circle' === $this->type ) {
473 $this->component_string = $this->render_circle();
474 } else {
475 $this->component_string = $this->render_bar();
476 }
477
478 return $this->component_string;
479 }
480 }
481