PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.1.0
Tutor LMS – eLearning and online course solution v3.1.0
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 / classes / Options_V2.php
tutor / classes Last commit date
Addons.php 1 year ago Admin.php 1 year ago Ajax.php 1 year ago Announcements.php 1 year ago Assets.php 1 year ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Course.php 1 year ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 1 year ago Course_Settings_Tabs.php 1 year ago Course_Widget.php 3 years ago Custom_Validation.php 3 years ago Dashboard.php 1 year ago Earnings.php 1 year ago FormHandler.php 2 years ago Frontend.php 1 year ago Gutenberg.php 1 year ago Input.php 1 year ago Instructor.php 1 year ago Instructors_List.php 1 year ago Lesson.php 1 year ago Options_V2.php 1 year ago Permalink.php 2 years ago Post_types.php 2 years ago Private_Course_Access.php 1 year ago Q_And_A.php 2 years ago Question_Answers_List.php 3 years ago Quiz.php 1 year ago QuizBuilder.php 1 year ago Quiz_Attempts_List.php 1 year ago RestAPI.php 2 years ago Reviews.php 3 years ago Rewrite_Rules.php 2 years ago Shortcode.php 1 year ago Singleton.php 1 year ago Student.php 1 year ago Students_List.php 3 years ago Taxonomies.php 3 years ago Template.php 1 year ago Theme_Compatibility.php 3 years ago Tools.php 3 years ago Tools_V2.php 1 year ago Tutor.php 1 year ago TutorEDD.php 1 year ago Tutor_Base.php 2 years ago Tutor_Setup.php 1 year ago Upgrader.php 1 year ago User.php 1 year ago Utils.php 1 year ago Video_Stream.php 3 years ago WhatsNew.php 2 years ago Withdraw.php 1 year ago Withdraw_Requests_List.php 1 year ago WooCommerce.php 1 year ago
Options_V2.php
1917 lines
1 <?php
2 /**
3 * Settings options
4 *
5 * @package Tutor\Settings
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 2.0.0
9 */
10
11 namespace Tutor;
12
13 use Tutor\Ecommerce\CartController;
14 use Tutor\Ecommerce\CheckoutController;
15 use Tutor\Ecommerce\Ecommerce;
16 use Tutor\Ecommerce\OptionKeys;
17 use TUTOR\Input;
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit;
21 }
22
23 /**
24 * Contains all the settings options
25 *
26 * @since 2.0.0
27 */
28 class Options_V2 {
29
30 /**
31 * Undocumented variable
32 *
33 * @since 2.0.0
34 *
35 * @var array $options
36 */
37 private $options;
38
39 /**
40 * Settings fields
41 *
42 * @since 2.0.0
43 *
44 * @var mixed $setting_fields
45 */
46 private $setting_fields;
47
48 /**
49 * Register hooks
50 *
51 * @since 2.0.0
52 *
53 * @param boolean $register_hook should register hook or not.
54 *
55 * @return void
56 */
57 public function __construct( $register_hook = true ) {
58 if ( ! $register_hook ) {
59 return;
60 }
61
62 // Saving option.
63 add_action( 'tutor_option_save_before', array( $this, 'validate_options' ) );
64 add_action( 'wp_ajax_tutor_option_save', array( $this, 'tutor_option_save' ) );
65 add_action( 'wp_ajax_tutor_option_default_save', array( $this, 'tutor_option_default_save' ) );
66 add_action( 'wp_ajax_tutor_option_search', array( $this, 'tutor_option_search' ) );
67 add_action( 'wp_ajax_tutor_export_settings', array( $this, 'tutor_export_settings' ) );
68 add_action( 'wp_ajax_tutor_export_single_settings', array( $this, 'tutor_export_single_settings' ) );
69 add_action( 'wp_ajax_tutor_delete_single_settings', array( $this, 'tutor_delete_single_settings' ) );
70 add_action( 'wp_ajax_tutor_import_settings', array( $this, 'tutor_import_settings' ) );
71 add_action( 'wp_ajax_tutor_apply_settings', array( $this, 'tutor_apply_settings' ) );
72 add_action( 'wp_ajax_load_saved_data', array( $this, 'load_saved_data' ) );
73 add_action( 'wp_ajax_reset_settings_data', array( $this, 'reset_settings_data' ) );
74 add_action( 'tutor_option_monetize_by_changed', array( $this, 'handle_changed_monetization_option' ) );
75 }
76
77 /**
78 * Get settings value
79 *
80 * @since 2.0.0
81 *
82 * @param mixed $key option key.
83 * @param mixed $default default value.
84 *
85 * @return mixed
86 */
87 private function get( $key = null, $default = false ) {
88
89 if ( ! $this->options ) {
90 // Get if already not prepared.
91 $this->options = (array) maybe_unserialize( get_option( 'tutor_option' ) );
92 }
93
94 $option = $this->options;
95
96 if ( empty( $option ) || ! is_array( $option ) ) {
97 return $default;
98 }
99
100 if ( ! $key ) {
101 return $option;
102 }
103
104 if ( array_key_exists( $key, $option ) ) {
105 return apply_filters( $key, $option[ $key ] );
106 }
107
108 // Access array value via dot notation, such as option->get('value.subvalue').
109 if ( strpos( $key, '.' ) ) {
110 $option_key_array = explode( '.', $key );
111 $new_option = $option;
112 foreach ( $option_key_array as $dot_key ) {
113 if ( isset( $new_option[ $dot_key ] ) ) {
114 $new_option = $new_option[ $dot_key ];
115 } else {
116 return $default;
117 }
118 }
119
120 return apply_filters( $key, $new_option );
121 }
122
123 return $default;
124 }
125
126 /**
127 * Get only list of options.
128 *
129 * @since 3.0.0
130 *
131 * @param array $only only options.
132 *
133 * @return array
134 */
135 public static function get_only( $only = array() ) {
136 $settings = get_option( 'tutor_option', array() );
137 return array_intersect_key( $settings, array_flip( $only ) );
138 }
139
140 /**
141 * Prepare settings search item.
142 *
143 * @since 3.0.0
144 *
145 * @param array $section section item.
146 * @param array $block block item.
147 * @param array $field field item.
148 *
149 * @return array prepared searchable field item.
150 */
151 private function prepare_search_item( $section, $block, $field ) {
152 $field['section_label'] = isset( $section['label'] ) ? $section['label'] : '';
153 $field['section_slug'] = isset( $section['slug'] ) ? $section['slug'] : '';
154 $field['block_label'] = isset( $block['label'] ) ? $block['label'] : '';
155
156 return $field;
157 }
158
159 /**
160 * Function to get all fields for search tutor_option_search
161 *
162 * @since 2.0.0
163 *
164 * @return void send wp_json response
165 */
166 public function tutor_option_search() {
167 tutor_utils()->checking_nonce();
168
169 $data_array = array();
170 foreach ( $this->get_setting_fields() as $sections ) {
171 if ( is_array( $sections ) && ! empty( $sections ) ) {
172 foreach ( tutor_utils()->sanitize_recursively( $sections ) as $section ) {
173 foreach ( $section['blocks'] as $blocks ) {
174 if ( isset( $blocks['fields'] ) && ! empty( $blocks['fields'] ) ) {
175 foreach ( $blocks['fields'] as $fields ) {
176 $data_array['fields'][] = $this->prepare_search_item( $section, $blocks, $fields );
177 }
178 }
179 }
180
181 /**
182 * Submenu item search.
183 *
184 * @since 3.0.0
185 */
186 if ( isset( $section['submenu'] ) && is_array( $section['submenu'] ) ) {
187 foreach ( tutor_utils()->sanitize_recursively( $section['submenu'] ) as $submenu_section ) {
188 foreach ( $submenu_section['blocks'] as $block ) {
189 if ( isset( $block['fields'] ) && ! empty( $block['fields'] ) ) {
190 foreach ( $block['fields'] as $fields ) {
191 $data_array['fields'][] = $this->prepare_search_item( $submenu_section, $block, $fields );
192 }
193 }
194 }
195 }
196 }
197 }
198 }
199 }
200
201 wp_send_json_success( $data_array );
202 }
203
204 /**
205 * Export settings
206 *
207 * @since 2.0.0
208 *
209 * @return void send wp_json response
210 */
211 public function tutor_export_settings() {
212 tutor_utils()->checking_nonce();
213 // Check if user is privileged.
214 if ( ! current_user_can( 'administrator' ) ) {
215 wp_send_json_error( tutor_utils()->error_message() );
216 }
217
218 $tutor_option = get_option( 'tutor_option' );
219 wp_send_json_success( maybe_unserialize( $tutor_option ) );
220 }
221
222 /**
223 * Export single settings
224 *
225 * @since 2.0.0
226 *
227 * @return void send wp_json response
228 */
229 public function tutor_export_single_settings() {
230
231 tutor_utils()->checking_nonce();
232
233 // Check if user is privileged.
234 if ( ! current_user_can( 'administrator' ) ) {
235 wp_send_json_error( tutor_utils()->error_message() );
236 }
237
238 $tutor_settings_log = get_option( 'tutor_settings_log' );
239 $export_id = $this->get_request_data( 'export_id' );
240 wp_send_json_success( $tutor_settings_log[ $export_id ] );
241 }
242
243 /**
244 * Apply settings
245 *
246 * @since 2.0.0
247 *
248 * @return void send wp_json response
249 */
250 public function tutor_apply_settings() {
251
252 tutor_utils()->checking_nonce();
253
254 // Check if user is privileged.
255 if ( ! current_user_can( 'administrator' ) ) {
256 wp_send_json_error( tutor_utils()->error_message() );
257 }
258
259 $tutor_settings_log = get_option( 'tutor_settings_log' );
260 $apply_id = $this->get_request_data( 'apply_id' );
261
262 update_option( 'tutor_option', $tutor_settings_log[ $apply_id ]['dataset'] );
263
264 wp_send_json_success( $tutor_settings_log[ $apply_id ] );
265 }
266
267 /**
268 * Delete single setting
269 *
270 * @since 2.0.0
271 *
272 * @return void send wp_json response
273 */
274 public function tutor_delete_single_settings() {
275
276 tutor_utils()->checking_nonce();
277
278 // Check if user is privileged.
279 if ( ! current_user_can( 'administrator' ) ) {
280 wp_send_json_error( tutor_utils()->error_message() );
281 }
282
283 $tutor_settings_log = get_option( 'tutor_settings_log' );
284 $delete_id = $this->get_request_data( 'delete_id' );
285 unset( $tutor_settings_log[ $delete_id ] );
286 update_option( 'tutor_settings_log', $tutor_settings_log );
287
288 wp_send_json_success( $tutor_settings_log );
289 }
290
291 /**
292 * Get request data
293 *
294 * @since 2.0.0
295 *
296 * @param mixed $var option key.
297 *
298 * @return mixed
299 */
300 public function get_request_data( $var ) {
301 return isset( $_REQUEST[ $var ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $var ] ) ) : null;
302 }
303
304 /**
305 * Tutor default settings update options
306 * and send json response
307 *
308 * @since 2.0.0
309 *
310 * @return void send wp_json response
311 */
312 public function tutor_default_settings() {
313 $attr = $this->get_setting_fields();
314
315 foreach ( $attr as $sections ) {
316
317 foreach ( $sections as $section ) {
318 foreach ( $section['blocks'] as $blocks ) {
319 foreach ( $blocks['fields'] as $field ) {
320 if ( isset( $field['default'] ) ) {
321 $attr_default[ $field['key'] ] = $field['default'];
322 }
323 }
324 }
325 }
326 }
327
328 update_option( 'tutor_option', $attr_default );
329
330 wp_send_json_success( $attr_default );
331 }
332
333 /**
334 * Tutor settings log
335 *
336 * @since 2.0.0
337 *
338 * @return void send wp_json response
339 */
340 public function load_saved_data() {
341 tutor_utils()->checking_nonce();
342
343 // Check if user is privileged.
344 if ( ! current_user_can( 'administrator' ) ) {
345 wp_send_json_error( tutor_utils()->error_message() );
346 }
347
348 wp_send_json_success( get_option( 'tutor_settings_log' ) );
349 }
350
351 /**
352 * Reset settings
353 *
354 * @since 2.0.0
355 *
356 * @return void send wp_json response
357 */
358 public function reset_settings_data() {
359 tutor_utils()->checking_nonce();
360
361 // Check if user is privileged.
362 if ( ! current_user_can( 'administrator' ) ) {
363 wp_send_json_error( tutor_utils()->error_message() );
364 }
365
366 $reset_fields = $return_fields = $return_fields_group = array(); //phpcs:ignore
367 $reset_page = Input::post( 'reset_page' );
368 $setting_data = $this->get_setting_fields()['option_fields'][ $reset_page ]['blocks'];
369
370 foreach ( $setting_data as $blocks ) {
371
372 $block_fields = isset( $blocks['fields'] ) ? $blocks['fields'] : array();
373 foreach ( $block_fields as $fields ) {
374 $return_fields[] = $fields;
375 }
376
377 $block_fields_group = isset( $blocks['fields_group'] ) ? $blocks['fields_group'] : array();
378 foreach ( $block_fields_group as $fields ) {
379 $return_fields_group[] = $fields;
380 }
381 }
382
383 $reset_fields = array_merge( $return_fields, $return_fields_group );
384
385 wp_send_json_success( $reset_fields );
386 }
387
388 /**
389 * Import settings
390 *
391 * @since 2.0.0
392 *
393 * @return void
394 */
395 public function tutor_import_settings() {
396 tutor_utils()->checking_nonce();
397
398 // Check if user is privileged.
399 if ( ! current_user_can( 'administrator' ) ) {
400 wp_send_json_error( tutor_utils()->error_message() );
401 }
402
403 $request = $this->get_request_data( 'tutor_options' );
404 $request = json_decode( stripslashes( $request ), true );
405
406 $time = $this->get_request_data( 'time' );
407
408 $save_import_data['datetime'] = (int) $time;
409 $save_import_data['history_date'] = gmdate( 'j M, Y, g:i a', $time );
410 $save_import_data['datatype'] = 'imported';
411 $save_import_data['dataset'] = $request['data'];
412 $import_data[ 'tutor-imported-' . $time ] = $save_import_data;
413
414 $get_option_data = get_option( 'tutor_settings_log' );
415 if ( empty( $get_option_data ) ) {
416 $get_option_data = array();
417 }
418 if ( ! empty( $get_option_data ) && null !== $save_import_data['dataset'] ) {
419
420 $update_option = array_merge( $import_data, $get_option_data );
421
422 $update_option = tutor_utils()->sanitize_recursively( $update_option );
423
424 if ( ! empty( $update_option ) ) {
425 update_option( 'tutor_settings_log', $update_option );
426 }
427
428 if ( ! empty( $save_import_data ) ) {
429 update_option( 'tutor_option', $save_import_data['dataset'] );
430 }
431
432 $get_final_data = get_option( 'tutor_settings_log' );
433 } else {
434 if ( ! empty( $import_data ) ) {
435 update_option( 'tutor_settings_log', $import_data );
436 }
437
438 if ( ! empty( $save_import_data ) ) {
439 update_option( 'tutor_option', $save_import_data['dataset'] );
440 }
441 $get_final_data = get_option( 'tutor_settings_log' );
442 }
443
444 wp_send_json_success( $get_final_data );
445 }
446
447 /**
448 * Validate options before save.
449 *
450 * @since 2.8.0
451 *
452 * @param array $options option submitted to save.
453 *
454 * @return void
455 */
456 public function validate_options( $options ) {
457 $success = true;
458 $message = '';
459
460 $enable_sharing = $options['enable_revenue_sharing'] ?? 'off';
461 $admin_commission = (int) $options['earning_admin_commission'] ?? 0;
462 $instructor_commission = (int) $options['earning_instructor_commission'] ?? 0;
463
464 if ( 'on' === $enable_sharing && ( $admin_commission + $instructor_commission ) > 100 ) {
465 $success = false;
466 $message = __( 'Total share percentage must be 100% or less' );
467 }
468
469 if ( ! $success ) {
470 wp_send_json(
471 array(
472 'success' => $success,
473 'message' => $message,
474 )
475 );
476 }
477 }
478
479 /**
480 * Function tutor_option_save
481 *
482 * @since 2.0.0
483 *
484 * @return void send wp_json response
485 */
486 public function tutor_option_save() {
487 tutor_utils()->checking_nonce();
488
489 ! current_user_can( 'manage_options' ) ? wp_send_json_error() : 0;
490
491 $data_before = get_option( 'tutor_option' );
492 $option = (array) tutor_utils()->array_get( 'tutor_option', $_POST, array() ); //phpcs:ignore
493
494 do_action( 'tutor_option_save_before', $option );
495
496 $option = tutor_utils()->sanitize_recursively( $option );
497 $option = apply_filters( 'tutor_option_input', $option );
498
499 $time = strtotime( 'now' ) + ( 6 * 60 * 60 );
500 $save_import_data['datetime'] = $time;
501 $save_import_data['history_date'] = gmdate( 'j M, Y, g:i a', $time );
502 $save_import_data['datatype'] = 'saved';
503 $save_import_data['dataset'] = $option;
504 $import_data[ 'tutor-saved-' . $time ] = $save_import_data;
505 $update_option = array();
506 $get_option_data = get_option( 'tutor_settings_log', array() );
507
508 if ( ! empty( $get_option_data ) ) {
509 $update_option = array_merge( $import_data, $get_option_data );
510 } else {
511 $update_option = array_merge( $update_option, $import_data );
512 }
513
514 $update_option = array_slice( $update_option, 0, 10 );
515
516 update_option( 'tutor_settings_log', $update_option );
517 update_option( 'tutor_option', $option );
518 update_option( 'tutor_option_update_time', gmdate( 'j M, Y, g:i a', $time ) );
519
520 /**
521 * Hook for each tutor settings option change detection.
522 * Example: `tutor_option_{course_permalink_base}_changed`
523 *
524 * @since 2.6.0
525 */
526 $data_after = get_option( 'tutor_option' );
527 if ( $data_before !== $data_after && is_array( $data_after ) ) {
528 foreach ( $data_after as $key => $value ) {
529 $from = $data_before[ $key ] ?? null;
530 $to = $value;
531 if ( $from !== $to ) {
532 do_action( "tutor_option_{$key}_changed", $from, $to );
533 }
534 }
535 }
536
537 do_action( 'tutor_option_save_after' );
538
539 $data = apply_filters(
540 'tutor_option_saved_data',
541 array(
542 'success' => true,
543 'message' => __( 'Settings Saved', 'tutor' ),
544 'options' => $option,
545 )
546 );
547
548 wp_send_json( $data );
549 }
550
551 /**
552 * Handle monetization option value change.
553 *
554 * @since 3.0.0
555 *
556 * @return void
557 */
558 public function handle_changed_monetization_option() {
559 add_filter(
560 'tutor_option_saved_data',
561 function ( $res ) {
562 $res['reload_required'] = true;
563 return $res;
564 }
565 );
566 }
567
568 /**
569 * Function tutor_option_save
570 *
571 * @since 2.0.0
572 *
573 * @return void send wp_json response
574 */
575 public function tutor_option_default_save() {
576 tutor_utils()->checking_nonce();
577
578 ! current_user_can( 'manage_options' ) ? wp_send_json_error() : 0;
579 $attr = $this->get_setting_fields();
580 $tutor_default_option = get_option( 'tutor_default_option' );
581 $tutor_saved_option = get_option( 'tutor_option' );
582
583 foreach ( $attr as $sections ) {
584 foreach ( $sections as $section ) {
585 foreach ( $section['blocks'] as $blocks ) {
586 foreach ( $blocks['fields'] as $field ) {
587 if ( isset( $tutor_default_option[ $field['key'] ] ) ) {
588 $attr_default[ $field['key'] ] = $tutor_saved_option[ $field['key'] ];
589 } elseif ( null !== $field['key'] ) {
590 $attr_default[ $field['key'] ] = $field['default'];
591 }
592 }
593 }
594 }
595 }
596
597 update_option( 'tutor_option', $attr_default );
598
599 wp_send_json_success( $attr_default );
600 }
601
602 /**
603 * Load settings page
604 *
605 * @since 2.0.0
606 *
607 * @return void
608 */
609 public function load_settings_page() {
610 extract( $this->get_setting_fields() ); //phpcs:ignore
611
612 if ( ! $template_path ) {
613 $template_path = tutor()->path . '/views/options/settings.php';
614 }
615 include $template_path;
616 }
617
618 /**
619 * Get settings fields
620 *
621 * @since 2.0.0
622 *
623 * @return mixed
624 */
625 public function get_setting_fields() {
626 if ( $this->setting_fields ) {
627 // Return from property if already prepared.
628 return $this->setting_fields;
629 }
630
631 $pages = tutor_utils()->get_pages();
632
633 $site_url = site_url();
634 $course_base = $this->get( 'course_permalink_base', 'courses' );
635 $lesson_key = $this->get( 'lesson_permalink_base', 'lessons' );
636 $quiz_key = $this->get( 'quiz_permalink_base', 'quizzes' );
637
638 $course_url = $site_url . '/<code>' . $course_base . '</code>/sample-course';
639 $lesson_url = $site_url . '/' . $course_base . '/sample-course/<code>' . $lesson_key . '</code>/sample-lesson/';
640 $quiz_url = $site_url . '/' . $course_base . '/sample-course/<code>' . $quiz_key . '</code>/sample-quiz/';
641
642 $student_url = tutor_utils()->profile_url( 0, false );
643 $methods_array = array();
644 $withdrawl_methods = apply_filters( 'tutor_withdrawal_methods_all', array() );
645
646 foreach ( $withdrawl_methods as $key => $method ) {
647 $methods_array[ $key ] = $method['method_name'];
648 }
649
650 $page_args = array(
651 'post_type' => 'page',
652 'post_status' => 'publish',
653 'posts_per_page' => 1,
654 'title' => 'Courses',
655 );
656
657 $page_posts = get_posts( $page_args );
658 $course_archive_page_id = ( is_array( $page_posts ) && count( $page_posts ) ) ? $page_posts[0] : null;
659
660 $attr = array(
661 'general' => array(
662 'label' => __( 'General', 'tutor' ),
663 'slug' => 'general',
664 'desc' => __( 'General Settings', 'tutor' ),
665 'template' => 'basic',
666 'icon' => 'tutor-icon-earth',
667 'blocks' => array(
668 array(
669 'label' => false,
670 'block_type' => 'uniform',
671 'slug' => 'general-page',
672 'fields' => array(
673 array(
674 'key' => 'tutor_dashboard_page_id',
675 'type' => 'select',
676 'label' => __( 'Dashboard Page', 'tutor' ),
677 'default' => '0',
678 'options' => $pages,
679 'desc' => __( 'This page will be used for student and instructor dashboard', 'tutor' ),
680 'searchable' => true,
681 ),
682 ),
683 ),
684 array(
685 'label' => false,
686 'block_type' => 'uniform',
687 'slug' => 'general-page',
688 'fields' => array(
689 array(
690 'key' => 'tutor_toc_page_id',
691 'type' => 'select',
692 'label' => __( 'Terms and Conditions Page', 'tutor' ),
693 'default' => '0',
694 'options' => $pages,
695 'desc' => __( 'This page will be used as the Terms and Conditions page', 'tutor' ),
696 'searchable' => true,
697 ),
698 array(
699 'key' => OptionKeys::PRIVACY_POLICY,
700 'type' => 'select',
701 'label' => __( 'Privacy Policy', 'tutor' ),
702 'default' => 0,
703 'options' => $pages,
704 'desc' => __( 'Choose the page for privacy policy.', 'tutor' ),
705 'searchable' => true,
706 ),
707 ),
708 ),
709 array(
710 'label' => __( 'Others', 'tutor' ),
711 'slug' => 'others',
712 'block_type' => 'isolate',
713 'fields' => array(
714 array(
715 'key' => 'enable_course_marketplace',
716 'type' => 'toggle_switch',
717 'label' => __( 'Enable Marketplace', 'tutor' ),
718 'label_title' => '',
719 'default' => 'off',
720 'desc' => __( 'Allow multiple instructors to upload their courses.', 'tutor' ),
721 ),
722 array(
723 'key' => 'pagination_per_page',
724 'type' => 'number',
725 'number_type' => 'integer',
726 'label' => __( 'Pagination', 'tutor' ),
727 'default' => '20',
728 'desc' => __( 'Set the number of rows to be displayed per page', 'tutor' ),
729 ),
730 ),
731 ),
732 array(
733 'label' => __( 'Instructor', 'tutor' ),
734 'slug' => 'instructor',
735 'block_type' => 'uniform',
736 'fields' => array(
737 array(
738 'key' => 'instructor_can_publish_course',
739 'type' => 'toggle_switch',
740 'label' => __( 'Allow Instructors to Publish Courses', 'tutor' ),
741 'label_title' => '',
742 'default' => 'off',
743 'desc' => __( 'Enable instructors to publish the course directly. If disabled, admins will be able to review course content before publishing.', 'tutor' ),
744 ),
745 array(
746 'key' => 'instructor_can_delete_course',
747 'type' => 'toggle_switch',
748 'label' => __( 'Allow Instructors to Trash Courses', 'tutor' ),
749 'label_title' => '',
750 'default' => 'on',
751 'desc' => __( 'Enable this setting to allow instructors to delete courses.', 'tutor' ),
752 ),
753 array(
754 'key' => 'enable_become_instructor_btn',
755 'type' => 'toggle_switch',
756 'label' => __( 'Become an Instructor Button', 'tutor' ),
757 'label_title' => '',
758 'default' => 'off',
759 'desc' => __( 'Enable the option to display this button on the student dashboard.', 'tutor' ),
760 ),
761 ),
762 ),
763 ),
764 ),
765 'course' => array(
766 'label' => __( 'Course', 'tutor' ),
767 'slug' => 'course',
768 'desc' => __( 'Course Settings', 'tutor' ),
769 'template' => 'basic',
770 'icon' => 'tutor-icon-book-open',
771 'blocks' => array(
772 'block_course' => array(
773 'label' => '',
774 'slug' => 'course',
775 'block_type' => 'uniform',
776 'fields' => array(
777 array(
778 'key' => 'student_must_login_to_view_course',
779 'type' => 'toggle_switch',
780 'label' => __( 'Course Visibility', 'tutor' ),
781 'label_title' => '',
782 'default' => 'off',
783 'desc' => __( 'Students must be logged in to view course', 'tutor' ),
784 ),
785 array(
786 'key' => 'course_content_access_for_ia',
787 'type' => 'toggle_switch',
788 'label' => __( 'Course Content Access', 'tutor' ),
789 'default' => 'off',
790 'label_title' => '',
791 'desc' => __( 'Allow instructors and admins to view the course content without enrolling', 'tutor' ),
792 ),
793 array(
794 'key' => 'course_content_summary',
795 'type' => 'toggle_switch',
796 'label' => __( 'Content Summary', 'tutor' ),
797 'default' => 'on',
798 'desc' => __( 'Enabling this feature will show a course content summary on the Course Details page.', 'tutor' ),
799 ),
800 array(
801 'key' => 'wc_automatic_order_complete_redirect_to_courses',
802 'type' => 'toggle_switch',
803 'label' => __( 'Auto Redirect to Courses', 'tutor' ),
804 'default' => 'off',
805 'label_title' => '',
806 'desc' => __( 'When a user\'s WooCommerce order is auto-completed, they will be redirected to enrolled courses', 'tutor' ),
807 ),
808 array(
809 'key' => 'enable_spotlight_mode',
810 'type' => 'toggle_switch',
811 'label' => __( 'Spotlight Mode', 'tutor' ),
812 'default' => 'off',
813 'label_title' => '',
814 'desc' => __( 'This will hide the header and the footer and enable spotlight (full screen) mode when students view lessons.', 'tutor' ),
815 ),
816 array(
817 'key' => 'auto_course_complete_on_all_lesson_completion',
818 'type' => 'toggle_switch',
819 'label' => __( 'Auto Complete Course on All Lesson Completion', 'tutor' ),
820 'default' => 'off',
821 'label_title' => '',
822 'desc' => __( 'If enabled, an Enrolled Course will be automatically completed if all its Lessons, Quizzes, and Assignments are already completed by the Student', 'tutor' ),
823 ),
824 array(
825 'key' => 'course_completion_process',
826 'type' => 'radio_vertical',
827 'label' => __( 'Course Completion Process', 'tutor' ),
828 'default' => 'flexible',
829 'select_options' => false,
830 'options' => array(
831 'flexible' => array(
832 'label' => __( 'Flexible', 'tutor' ),
833 'desc' => __( 'Students can complete courses anytime in the Flexible mode', 'tutor' ),
834 ),
835 'strict' => array(
836 'label' => __( 'Strict', 'tutor' ),
837 'desc' => __( 'Students have to complete, pass all the lessons and quizzes (if any) to mark a course as complete.', 'tutor' ),
838 ),
839 ),
840 'desc' => __( 'Choose when a user can click on the <strong>“Complete Course”</strong> button', 'tutor' ),
841 ),
842 array(
843 'key' => 'course_retake_feature',
844 'type' => 'toggle_switch',
845 'label' => __( 'Course Retake', 'tutor' ),
846 'default' => 'off',
847 'label_title' => '',
848 'desc' => __( 'Enabling this feature will allow students to reset course progress and start over.', 'tutor' ),
849 ),
850 array(
851 'key' => 'enable_course_review_moderation',
852 'type' => 'toggle_switch',
853 'label' => __( "Publish Course Review on Admin's Approval", 'tutor' ),
854 'default' => 'off',
855 'label_title' => '',
856 'desc' => __( 'Enable to publish/re-publish Course Review after the approval of Site Admin', 'tutor' ),
857 ),
858 ),
859 ),
860 'block_lesson' => array(
861 'label' => __( 'Lesson', 'tutor' ),
862 'slug' => 'lesson',
863 'block_type' => 'uniform',
864 'fields' => array(
865 array(
866 'key' => 'enable_lesson_classic_editor',
867 'type' => 'toggle_switch',
868 'label' => __( 'WP Editor for Lesson', 'tutor' ),
869 'label_title' => '',
870 'default' => 'off',
871 'desc' => __( 'Enable classic editor to edit lesson.', 'tutor' ),
872 ),
873 array(
874 'key' => 'autoload_next_course_content',
875 'type' => 'toggle_switch',
876 'label' => __( 'Automatically Load Next Course Content.', 'tutor' ),
877 'label_title' => '',
878 'default' => 'off',
879 'desc' => __( 'Enable this feature to automatically load the next course content after the current one is finished.', 'tutor' ),
880 ),
881 array(
882 'key' => 'enable_comment_for_lesson',
883 'type' => 'toggle_switch',
884 'label' => __( 'Enable Lesson Comment', 'tutor' ),
885 'label_title' => '',
886 'default' => 'off',
887 'desc' => __( 'Enable this feature to allow students to post comments on lessons.', 'tutor' ),
888 ),
889 ),
890 ),
891 'block_quiz' => array(
892 'label' => __( 'Quiz', 'tutor' ),
893 'slug' => 'quiz',
894 'block_type' => 'uniform',
895 'fields' => array(
896 array(
897 'key' => 'quiz_when_time_expires',
898 'type' => 'radio_vertical',
899 'label' => __( 'When time expires', 'tutor' ),
900 'default' => 'auto_abandon',
901 'select_options' => false,
902 'options' => array(
903 'auto_submit' => array(
904 'label' => __( 'Auto Submit', 'tutor' ),
905 'desc' => __( 'The current quiz answers are submitted automatically.', 'tutor' ),
906 ),
907 // 'grace_period' => __( 'The current quiz answers are submitted by students.', 'tutor' )
908 'auto_abandon' => array(
909 'label' => __( 'Auto Abandon', 'tutor' ),
910 'desc' => __( 'Attempts must be submitted before time expires, otherwise they will not be counted', 'tutor' ),
911 ),
912 ),
913 'desc' => __( 'Choose which action to follow when the quiz time expires.', 'tutor' ),
914 ),
915 array(
916 'key' => 'quiz_answer_display_time',
917 'type' => 'number',
918 'label' => __( 'Correct Answer Display Time (When Reveal Mode is enabled)', 'tutor' ),
919 'default' => '2',
920 'desc' => __( 'Put the answer display time in seconds', 'tutor' ),
921 ),
922 array(
923 'key' => 'quiz_attempts_allowed',
924 'type' => 'number',
925 'number_type' => 'integer',
926 'label' => __( 'Default Quiz Attempt limit (When Retry Mode is enabled)', 'tutor' ),
927 'default' => '10',
928 'desc' => __( 'The highest number of attempts allowed for students to participate a quiz. 0 means unlimited. This will work as the default Quiz Attempt limit in case of Quiz Retry Mode.', 'tutor' ),
929 ),
930 array(
931 'key' => 'quiz_previous_button_enabled',
932 'type' => 'toggle_switch',
933 'label' => __( 'Show Quiz Previous Button', 'tutor' ),
934 'default' => 'on',
935 'desc' => __( 'Choose whether to show or hide the previous button for each question.', 'tutor' ),
936 ),
937 array(
938 'key' => 'quiz_grade_method',
939 'type' => 'radio_horizontal_full',
940 'label' => __( 'Final Grade Calculation', 'tutor' ),
941 'desc' => __( 'When multiple attempts are allowed, select which method should be used to calculate a student\'s final grade for the quiz.', 'tutor' ),
942 'default' => 'highest_grade',
943 'options' => array(
944 'highest_grade' => __( 'Highest Grade', 'tutor' ),
945 'average_grade' => __( 'Average Grade', 'tutor' ),
946 'first_attempt' => __( 'First Attempt', 'tutor' ),
947 'last_attempt' => __( 'Last Attempt', 'tutor' ),
948 ),
949 ),
950 ),
951 ),
952 array(
953 'label' => __( 'Video', 'tutor' ),
954 'slug' => 'video',
955 'block_type' => 'uniform',
956 'fields' => array(
957 array(
958 'key' => 'supported_video_sources',
959 'type' => 'checkbox_vertical',
960 'default' => array( 'youtube', 'vimeo' ),
961 'label' => __( 'Preferred Video Source', 'tutor' ),
962 'label_title' => __( 'Preferred Video Source', 'tutor' ),
963 'options' => tutor_utils()->get_video_sources( true ),
964 'desc' => __( 'Select the video hosting platform(s) you want to enable.', 'tutor' ),
965 ),
966 ),
967 ),
968 ),
969 ),
970 'monetization' => array(
971 'label' => __( 'Monetization', 'tutor' ),
972 'slug' => 'monetization',
973 'desc' => __( 'Monetization Settings', 'tutor' ),
974 'template' => 'basic',
975 'icon' => 'tutor-icon-badge-discount',
976 'blocks' => array(
977 'block_options' => array(
978 'label' => __( 'Options', 'tutor' ),
979 'slug' => 'options',
980 'block_type' => 'uniform',
981 'fields' => array(
982 array(
983 'key' => 'monetize_by',
984 'type' => 'select',
985 'label' => __( 'Select eCommerce Engine', 'tutor' ),
986 'select_options' => false,
987 'options' => apply_filters(
988 'tutor_monetization_options',
989 array(
990 'free' => __( 'Disable Monetization', 'tutor' ),
991 )
992 ),
993 'default' => 'free',
994 'desc' => __( 'Select a monetization option to generate revenue by selling courses.', 'tutor' ),
995 ),
996 ),
997 ),
998 'block_woocommerce' => array(
999 'label' => __( 'Woocommerce', 'tutor' ),
1000 'slug' => 'woocommerce',
1001 'block_type' => 'uniform',
1002 'fields' => array(
1003 array(
1004 'key' => 'tutor_woocommerce_order_auto_complete',
1005 'type' => 'toggle_switch',
1006 'label' => __( 'Automatically Complete WooCommerce Orders', 'tutor' ),
1007 'label_title' => '',
1008 'default' => 'off',
1009 'desc' => __( 'If enabled, in the case of Courses, WooCommerce Orders will get the "Completed" status .', 'tutor' ),
1010 ),
1011 ),
1012 ),
1013 'block_revenue_sharing' => array(
1014 'label' => __( 'Revenue Sharing', 'tutor' ),
1015 'slug' => 'revenue_sharing',
1016 'block_type' => 'uniform',
1017 'fields' => array(
1018 array(
1019 'key' => 'enable_revenue_sharing',
1020 'type' => 'toggle_switch',
1021 'label' => __( 'Enable Revenue Sharing', 'tutor' ),
1022 'label_title' => '',
1023 'default' => 'off',
1024 'desc' => __( 'Allow revenue generated from selling courses to be shared with course creators.', 'tutor' ),
1025 'toggle_fields' => 'sharing_percentage',
1026 'toggle_blocks' => 'fees,withdraw',
1027 ),
1028 array(
1029 'key' => 'sharing_percentage',
1030 'type' => 'double_input',
1031 'label' => __( 'Sharing Percentage', 'tutor' ),
1032 'label_title' => '',
1033 'default' => '',
1034 'fields' => array(
1035 'earning_instructor_commission' => array(
1036 'id' => 'revenue-instructor',
1037 'type' => 'ratio',
1038 'title' => __( 'Instructor Takes', 'tutor' ),
1039 'default' => 20,
1040 ),
1041 'earning_admin_commission' => array(
1042 'id' => 'revenue-admin',
1043 'type' => 'ratio',
1044 'title' => __( 'Admin Takes', 'tutor' ),
1045 'default' => 80,
1046 ),
1047 ),
1048 'desc' => __( 'Set how the sales revenue will be shared among admins and instructors.', 'tutor' ),
1049 ),
1050 ),
1051 ),
1052 'block_fees' => array(
1053 'label' => __( 'Fees', 'tutor' ),
1054 'slug' => 'fees',
1055 'block_type' => 'uniform',
1056 'fields' => array(
1057 array(
1058 'key' => 'enable_fees_deducting',
1059 'type' => 'toggle_switch',
1060 'label' => __( 'Deduct Fees', 'tutor' ),
1061 'label_title' => '',
1062 'default' => 'off',
1063 'desc' => __( 'Fees are charged from the entire sales amount. The remaining amount will be divided among admin and instructors.', 'tutor' ),
1064 'toggle_fields' => 'fees_name,fee_amount_type',
1065 ),
1066 array(
1067 'key' => 'fees_name',
1068 'type' => 'textarea',
1069 'label' => __( 'Fee Description', 'tutor' ),
1070 'placeholder' => __( 'Fee Description', 'tutor' ),
1071 'desc' => __( 'Set a description for the fee that you are deducting. Make sure to give a reasonable explanation to maintain transparency with your site’s instructors.', 'tutor' ),
1072 'maxlength' => 200,
1073 'rows' => 5,
1074 'default' => 'Maintenance Fees',
1075 ),
1076 array(
1077 'key' => 'fee_amount_type',
1078 'type' => 'group_fields',
1079 'label' => __( 'Fee Amount & Type', 'tutor' ),
1080 'desc' => __( 'Select the fee type and add fee amount/percentage', 'tutor' ),
1081 'group_fields' => array(
1082 'fees_type' => array(
1083 'type' => 'select',
1084 'default' => 'fixed',
1085 'select_options' => false,
1086 'options' => array(
1087 'percent' => __( 'Percent', 'tutor' ),
1088 'fixed' => __( 'Fixed', 'tutor' ),
1089 ),
1090 ),
1091 'fees_amount' => array(
1092 'type' => 'number',
1093 'default' => '0',
1094 ),
1095 ),
1096 ),
1097 ),
1098 ),
1099 'block_withdraw' => array(
1100 'label' => __( 'Withdraw', 'tutor' ),
1101 'slug' => 'withdraw',
1102 'block_type' => 'uniform',
1103 'fields' => array(
1104 array(
1105 'key' => 'min_withdraw_amount',
1106 'type' => 'number',
1107 'label' => __( 'Minimum Withdrawal Amount', 'tutor' ),
1108 'default' => '80',
1109 'desc' => __( 'Instructors should earn equal or above this amount to make a withdraw request.', 'tutor' ),
1110 ),
1111 array(
1112 'key' => 'minimum_days_for_balance_to_be_available',
1113 'type' => 'number',
1114 'number_type' => 'integer',
1115 'label' => __( 'Minimum Days Before Balance is Available', 'tutor' ),
1116 'default' => '7',
1117 'min' => 1,
1118 'desc' => __( 'Any income has to remain this many days in the platform before it is available for withdrawal.', 'tutor' ),
1119 ),
1120 array(
1121 'key' => 'tutor_withdrawal_methods',
1122 'type' => 'checkbox_horizontal',
1123 'label' => __( 'Enable Withdraw Method', 'tutor' ),
1124 'default' => array( 'bank_transfer_withdraw' ),
1125 'options' => $methods_array,
1126 'desc' => __( 'Set how you would like to withdraw money from the website.', 'tutor' ),
1127 ),
1128 array(
1129 'key' => 'tutor_bank_transfer_withdraw_instruction',
1130 'type' => 'textarea',
1131 'label' => __( 'Bank Instructions', 'tutor' ),
1132 'default' => __( 'Write the up to date bank informations of your instructor here.', 'tutor' ),
1133 'desc' => __( 'Write bank instructions for the instructors to conduct withdrawals.', 'tutor' ),
1134 ),
1135 ),
1136 ),
1137 ),
1138 ),
1139 'design' => array(
1140 'label' => __( 'Design', 'tutor' ),
1141 'slug' => 'design',
1142 'desc' => __( 'Design Settings', 'tutor' ),
1143 'template' => 'design',
1144 'icon' => 'tutor-icon-color-palette',
1145 'blocks' => array(
1146 'block_course' => array(
1147 'label' => __( 'Course', 'tutor' ),
1148 'slug' => 'course',
1149 'block_type' => 'uniform',
1150 'fields' => array(
1151 array(
1152 'key' => 'courses_col_per_row',
1153 'type' => 'radio_horizontal',
1154 'label' => __( 'Column Per Row', 'tutor' ),
1155 'default' => '3',
1156 'options' => array(
1157 '1' => __( 'One', 'tutor' ),
1158 '2' => __( 'Two', 'tutor' ),
1159 '3' => __( 'Three', 'tutor' ),
1160 '4' => __( 'Four', 'tutor' ),
1161 ),
1162 'desc' => __( 'Define how many columns you want to use to display courses.', 'tutor' ),
1163 ),
1164 array(
1165 'key' => 'course_archive_filter',
1166 'type' => 'toggle_switch',
1167 'label' => __( 'Course Filter', 'tutor' ),
1168 'label_title' => '',
1169 'default' => 'off',
1170 'desc' => __( 'Show sorting and filtering options on course archive page', 'tutor' ),
1171 ),
1172 array(
1173 'key' => 'courses_per_page',
1174 'type' => 'number',
1175 'number_type' => 'integer',
1176 'label' => __( 'Courses Per Page', 'tutor' ),
1177 'default' => '12',
1178 'desc' => __( 'Set the number of courses to display per page on the Course List page.', 'tutor' ),
1179 ),
1180 array(
1181 'key' => 'supported_course_filters',
1182 'type' => 'checkbox_horizontal',
1183 'label' => __( 'Preferred Course Filters', 'tutor' ),
1184 'default' => array( 'search', 'category' ),
1185 'options' => array(
1186 'search' => __( 'Keyword Search', 'tutor' ),
1187 'category' => __( 'Category', 'tutor' ),
1188 'tag' => __( 'Tag', 'tutor' ),
1189 'difficulty_level' => __( 'Difficulty Level', 'tutor' ),
1190 'price_type' => __( 'Price Type', 'tutor' ),
1191 ),
1192 'desc' => __( 'Choose preferred filter options you\'d like to show on the course archive page.', 'tutor' ),
1193 ),
1194 array(
1195 'key' => 'course_archive_filter_sorting',
1196 'type' => 'toggle_switch',
1197 'label' => __( 'Course Sorting', 'tutor' ),
1198 'label_title' => '',
1199 'default' => 'on',
1200 'desc' => __( 'If enabled, the courses will be sortable by Course Name or Creation Date in either Ascending or Descending order', 'tutor' ),
1201 ),
1202 ),
1203 ),
1204 'layout' => array(
1205 'label' => __( 'Layout', 'tutor' ),
1206 'slug' => 'layout',
1207 'block_type' => 'uniform',
1208 'fields' => array(
1209 array(
1210 'key' => 'instructor_list_layout',
1211 'type' => 'group_radio',
1212 'label' => __( 'Instructor List Layout', 'tutor' ),
1213 'desc' => __( 'Choose a layout for the list of instructors inside a course page. You can change this at any time.', 'tutor' ),
1214 'default' => 'portrait',
1215 'group_options' => array(
1216 'vertical' => array(
1217 'default' => array(
1218 'title' => __( 'Portrait', 'tutor' ),
1219 'image' => 'instructor-layout/instructor-portrait.svg',
1220 ),
1221 'cover' => array(
1222 'title' => __( 'Cover', 'tutor' ),
1223 'image' => 'instructor-layout/instructor-cover.svg',
1224 ),
1225 'minimal' => array(
1226 'title' => __( 'Minimal', 'tutor' ),
1227 'image' => 'instructor-layout/instructor-minimal.svg',
1228 ),
1229 ),
1230 'horizontal' => array(
1231 'portrait-horizontal' => array(
1232 'title' => __( 'Portrait Horizontal', 'tutor' ),
1233 'image' => 'instructor-layout/instructor-horizontal-portrait.svg',
1234 ),
1235 'minimal-horizontal' => array(
1236 'title' => __( 'Minimal Horizontal', 'tutor' ),
1237 'image' => 'instructor-layout/instructor-horizontal-minimal.svg',
1238 ),
1239 ),
1240 ),
1241 ),
1242 array(
1243 'key' => 'public_profile_layout',
1244 'type' => 'group_radio_full_3',
1245 'label' => __( 'Instructor Public Profile Layout', 'tutor' ),
1246 'desc' => __( 'Choose a layout design for a instructor’s public profile', 'tutor' ),
1247 'default' => 'pp-rectangle',
1248 'group_options' => array(
1249 'private' => array(
1250 'title' => __( 'Private', 'tutor' ),
1251 'image' => 'profile-layout/profile-private.svg',
1252 ),
1253 'pp-circle' => array(
1254 'title' => __( 'Modern', 'tutor' ),
1255 'image' => 'profile-layout/profile-modern.svg',
1256 ),
1257 'no-cp' => array(
1258 'title' => __( 'Minimal', 'tutor' ),
1259 'image' => 'profile-layout/profile-minimal.svg',
1260 ),
1261 'pp-rectangle' => array(
1262 'title' => __( 'Classic', 'tutor' ),
1263 'image' => 'profile-layout/profile-classic.svg',
1264 ),
1265 ),
1266 ),
1267 array(
1268 'key' => 'student_public_profile_layout',
1269 'type' => 'group_radio_full_3',
1270 'label' => __( 'Student Public Profile Layout', 'tutor' ),
1271 'desc' => __( 'Choose a layout design for a student’s public profile', 'tutor' ),
1272 'default' => 'pp-rectangle',
1273 'group_options' => array(
1274 'private' => array(
1275 'title' => __( 'Private', 'tutor' ),
1276 'image' => 'profile-layout/profile-private.svg',
1277 ),
1278 'pp-circle' => array(
1279 'title' => __( 'Modern', 'tutor' ),
1280 'image' => 'profile-layout/profile-modern.svg',
1281 ),
1282 'no-cp' => array(
1283 'title' => __( 'Minimal', 'tutor' ),
1284 'image' => 'profile-layout/profile-minimal.svg',
1285 ),
1286 'pp-rectangle' => array(
1287 'title' => __( 'Classic', 'tutor' ),
1288 'image' => 'profile-layout/profile-classic.svg',
1289 ),
1290 ),
1291 ),
1292 ),
1293 ),
1294 'course-details' => array(
1295 'label' => __( 'Course Details', 'tutor' ),
1296 'slug' => 'course-details',
1297 'block_type' => 'isolate',
1298 'fields' => array(
1299 array(
1300 'key' => 'course_details_adjustments',
1301 'type' => 'checkgroup',
1302 'label' => __( 'Page Features', 'tutor' ),
1303 'desc' => __( 'You can keep the following features active or inactive as per the need of your business model', 'tutor' ),
1304 'group_options' => array(
1305 array(
1306 'key' => 'display_course_instructors',
1307 'type' => 'toggle_single',
1308 'label' => __( 'Instructor Info', 'tutor' ),
1309 'default' => 'on',
1310 'desc' => __( 'Toggle to show instructor info', 'tutor' ),
1311 ),
1312 array(
1313 'key' => 'enable_q_and_a_on_course',
1314 'type' => 'toggle_single',
1315 'label' => __( 'Q&A', 'tutor' ),
1316 'default' => 'on',
1317 'desc' => __( 'Enable to add a Q&A section', 'tutor' ),
1318 ),
1319 array(
1320 'key' => 'enable_course_author',
1321 'type' => 'toggle_single',
1322 'label' => __( 'Author', 'tutor' ),
1323 'label_title' => __( 'Enable', 'tutor' ),
1324 'default' => 'off',
1325 'desc' => __( 'Enable to show course author name', 'tutor' ),
1326 ),
1327 array(
1328 'key' => 'enable_course_level',
1329 'type' => 'toggle_single',
1330 'label' => __( 'Level', 'tutor' ),
1331 'label_title' => __( 'Enable', 'tutor' ),
1332 'default' => 'on',
1333 'desc' => __( 'Enable to show course level', 'tutor' ),
1334 ),
1335 array(
1336 'key' => 'enable_course_share',
1337 'type' => 'toggle_single',
1338 'label' => __( 'Social Share', 'tutor' ),
1339 'label_title' => __( 'Enable', 'tutor' ),
1340 'default' => 'on',
1341 'desc' => __( 'Toggle to enable course social share', 'tutor' ),
1342 ),
1343 array(
1344 'key' => 'enable_course_duration',
1345 'type' => 'toggle_single',
1346 'label' => __( 'Duration', 'tutor' ),
1347 'label_title' => __( 'Disable', 'tutor' ),
1348 'default' => 'on',
1349 'desc' => __( 'Enable to show course duration', 'tutor' ),
1350 ),
1351 array(
1352 'key' => 'enable_course_total_enrolled',
1353 'type' => 'toggle_single',
1354 'label' => __( 'Total Enrolled', 'tutor' ),
1355 'label_title' => __( 'Enable', 'tutor' ),
1356 'default' => 'on',
1357 'desc' => __( 'Enable to show total enrolled students', 'tutor' ),
1358 ),
1359 array(
1360 'key' => 'enable_course_update_date',
1361 'type' => 'toggle_single',
1362 'label' => __( 'Update Date', 'tutor' ),
1363 'label_title' => __( 'Enable', 'tutor' ),
1364 'default' => 'on',
1365 'desc' => __( 'Enable to show course update information', 'tutor' ),
1366 ),
1367 array(
1368 'key' => 'enable_course_progress_bar',
1369 'type' => 'toggle_single',
1370 'label' => __( 'Progress Bar', 'tutor' ),
1371 'label_title' => __( 'Enable', 'tutor' ),
1372 'default' => 'on',
1373 'desc' => __( 'Enable to show course progress for Students', 'tutor' ),
1374 ),
1375 array(
1376 'key' => 'enable_course_material',
1377 'type' => 'toggle_single',
1378 'label' => __( 'Material', 'tutor' ),
1379 'label_title' => __( 'Enable', 'tutor' ),
1380 'default' => 'on',
1381 'desc' => __( 'Enable to show course materials', 'tutor' ),
1382 ),
1383 array(
1384 'key' => 'enable_course_about',
1385 'type' => 'toggle_single',
1386 'label' => __( 'About', 'tutor' ),
1387 'label_title' => __( 'Enable', 'tutor' ),
1388 'default' => 'on',
1389 'desc' => __( 'Enable to show course about section', 'tutor' ),
1390 ),
1391 array(
1392 'key' => 'enable_course_description',
1393 'type' => 'toggle_single',
1394 'label' => __( 'Description', 'tutor' ),
1395 'label_title' => __( 'Enable', 'tutor' ),
1396 'default' => 'on',
1397 'desc' => __( 'Enable to show course description', 'tutor' ),
1398 ),
1399 array(
1400 'key' => 'enable_course_benefits',
1401 'type' => 'toggle_single',
1402 'label' => __( 'Benefits', 'tutor' ),
1403 'label_title' => __( 'Enable', 'tutor' ),
1404 'default' => 'on',
1405 'desc' => __( 'Enable to show course benefits section', 'tutor' ),
1406 ),
1407 array(
1408 'key' => 'enable_course_requirements',
1409 'type' => 'toggle_single',
1410 'label' => __( 'Requirements', 'tutor' ),
1411 'label_title' => __( 'Enable', 'tutor' ),
1412 'default' => 'on',
1413 'desc' => __( 'Enable to show courses requirements section', 'tutor' ),
1414 ),
1415 array(
1416 'key' => 'enable_course_target_audience',
1417 'type' => 'toggle_single',
1418 'label' => __( 'Target Audience', 'tutor' ),
1419 'label_title' => __( 'Disable', 'tutor' ),
1420 'default' => 'on',
1421 'desc' => __( 'Enable to show course target audience section', 'tutor' ),
1422 ),
1423 array(
1424 'key' => 'enable_course_announcements',
1425 'type' => 'toggle_single',
1426 'label' => __( 'Announcements', 'tutor' ),
1427 'label_title' => __( 'Enable', 'tutor' ),
1428 'default' => 'on',
1429 'desc' => __( 'Enable to show course announcements section', 'tutor' ),
1430 ),
1431 array(
1432 'key' => 'enable_course_review',
1433 'type' => 'toggle_single',
1434 'label' => __( 'Review', 'tutor' ),
1435 'label_title' => __( 'Enable', 'tutor' ),
1436 'default' => 'on',
1437 'desc' => __( 'Enable to show course review section', 'tutor' ),
1438 ),
1439 ),
1440 ),
1441 ),
1442 ),
1443 'colors' => array(
1444 'label' => __( 'Colors', 'tutor' ),
1445 'slug' => 'colors',
1446 'block_type' => 'color_picker',
1447 'fields_group' => array(
1448 array(
1449 'key' => 'color_preset_type',
1450 'type' => 'color_preset',
1451 'label' => __( 'Preset Colors', 'tutor' ),
1452 'desc' => __( 'These colors will be used throughout your website. Choose between these presets or create your own custom palette.', 'tutor' ),
1453 'default' => 'default',
1454 'fields' => array(
1455 /* First 4 preset_name should be same as color_fields */
1456 array(
1457 'key' => 'default',
1458 'label' => __( 'Default', 'tutor' ),
1459 'colors' => array(
1460 array(
1461 'slug' => 'tutor_primary_color',
1462 'preset_name' => 'primary',
1463 'value' => '#3E64DE',
1464 ),
1465 array(
1466 'slug' => 'tutor_primary_hover_color',
1467 'preset_name' => 'hover',
1468 'value' => '#395BCA',
1469 ),
1470 array(
1471 'slug' => 'tutor_text_color',
1472 'preset_name' => 'text',
1473 'value' => '#212327',
1474 ),
1475 array(
1476 'slug' => 'tutor_gray_color',
1477 'preset_name' => 'gray',
1478 'value' => '#E3E5EB',
1479 ),
1480 array(
1481 'slug' => 'tutor_border_color',
1482 'preset_name' => 'border',
1483 'value' => '#CDCFD5',
1484 ),
1485 ),
1486 ),
1487 array(
1488 'key' => 'landscape',
1489 'label' => __( 'Landscape', 'tutor' ),
1490 'colors' => array(
1491 array(
1492 'slug' => 'tutor_primary_color',
1493 'preset_name' => 'primary',
1494 'value' => '#239371',
1495 ),
1496 array(
1497 'slug' => 'tutor_primary_hover_color',
1498 'preset_name' => 'hover',
1499 'value' => '#117D5D',
1500 ),
1501 array(
1502 'slug' => 'tutor_text_color',
1503 'preset_name' => 'text',
1504 'value' => '#212327',
1505 ),
1506 array(
1507 'slug' => 'tutor_gray_color',
1508 'preset_name' => 'gray',
1509 'value' => '#E3E5EB',
1510 ),
1511 array(
1512 'slug' => 'tutor_border_color',
1513 'preset_name' => 'border',
1514 'value' => '#CDCFD5',
1515 ),
1516 ),
1517 ),
1518 array(
1519 'key' => 'ocean',
1520 'label' => __( 'Ocean', 'tutor' ),
1521 'colors' => array(
1522 array(
1523 'slug' => 'tutor_primary_color',
1524 'preset_name' => 'primary',
1525 'value' => '#5A18C2',
1526 ),
1527 array(
1528 'slug' => 'tutor_primary_hover_color',
1529 'preset_name' => 'hover',
1530 'value' => '#3F02A0',
1531 ),
1532 array(
1533 'slug' => 'tutor_text_color',
1534 'preset_name' => 'text',
1535 'value' => '#212327',
1536 ),
1537 array(
1538 'slug' => 'tutor_gray_color',
1539 'preset_name' => 'gray',
1540 'value' => '#E3E5EB',
1541 ),
1542 array(
1543 'slug' => 'tutor_border_color',
1544 'preset_name' => 'border',
1545 'value' => '#CDCFD5',
1546 ),
1547 ),
1548 ),
1549 array(
1550 'key' => 'custom',
1551 'label' => __( 'Custom', 'tutor' ),
1552 'colors' => array(
1553 array(
1554 'slug' => 'tutor_primary_color',
1555 'preset_name' => 'primary',
1556 'value' => '#3E64DE',
1557 ),
1558 array(
1559 'slug' => 'tutor_primary_hover_color',
1560 'preset_name' => 'hover',
1561 'value' => '#28408E',
1562 ),
1563 array(
1564 'slug' => 'tutor_text_color',
1565 'preset_name' => 'text',
1566 'value' => '#1A1B1E',
1567 ),
1568 array(
1569 'slug' => 'tutor_gray_color',
1570 'preset_name' => 'gray',
1571 'value' => '#E3E5EB',
1572 ),
1573 array(
1574 'slug' => 'tutor_border_color',
1575 'preset_name' => 'border',
1576 'value' => '#CDCFD5',
1577 ),
1578 ),
1579 ),
1580 ),
1581 ),
1582 array(
1583 'key' => 'tutor_color_presets',
1584 'type' => 'color_fields',
1585 'label' => __( 'Preset Colors', 'tutor' ),
1586 'fields' => array(
1587 array(
1588 'key' => 'tutor_primary_color',
1589 'type' => 'color_field',
1590 'preset_name' => 'primary',
1591 'preset_exist' => true,
1592 'label' => __( 'Primary Color', 'tutor' ),
1593 'default' => '#3E64DE',
1594 'desc' => __( 'Choose a primary color', 'tutor' ),
1595 ),
1596 array(
1597 'key' => 'tutor_primary_hover_color',
1598 'type' => 'color_field',
1599 'preset_name' => 'hover',
1600 'preset_exist' => true,
1601 'label' => __( 'Primary Hover Color', 'tutor' ),
1602 'default' => '#395BCA',
1603 'desc' => __( 'Choose a primary hover color', 'tutor' ),
1604 ),
1605 array(
1606 'key' => 'tutor_text_color',
1607 'type' => 'color_field',
1608 'preset_name' => 'text',
1609 'preset_exist' => true,
1610 'label' => __( 'Text Color', 'tutor' ),
1611 'default' => '#212327',
1612 'desc' => __( 'Choose a text color for your website', 'tutor' ),
1613 ),
1614 array(
1615 'key' => 'tutor_gray_color',
1616 'type' => 'color_field',
1617 'preset_name' => 'gray',
1618 'preset_exist' => false,
1619 'label' => __( 'Gray', 'tutor' ),
1620 'default' => '#E3E5EB',
1621 'desc' => __( 'Choose a color for elements like table, card etc', 'tutor' ),
1622 ),
1623 array(
1624 'key' => 'tutor_border_color',
1625 'type' => 'color_field',
1626 'preset_name' => 'border',
1627 'preset_exist' => false,
1628 'label' => __( 'Border', 'tutor' ),
1629 'default' => '#CDCFD5',
1630 'desc' => __( 'Choose a border color for your website', 'tutor' ),
1631 ),
1632 ),
1633 ),
1634 ),
1635 ),
1636 'video_player' => array(
1637 'label' => __( 'Video Player', 'tutor' ),
1638 'slug' => 'video_player',
1639 'block_type' => 'uniform',
1640 'fields' => array(
1641 array(
1642 'key' => 'disable_default_player_youtube',
1643 'type' => 'toggle_switch',
1644 'label' => __( 'Use Tutor Player for YouTube', 'tutor' ),
1645 'label_title' => '',
1646 'default' => 'off',
1647 'desc' => __( 'Enable this option to use Tutor LMS video player for YouTube.', 'tutor' ),
1648 ),
1649 array(
1650 'key' => 'disable_default_player_vimeo',
1651 'type' => 'toggle_switch',
1652 'label' => __( 'Use Tutor Player for Vimeo', 'tutor' ),
1653 'label_title' => '',
1654 'default' => 'off',
1655 'desc' => __( 'Enable this option to use Tutor LMS video player for Vimeo.', 'tutor' ),
1656 ),
1657 ),
1658 ),
1659 ),
1660 ),
1661 'advanced' => array(
1662 'label' => __( 'Advanced', 'tutor' ),
1663 'slug' => 'advanced',
1664 'desc' => __( 'Advanced Settings', 'tutor' ),
1665 'template' => 'basic',
1666 'icon' => 'tutor-icon-filter',
1667 'blocks' => array(
1668 array(
1669 'label' => __( 'Course', 'tutor' ),
1670 'slug' => 'options',
1671 'block_type' => 'uniform',
1672 'fields' => array(
1673 array(
1674 'key' => 'enable_gutenberg_course_edit',
1675 'type' => 'toggle_switch',
1676 'label' => __( 'Gutenberg Editor', 'tutor' ),
1677 'default' => 'off',
1678 'desc' => __( 'Enable this to create courses using the Gutenberg Editor.', 'tutor' ),
1679 ),
1680 array(
1681 'key' => 'hide_course_from_shop_page',
1682 'type' => 'toggle_switch',
1683 'label' => __( 'Hide Course Products on Shop Page', 'tutor' ),
1684 'default' => 'off',
1685 'desc' => __( 'Enable to hide course products on shop page.', 'tutor' ),
1686 ),
1687 array(
1688 'key' => 'course_archive_page',
1689 'type' => 'select',
1690 'label' => __( 'Course Archive Page', 'tutor' ),
1691 'default' => $course_archive_page_id->ID ?? '0',
1692 'options' => $pages,
1693 'desc' => __( 'This page will be used to list all the published courses.', 'tutor' ),
1694 'searchable' => true,
1695 ),
1696 array(
1697 'key' => 'instructor_register_page',
1698 'type' => 'select',
1699 'label' => __( 'Instructor Registration Page', 'tutor' ),
1700 'default' => '0',
1701 'options' => $pages,
1702 'desc' => __( 'Choose the page for instructor registration.', 'tutor' ),
1703 'searchable' => true,
1704 ),
1705 array(
1706 'key' => 'student_register_page',
1707 'type' => 'select',
1708 'label' => __( 'Student Registration Page', 'tutor' ),
1709 'default' => '0',
1710 'options' => $pages,
1711 'desc' => __( 'Choose the page for student registration.', 'tutor' ),
1712 'searchable' => true,
1713 ),
1714 array(
1715 'key' => 'lesson_video_duration_youtube_api_key',
1716 'type' => 'text',
1717 'label' => __( 'YouTube API Key', 'tutor' ),
1718 'default' => '',
1719 'desc' => __(
1720 'To host live videos on your platform using YouTube, enter your YouTube API key.',
1721 'tutor'
1722 ),
1723 'placeholder' => __( 'Insert API key here', 'tutor' ),
1724 ),
1725 ),
1726 ),
1727 array(
1728 'label' => __( 'Base Permalink', 'tutor' ),
1729 'slug' => 'base_permalink',
1730 'block_type' => 'uniform',
1731 'fields' => array(
1732 array(
1733 'key' => 'course_permalink_base',
1734 'type' => 'text',
1735 'label' => __( 'Course Permalink', 'tutor' ),
1736 'default' => 'courses',
1737 'desc' => $course_url,
1738 ),
1739 array(
1740 'key' => 'lesson_permalink_base',
1741 'type' => 'text',
1742 'label' => __( 'Lesson Permalink', 'tutor' ),
1743 'default' => 'lessons',
1744 'desc' => $lesson_url,
1745 ),
1746 array(
1747 'key' => 'quiz_permalink_base',
1748 'type' => 'text',
1749 'label' => __( 'Quiz Permalink', 'tutor' ),
1750 'default' => 'quizzes',
1751 'desc' => $quiz_url,
1752 ),
1753 ),
1754 ),
1755 array(
1756 'label' => __( 'Options', 'tutor' ),
1757 'slug' => 'options',
1758 'block_type' => 'uniform',
1759 'fields' => array(
1760 array(
1761 'key' => 'enable_profile_completion',
1762 'type' => 'toggle_switch',
1763 'label' => __( 'Profile Completion', 'tutor' ),
1764 'label_title' => '',
1765 'default' => 'off',
1766 'desc' => __( 'Enabling this feature will show a notification bar to students and instructors to complete their profile information', 'tutor' ),
1767 ),
1768 array(
1769 'key' => 'enable_tutor_native_login',
1770 'type' => 'toggle_switch',
1771 'label' => __( 'Enable Tutor Login', 'tutor' ),
1772 'label_title' => '',
1773 'default' => 'on',
1774 'desc' => __( 'Enable to use the tutor login modal instead of the default WordPress login page', 'tutor' ),
1775 ),
1776 array(
1777 'key' => 'delete_on_uninstall',
1778 'type' => 'toggle_switch',
1779 'label' => __( 'Erase upon uninstallation', 'tutor' ),
1780 'label_title' => '',
1781 'default' => 'off',
1782 'desc' => __( 'Delete all data during uninstallation', 'tutor' ),
1783 ),
1784 array(
1785 'key' => 'enable_tutor_maintenance_mode',
1786 'type' => 'toggle_switch',
1787 'label' => __( 'Maintenance Mode', 'tutor' ),
1788 'label_title' => '',
1789 'default' => 'off',
1790 'desc' => __( 'Enabling maintenance mode will display a custom message on the frontend. During maintenance mode, visitors cannot access site content, but the wp-admin dashboard remains accessible.', 'tutor' ),
1791 ),
1792 ),
1793 ),
1794 ),
1795 ),
1796 );
1797
1798 $attrs = apply_filters( 'tutor/options/extend/attr', apply_filters( 'tutor/options/attr', $attr ) );
1799
1800 // Get the active tab.
1801 $tab_page = tutor_utils()->array_get( 'tab_page', $_REQUEST, 'general' );
1802 $tab_data = null;
1803 $template = null;
1804
1805 foreach ( $attrs as $key => $section ) {
1806 if ( $tab_page == $key ) {
1807 if ( isset( $section['template_path'] ) && $section['template_path'] ) {
1808 $template = $section['template_path'];
1809 $tab_data = $section;
1810 }
1811 break;
1812 }
1813 }
1814
1815 // Store in runtime cache.
1816 $this->setting_fields = array(
1817 'option_fields' => $attrs,
1818 'active_tab' => $tab_page,
1819 'active_tab_data' => $tab_data,
1820 'template_path' => $template,
1821 );
1822
1823 return $this->setting_fields;
1824 }
1825
1826 /**
1827 * Generate field
1828 *
1829 * @since 2.0.0
1830 *
1831 * @param array $field field array.
1832 * @param array $blocks blocks array.
1833 *
1834 * @return void
1835 *
1836 * Generate Option Field
1837 */
1838 public function generate_field( $field = array(), $blocks = array() ) {
1839 ob_start();
1840 if ( isset( $field['type'] ) ) {
1841 include tutor()->path . "views/options/field-types/{$field['type']}.php";
1842 }
1843 echo ob_get_clean();//phpcs:ignore
1844 }
1845
1846 /**
1847 * Include field type template & return buffered
1848 * string data.
1849 *
1850 * @since 2.0.0
1851 *
1852 * @param array $field field.
1853 *
1854 * @return string
1855 */
1856 public function field_type( $field = array() ) {
1857 ob_start();
1858 if ( isset( $field['type'] ) ) {
1859 include tutor()->path . "views/options/field-types/{$field['type']}.php";
1860 }
1861 return ob_get_clean();
1862 }
1863
1864 /**
1865 * Include Option blocks template & return
1866 * buffered string data.
1867 *
1868 * @since 2.0.0
1869 *
1870 * @param array $blocks blocks.
1871 *
1872 * @return string
1873 */
1874 public function blocks( $blocks = array() ) {
1875 ob_start();
1876 include tutor()->path . 'views/options/option_blocks.php';
1877 return ob_get_clean();
1878 }
1879
1880 /**
1881 * Include options template & returns
1882 * buffered string data.
1883 *
1884 * @since 2.0.0
1885 *
1886 * @param array $section section.
1887 *
1888 * @return string
1889 */
1890 public function template( $section = array() ) {
1891 ob_start();
1892 $blocks = $section['blocks'];
1893 if ( isset( $section['template'] ) ) {
1894 include tutor()->path . "views/options/template/{$section['template']}.php";
1895 }
1896 return ob_get_clean();
1897 }
1898
1899 /**
1900 * Load template inside template directory
1901 *
1902 * @since 2.0.0
1903 *
1904 * @param mixed $template_slug template slug.
1905 * @param mixed $section section.
1906 *
1907 * @return string
1908 */
1909 public function view_template( $template_slug, $section = array() ) {
1910 ob_start();
1911 if ( isset( $template_slug ) ) {
1912 require tutor()->path . "views/options/template/{$template_slug}";
1913 }
1914 return ob_get_clean();
1915 }
1916 }
1917