PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
← All changes | inc/class-lp-widget.php +453 -453 4.3.94.4.8 View file →
@@ -1,453 +1,453 @@
1 -<?php
2 -/**
3 - * Widget class
4 - *
5 - * @package Learnpress/Abstracts
6 - * @author ThimPress <nhamdv>
7 - */
8 -
9 -defined( 'ABSPATH' ) || exit;
10 -
11 -/**
12 - * LP_Widget
13 - *
14 - * @version 4.0.0
15 - * @extends WP_Widget
16 - */
17 -class LP_Widget extends WP_Widget {
18 -
19 - /**
20 - * CSS class.
21 - *
22 - * @var string
23 - */
24 - public $widget_cssclass;
25 -
26 - /**
27 - * Widget description.
28 - *
29 - * @var string
30 - */
31 - public $widget_description;
32 -
33 - /**
34 - * Widget ID.
35 - *
36 - * @var string
37 - */
38 - public $widget_id;
39 -
40 - /**
41 - * Widget name.
42 - *
43 - * @var string
44 - */
45 - public $widget_name;
46 -
47 - /**
48 - * Enable rest_api for LearnPress.
49 - *
50 - * @var string
51 - */
52 - public $widget_in_rest = true;
53 -
54 - /**
55 - * New param add to rest api need for data.
56 - *
57 - * @var array
58 - */
59 - public $widget_data_attr = array();
60 -
61 - /**
62 - * Settings.
63 - *
64 - * @var array
65 - */
66 - public $settings;
67 -
68 - /**
69 - * Constructor.
70 - */
71 - public function __construct() {
72 - $widget_ops = array(
73 - 'classname' => $this->widget_cssclass,
74 - 'description' => $this->widget_description,
75 - 'customize_selective_refresh' => true,
76 - );
77 -
78 - parent::__construct( $this->widget_id, $this->widget_name, $widget_ops );
79 - }
80 -
81 - /**
82 - * Get this widgets title.
83 - */
84 - protected function get_instance_title( $instance ) {
85 - if ( isset( $instance['title'] ) ) {
86 - return $instance['title'];
87 - }
88 -
89 - if ( isset( $this->settings, $this->settings['title'], $this->settings['title']['std'] ) ) {
90 - return $this->settings['title']['std'];
91 - }
92 -
93 - return '';
94 - }
95 -
96 - /**
97 - * Output the html at the start of a widget.
98 - *
99 - * @param array $args Arguments.
100 - * @param array $instance Instance.
101 - */
102 - public function widget_start( $args, $instance ) {
103 - echo wp_kses_post( $args['before_widget'] );
104 -
105 - $title = apply_filters( 'widget_title', $this->get_instance_title( $instance ), $instance, $this->id_base );
106 -
107 - if ( $title ) {
108 - echo wp_kses_post( $args['before_title'] . $title . $args['after_title'] );
109 - }
110 - }
111 -
112 - /**
113 - * Output the html at the end of a widget.
114 - *
115 - * @param array $args Arguments.
116 - */
117 - public function widget_end( $args ) {
118 - echo wp_kses_post( $args['after_widget'] );
119 - }
120 -
121 - /**
122 - * Output Widgets HTML.
123 - *
124 - * @param [type] $args
125 - * @param [type] $instance
126 - *
127 - * @return void
128 - */
129 - public function widget( $args, $instance ) {
130 - wp_enqueue_script( 'lp-widgets' );
131 - if ( $this->id_base === 'learnpress_widget_course_filter' ) {
132 - wp_enqueue_script( 'lp-course-filter' );
133 - }
134 -
135 - do_action( 'learn-press/widget/before', $this, $args, $instance );
136 -
137 - if ( empty( $instance['show_in_rest'] ) ) {
138 - $this->widget_in_rest = false;
139 - }
140 -
141 - $data = array_merge(
142 - $this->widget_data_attr,
143 - array(
144 - 'widget' => $this->widget_id,
145 - 'instance' => wp_json_encode( $instance ),
146 - )
147 - );
148 -
149 - echo $this->lp_widget_content( $data, $args, $instance );
150 - }
151 -
152 - /**
153 - * Show widget content.
154 - *
155 - * @param array $data Data attribute HTML for Rest API js.
156 - * @param [type] $args Default Widget Args
157 - * @param [type] $instance Default Widget Instance
158 - *
159 - * @return string HTML
160 - */
161 - public function lp_widget_content( $data, $args, $instance ) {
162 - ob_start();
163 -
164 - $this->widget_start( $args, $instance );
165 -
166 - if ( ! is_admin() && $this->widget_in_rest ) {
167 - ?>
168 - <div class="learnpress-widget-wrapper learnpress-widget-wrapper__restapi"
169 - data-widget="<?php echo htmlentities( wp_json_encode( $data ) ); ?>">
170 - <?php lp_skeleton_animation_html( 5 ); ?>
171 - <div class="lp-widget-loading-change"></div>
172 - </div>
173 - <?php
174 - } else { // Use for Preview in Widget Editor since WordPress 5.8
175 - $content = $this->lp_rest_api_content( $instance, array() );
176 -
177 - echo '<div class="learnpress-widget-wrapper" data-widget="' . htmlentities( wp_json_encode( $data ) ) . '">';
178 - echo '<div class="lp-widget-loading-change"></div>';
179 -
180 - if ( is_wp_error( $content ) ) {
181 - echo $content->get_error_message();
182 - } else {
183 - echo $content;
184 - }
185 -
186 - echo '</div>';
187 - }
188 -
189 - $this->widget_end( $args );
190 -
191 - return ob_get_clean();
192 - }
193 -
194 - /**
195 - * Send content for API
196 - *
197 - * @param array $instance Widget Instance
198 - * @param array $params RestAPI param need for content.
199 - *
200 - * @return string || WP_Error
201 - */
202 - public function lp_rest_api_content( $instance, $params ) {
203 - return 'No content for Rest API';
204 - }
205 -
206 - /**
207 - * Updates a particular instance of a widget.
208 - */
209 - public function update( $new_instance, $old_instance ) {
210 -
211 - $instance = $old_instance;
212 -
213 - if ( empty( $this->settings ) ) {
214 - return $instance;
215 - }
216 -
217 - foreach ( $this->settings as $key => $setting ) {
218 - if ( ! isset( $setting['type'] ) ) {
219 - continue;
220 - }
221 -
222 - switch ( $setting['type'] ) {
223 - case 'number':
224 - $instance[ $key ] = absint( $new_instance[ $key ] ?? '' );
225 -
226 - if ( isset( $setting['min'] ) && '' !== $setting['min'] ) {
227 - $instance[ $key ] = max( $instance[ $key ], $setting['min'] );
228 - }
229 -
230 - if ( isset( $setting['max'] ) && '' !== $setting['max'] ) {
231 - $instance[ $key ] = min( $instance[ $key ], $setting['max'] );
232 - }
233 - break;
234 - case 'textarea':
235 - $instance[ $key ] = wp_kses( trim( wp_unslash( $new_instance[ $key ] ) ), wp_kses_allowed_html( 'post' ) );
236 - break;
237 - case 'checkbox':
238 - $instance[ $key ] = empty( $new_instance[ $key ] ) ? 0 : 1;
239 - break;
240 - case 'sortable-checkbox':
241 - $instance[ $key ] = empty( $new_instance[ $key ] ) ? [] : map_deep( $new_instance[ $key ], 'sanitize_text_field' );
242 - break;
243 - default:
244 - $instance[ $key ] = isset( $new_instance[ $key ] ) ? sanitize_text_field( $new_instance[ $key ] ) : ( $setting['std'] ?? '' );
245 - break;
246 - }
247 -
248 - /**
249 - * Sanitize the value of a setting.
250 - */
251 - $instance[ $key ] = apply_filters( 'learnpress_widget_settings_sanitize_option', $instance[ $key ], $new_instance, $key, $setting );
252 - }
253 -
254 - return $instance;
255 - }
256 -
257 - /**
258 - * Outputs the settings update form.
259 - */
260 - public function form( $instance ) {
261 - if ( empty( $this->settings ) ) {
262 - echo '<p>' . esc_html__( 'There are no options for this widget.', 'learnpress' ) . '</p>';
263 -
264 - return;
265 - }
266 -
267 - foreach ( $this->settings as $key => $setting ) {
268 - $class = $setting['class'] ?? '';
269 - $value = $instance[ $key ] ?? $setting['std'] ?? '';
270 -
271 - switch ( $setting['type'] ) {
272 - case 'text':
273 - ?>
274 - <p>
275 - <label
276 - for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
277 - <?php
278 - // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
279 - ?>
280 - <input class="widefat <?php echo esc_attr( $class ); ?>"
281 - id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
282 - name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" type="text"
283 - value="<?php echo esc_attr( $value ); ?>"/>
284 - </p>
285 - <?php
286 - break;
287 - case 'hidden':
288 - ?>
289 - <p>
290 - <input
291 - class="fields-sort"
292 - id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
293 - name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" type="hidden"
294 - value="<?php echo esc_attr( $value ); ?>"/>
295 - </p>
296 - <?php
297 - break;
298 - case 'number':
299 - ?>
300 - <p>
301 - <label
302 - for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
303 - <input class="widefat <?php echo esc_attr( $class ); ?>"
304 - id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
305 - name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" type="number"
306 - step="<?php echo isset( $setting['step'] ) ? esc_attr( $setting['step'] ) : '1'; ?>"
307 - min="<?php echo isset( $setting['min'] ) ? esc_attr( $setting['min'] ) : ''; ?>"
308 - max="<?php echo isset( $setting['max'] ) ? esc_attr( $setting['max'] ) : ''; ?>"
309 - value="<?php echo esc_attr( $value ); ?>"/>
310 - </p>
311 - <?php
312 - break;
313 - case 'select':
314 - ?>
315 - <p>
316 - <label
317 - for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
318 - <select class="widefat <?php echo esc_attr( $class ); ?>"
319 - id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
320 - name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>">
321 - <?php foreach ( $setting['options'] as $option_key => $option_value ) : ?>
322 - <option
323 - value="<?php echo esc_attr( $option_key ); ?>" <?php selected( $option_key, $value ); ?>><?php echo esc_html( $option_value ); ?></option>
324 - <?php endforeach; ?>
325 - </select>
326 - </p>
327 - <?php
328 - break;
329 - case 'textarea':
330 - ?>
331 - <p>
332 - <label
333 - for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
334 - <textarea class="widefat <?php echo esc_attr( $class ); ?>"
335 - id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
336 - name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" cols="20"
337 - rows="3"><?php echo esc_textarea( $value ); ?></textarea>
338 - <?php if ( isset( $setting['desc'] ) ) : ?>
339 - <small><?php echo esc_html( $setting['desc'] ); ?></small>
340 - <?php endif; ?>
341 - </p>
342 - <?php
343 - break;
344 - case 'checkbox':
345 - ?>
346 - <p>
347 - <input class="checkbox <?php echo esc_attr( $class ); ?>"
348 - id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
349 - name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" type="checkbox"
350 - value="1" <?php checked( $value, 1 ); ?> />
351 - <label
352 - for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
353 - </p>
354 - <?php
355 - break;
356 - case 'sortable-checkbox':
357 - $values_default = $setting['std'] ?? array();
358 - $order = $instance['fields_order'] ?? '';
359 - ?>
360 - <div class="sortable-wrapper">
361 - <label><?php echo wp_kses_post( $setting['label'] ); ?></label>
362 - <div>
363 - <?php
364 - $options = $setting['options'] ?? array();
365 - if ( ! empty( $order ) ) {
366 - $order = explode( ',', $order );
367 - $new_options = array();
368 - foreach ( $order as $order_val ) {
369 - if ( isset( $options[ $order_val ] ) ) {
370 - $new_options[ $order_val ] = $options[ $order_val ];
371 - }
372 - }
373 -
374 - $options = $new_options;
375 - }
376 - ?>
377 - <div class="sortable <?php echo esc_attr( $class ); ?>">
378 - <?php
379 - foreach ( $options as $option_name => $option ) {
380 - $checked_value = ! empty( $instance ) ? ( $instance[ $key ] ?? array() ) : $values_default;
381 - ?>
382 - <div class="sortable__item">
383 - <i class="dashicons dashicons-menu drag"></i>
384 - <input class="checkbox"
385 - id="<?php echo esc_attr( $this->get_field_id( $option['id'] ) ); ?>"
386 - name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>[]"
387 - type="checkbox"
388 - value="<?php echo esc_attr( $option_name ); ?>"
389 - <?php checked( in_array( $option_name, $checked_value ) ); ?>
390 - />
391 - <label
392 - for="<?php echo esc_attr( $this->get_field_id( $option['id'] ) ); ?>"><?php echo wp_kses_post( $option['label'] ); ?></label>
393 - </div>
394 - <?php
395 - }
396 - ?>
397 - </div>
398 - </div>
399 - </div>
400 - <script>
401 - jQuery(document).trigger('learnpress/widgets/select');
402 - </script>
403 - <?php
404 - break;
405 -
406 - case 'autocomplete':
407 - $data_struct = [
408 - 'urlApi' => get_rest_url( null, 'lp/v1/admin/tools/search-course' ),
409 - 'dataType' => 'courses',
410 - 'keyGetValue' => [
411 - 'value' => 'ID',
412 - 'text' => '{{post_title}} (#{{ID}})',
413 - 'key_render' => [
414 - 'post_title' => 'post_title',
415 - 'ID' => 'ID',
416 - ],
417 - ],
418 - 'setting' => [
419 - 'placeholder' => esc_html__( 'Choose Course', 'learnpress' ),
420 - ],
421 - ];
422 - ?>
423 - <p>
424 - <label for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>">
425 - <?php echo wp_kses_post( $setting['label'] ); ?>
426 - </label>
427 - <select class="lp-tom-select"
428 - id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
429 - name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>"
430 - data-rest-url="<?php echo get_rest_url(); ?>"
431 - data-post-type="<?php echo esc_attr( $setting['post_type'] ?? LP_COURSE_CPT ); ?>"
432 - data-saved = "<?php echo esc_attr( $value ?? '' ); ?>"
433 - data-struct = "<?php echo htmlentities2( json_encode( $data_struct ) ); ?>"
434 - style="width: 300px;">
435 - <?php if ( ! empty( $value ) ) : ?>
436 - <option value="<?php echo esc_attr( $value ); ?>"
437 - selected="selected"><?php echo esc_html( get_the_title( $value ) ); ?></option>
438 - <?php endif; ?>
439 - <script>
440 - jQuery(document).trigger('learnpress/widgets/select');
441 - </script>
442 - </select>
443 - </p>
444 - <?php
445 - break;
446 -
447 - default:
448 - do_action( 'learnpress_widget_field_' . $setting['type'], $key, $value, $setting, $instance );
449 - break;
450 - }
451 - }
452 - }
453 -}
1 +<?php
2 +/**
3 + * Widget class
4 + *
5 + * @package Learnpress/Abstracts
6 + * @author ThimPress <nhamdv>
7 + */
8 +
9 +defined( 'ABSPATH' ) || exit;
10 +
11 +/**
12 + * LP_Widget
13 + *
14 + * @version 4.0.0
15 + * @extends WP_Widget
16 + */
17 +class LP_Widget extends WP_Widget {
18 +
19 + /**
20 + * CSS class.
21 + *
22 + * @var string
23 + */
24 + public $widget_cssclass;
25 +
26 + /**
27 + * Widget description.
28 + *
29 + * @var string
30 + */
31 + public $widget_description;
32 +
33 + /**
34 + * Widget ID.
35 + *
36 + * @var string
37 + */
38 + public $widget_id;
39 +
40 + /**
41 + * Widget name.
42 + *
43 + * @var string
44 + */
45 + public $widget_name;
46 +
47 + /**
48 + * Enable rest_api for LearnPress.
49 + *
50 + * @var string
51 + */
52 + public $widget_in_rest = true;
53 +
54 + /**
55 + * New param add to rest api need for data.
56 + *
57 + * @var array
58 + */
59 + public $widget_data_attr = array();
60 +
61 + /**
62 + * Settings.
63 + *
64 + * @var array
65 + */
66 + public $settings;
67 +
68 + /**
69 + * Constructor.
70 + */
71 + public function __construct() {
72 + $widget_ops = array(
73 + 'classname' => $this->widget_cssclass,
74 + 'description' => $this->widget_description,
75 + 'customize_selective_refresh' => true,
76 + );
77 +
78 + parent::__construct( $this->widget_id, $this->widget_name, $widget_ops );
79 + }
80 +
81 + /**
82 + * Get this widgets title.
83 + */
84 + protected function get_instance_title( $instance ) {
85 + if ( isset( $instance['title'] ) ) {
86 + return $instance['title'];
87 + }
88 +
89 + if ( isset( $this->settings, $this->settings['title'], $this->settings['title']['std'] ) ) {
90 + return $this->settings['title']['std'];
91 + }
92 +
93 + return '';
94 + }
95 +
96 + /**
97 + * Output the html at the start of a widget.
98 + *
99 + * @param array $args Arguments.
100 + * @param array $instance Instance.
101 + */
102 + public function widget_start( $args, $instance ) {
103 + echo wp_kses_post( $args['before_widget'] );
104 +
105 + $title = apply_filters( 'widget_title', $this->get_instance_title( $instance ), $instance, $this->id_base );
106 +
107 + if ( $title ) {
108 + echo wp_kses_post( $args['before_title'] . $title . $args['after_title'] );
109 + }
110 + }
111 +
112 + /**
113 + * Output the html at the end of a widget.
114 + *
115 + * @param array $args Arguments.
116 + */
117 + public function widget_end( $args ) {
118 + echo wp_kses_post( $args['after_widget'] );
119 + }
120 +
121 + /**
122 + * Output Widgets HTML.
123 + *
124 + * @param [type] $args
125 + * @param [type] $instance
126 + *
127 + * @return void
128 + */
129 + public function widget( $args, $instance ) {
130 + wp_enqueue_script( 'lp-widgets' );
131 + if ( $this->id_base === 'learnpress_widget_course_filter' ) {
132 + wp_enqueue_script( 'lp-course-filter' );
133 + }
134 +
135 + do_action( 'learn-press/widget/before', $this, $args, $instance );
136 +
137 + if ( empty( $instance['show_in_rest'] ) ) {
138 + $this->widget_in_rest = false;
139 + }
140 +
141 + $data = array_merge(
142 + $this->widget_data_attr,
143 + array(
144 + 'widget' => $this->widget_id,
145 + 'instance' => wp_json_encode( $instance ),
146 + )
147 + );
148 +
149 + echo $this->lp_widget_content( $data, $args, $instance );
150 + }
151 +
152 + /**
153 + * Show widget content.
154 + *
155 + * @param array $data Data attribute HTML for Rest API js.
156 + * @param [type] $args Default Widget Args
157 + * @param [type] $instance Default Widget Instance
158 + *
159 + * @return string HTML
160 + */
161 + public function lp_widget_content( $data, $args, $instance ) {
162 + ob_start();
163 +
164 + $this->widget_start( $args, $instance );
165 +
166 + if ( ! is_admin() && $this->widget_in_rest ) {
167 + ?>
168 + <div class="learnpress-widget-wrapper learnpress-widget-wrapper__restapi"
169 + data-widget="<?php echo htmlentities( wp_json_encode( $data ) ); ?>">
170 + <?php lp_skeleton_animation_html( 5 ); ?>
171 + <div class="lp-widget-loading-change"></div>
172 + </div>
173 + <?php
174 + } else { // Use for Preview in Widget Editor since WordPress 5.8
175 + $content = $this->lp_rest_api_content( $instance, array() );
176 +
177 + echo '<div class="learnpress-widget-wrapper" data-widget="' . htmlentities( wp_json_encode( $data ) ) . '">';
178 + echo '<div class="lp-widget-loading-change"></div>';
179 +
180 + if ( is_wp_error( $content ) ) {
181 + echo $content->get_error_message();
182 + } else {
183 + echo $content;
184 + }
185 +
186 + echo '</div>';
187 + }
188 +
189 + $this->widget_end( $args );
190 +
191 + return ob_get_clean();
192 + }
193 +
194 + /**
195 + * Send content for API
196 + *
197 + * @param array $instance Widget Instance
198 + * @param array $params RestAPI param need for content.
199 + *
200 + * @return string || WP_Error
201 + */
202 + public function lp_rest_api_content( $instance, $params ) {
203 + return 'No content for Rest API';
204 + }
205 +
206 + /**
207 + * Updates a particular instance of a widget.
208 + */
209 + public function update( $new_instance, $old_instance ) {
210 +
211 + $instance = $old_instance;
212 +
213 + if ( empty( $this->settings ) ) {
214 + return $instance;
215 + }
216 +
217 + foreach ( $this->settings as $key => $setting ) {
218 + if ( ! isset( $setting['type'] ) ) {
219 + continue;
220 + }
221 +
222 + switch ( $setting['type'] ) {
223 + case 'number':
224 + $instance[ $key ] = absint( $new_instance[ $key ] ?? '' );
225 +
226 + if ( isset( $setting['min'] ) && '' !== $setting['min'] ) {
227 + $instance[ $key ] = max( $instance[ $key ], $setting['min'] );
228 + }
229 +
230 + if ( isset( $setting['max'] ) && '' !== $setting['max'] ) {
231 + $instance[ $key ] = min( $instance[ $key ], $setting['max'] );
232 + }
233 + break;
234 + case 'textarea':
235 + $instance[ $key ] = wp_kses( trim( wp_unslash( $new_instance[ $key ] ) ), wp_kses_allowed_html( 'post' ) );
236 + break;
237 + case 'checkbox':
238 + $instance[ $key ] = empty( $new_instance[ $key ] ) ? 0 : 1;
239 + break;
240 + case 'sortable-checkbox':
241 + $instance[ $key ] = empty( $new_instance[ $key ] ) ? [] : map_deep( $new_instance[ $key ], 'sanitize_text_field' );
242 + break;
243 + default:
244 + $instance[ $key ] = isset( $new_instance[ $key ] ) ? sanitize_text_field( $new_instance[ $key ] ) : ( $setting['std'] ?? '' );
245 + break;
246 + }
247 +
248 + /**
249 + * Sanitize the value of a setting.
250 + */
251 + $instance[ $key ] = apply_filters( 'learnpress_widget_settings_sanitize_option', $instance[ $key ], $new_instance, $key, $setting );
252 + }
253 +
254 + return $instance;
255 + }
256 +
257 + /**
258 + * Outputs the settings update form.
259 + */
260 + public function form( $instance ) {
261 + if ( empty( $this->settings ) ) {
262 + echo '<p>' . esc_html__( 'There are no options for this widget.', 'learnpress' ) . '</p>';
263 +
264 + return;
265 + }
266 +
267 + foreach ( $this->settings as $key => $setting ) {
268 + $class = $setting['class'] ?? '';
269 + $value = $instance[ $key ] ?? $setting['std'] ?? '';
270 +
271 + switch ( $setting['type'] ) {
272 + case 'text':
273 + ?>
274 + <p>
275 + <label
276 + for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
277 + <?php
278 + // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
279 + ?>
280 + <input class="widefat <?php echo esc_attr( $class ); ?>"
281 + id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
282 + name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" type="text"
283 + value="<?php echo esc_attr( $value ); ?>"/>
284 + </p>
285 + <?php
286 + break;
287 + case 'hidden':
288 + ?>
289 + <p>
290 + <input
291 + class="fields-sort"
292 + id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
293 + name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" type="hidden"
294 + value="<?php echo esc_attr( $value ); ?>"/>
295 + </p>
296 + <?php
297 + break;
298 + case 'number':
299 + ?>
300 + <p>
301 + <label
302 + for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
303 + <input class="widefat <?php echo esc_attr( $class ); ?>"
304 + id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
305 + name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" type="number"
306 + step="<?php echo isset( $setting['step'] ) ? esc_attr( $setting['step'] ) : '1'; ?>"
307 + min="<?php echo isset( $setting['min'] ) ? esc_attr( $setting['min'] ) : ''; ?>"
308 + max="<?php echo isset( $setting['max'] ) ? esc_attr( $setting['max'] ) : ''; ?>"
309 + value="<?php echo esc_attr( $value ); ?>"/>
310 + </p>
311 + <?php
312 + break;
313 + case 'select':
314 + ?>
315 + <p>
316 + <label
317 + for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
318 + <select class="widefat <?php echo esc_attr( $class ); ?>"
319 + id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
320 + name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>">
321 + <?php foreach ( $setting['options'] as $option_key => $option_value ) : ?>
322 + <option
323 + value="<?php echo esc_attr( $option_key ); ?>" <?php selected( $option_key, $value ); ?>><?php echo esc_html( $option_value ); ?></option>
324 + <?php endforeach; ?>
325 + </select>
326 + </p>
327 + <?php
328 + break;
329 + case 'textarea':
330 + ?>
331 + <p>
332 + <label
333 + for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
334 + <textarea class="widefat <?php echo esc_attr( $class ); ?>"
335 + id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
336 + name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" cols="20"
337 + rows="3"><?php echo esc_textarea( $value ); ?></textarea>
338 + <?php if ( isset( $setting['desc'] ) ) : ?>
339 + <small><?php echo esc_html( $setting['desc'] ); ?></small>
340 + <?php endif; ?>
341 + </p>
342 + <?php
343 + break;
344 + case 'checkbox':
345 + ?>
346 + <p>
347 + <input class="checkbox <?php echo esc_attr( $class ); ?>"
348 + id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
349 + name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" type="checkbox"
350 + value="1" <?php checked( $value, 1 ); ?> />
351 + <label
352 + for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
353 + </p>
354 + <?php
355 + break;
356 + case 'sortable-checkbox':
357 + $values_default = $setting['std'] ?? array();
358 + $order = $instance['fields_order'] ?? '';
359 + ?>
360 + <div class="sortable-wrapper">
361 + <label><?php echo wp_kses_post( $setting['label'] ); ?></label>
362 + <div>
363 + <?php
364 + $options = $setting['options'] ?? array();
365 + if ( ! empty( $order ) ) {
366 + $order = explode( ',', $order );
367 + $new_options = array();
368 + foreach ( $order as $order_val ) {
369 + if ( isset( $options[ $order_val ] ) ) {
370 + $new_options[ $order_val ] = $options[ $order_val ];
371 + }
372 + }
373 +
374 + $options = $new_options;
375 + }
376 + ?>
377 + <div class="sortable <?php echo esc_attr( $class ); ?>">
378 + <?php
379 + foreach ( $options as $option_name => $option ) {
380 + $checked_value = ! empty( $instance ) ? ( $instance[ $key ] ?? array() ) : $values_default;
381 + ?>
382 + <div class="sortable__item">
383 + <i class="dashicons dashicons-menu drag"></i>
384 + <input class="checkbox"
385 + id="<?php echo esc_attr( $this->get_field_id( $option['id'] ) ); ?>"
386 + name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>[]"
387 + type="checkbox"
388 + value="<?php echo esc_attr( $option_name ); ?>"
389 + <?php checked( in_array( $option_name, $checked_value ) ); ?>
390 + />
391 + <label
392 + for="<?php echo esc_attr( $this->get_field_id( $option['id'] ) ); ?>"><?php echo wp_kses_post( $option['label'] ); ?></label>
393 + </div>
394 + <?php
395 + }
396 + ?>
397 + </div>
398 + </div>
399 + </div>
400 + <script>
401 + jQuery(document).trigger('learnpress/widgets/select');
402 + </script>
403 + <?php
404 + break;
405 +
406 + case 'autocomplete':
407 + $data_struct = [
408 + 'urlApi' => get_rest_url( null, 'lp/v1/admin/tools/search-course' ),
409 + 'dataType' => 'courses',
410 + 'keyGetValue' => [
411 + 'value' => 'ID',
412 + 'text' => '{{post_title}} (#{{ID}})',
413 + 'key_render' => [
414 + 'post_title' => 'post_title',
415 + 'ID' => 'ID',
416 + ],
417 + ],
418 + 'setting' => [
419 + 'placeholder' => esc_html__( 'Choose Course', 'learnpress' ),
420 + ],
421 + ];
422 + ?>
423 + <p>
424 + <label for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>">
425 + <?php echo wp_kses_post( $setting['label'] ); ?>
426 + </label>
427 + <select class="lp-tom-select"
428 + id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"
429 + name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>"
430 + data-rest-url="<?php echo get_rest_url(); ?>"
431 + data-post-type="<?php echo esc_attr( $setting['post_type'] ?? LP_COURSE_CPT ); ?>"
432 + data-saved = "<?php echo esc_attr( $value ?? '' ); ?>"
433 + data-struct = "<?php echo htmlentities2( json_encode( $data_struct ) ); ?>"
434 + style="width: 300px;">
435 + <?php if ( ! empty( $value ) ) : ?>
436 + <option value="<?php echo esc_attr( $value ); ?>"
437 + selected="selected"><?php echo esc_html( get_the_title( $value ) ); ?></option>
438 + <?php endif; ?>
439 + <script>
440 + jQuery(document).trigger('learnpress/widgets/select');
441 + </script>
442 + </select>
443 + </p>
444 + <?php
445 + break;
446 +
447 + default:
448 + do_action( 'learnpress_widget_field_' . $setting['type'], $key, $value, $setting, $instance );
449 + break;
450 + }
451 + }
452 + }
453 +}