PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.0.2
Tutor LMS – eLearning and online course solution v3.0.2
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 1 year 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 3 years ago WooCommerce.php 1 year ago
Options_V2.php
1905 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' => __( 'Students can complete courses anytime in the Flexible mode', 'tutor' ),
832 'strict' => __( 'Students have to complete, pass all the lessons and quizzes (if any) to mark a course as complete.', 'tutor' ),
833 ),
834 'desc' => __( 'Choose when a user can click on the <strong>“Complete Course”</strong> button', 'tutor' ),
835 ),
836 array(
837 'key' => 'course_retake_feature',
838 'type' => 'toggle_switch',
839 'label' => __( 'Course Retake', 'tutor' ),
840 'default' => 'off',
841 'label_title' => '',
842 'desc' => __( 'Enabling this feature will allow students to reset course progress and start over.', 'tutor' ),
843 ),
844 array(
845 'key' => 'enable_course_review_moderation',
846 'type' => 'toggle_switch',
847 'label' => __( "Publish Course Review on Admin's Approval", 'tutor' ),
848 'default' => 'off',
849 'label_title' => '',
850 'desc' => __( 'Enable to publish/re-publish Course Review after the approval of Site Admin', 'tutor' ),
851 ),
852 ),
853 ),
854 'block_lesson' => array(
855 'label' => __( 'Lesson', 'tutor' ),
856 'slug' => 'lesson',
857 'block_type' => 'uniform',
858 'fields' => array(
859 array(
860 'key' => 'enable_lesson_classic_editor',
861 'type' => 'toggle_switch',
862 'label' => __( 'WP Editor for Lesson', 'tutor' ),
863 'label_title' => '',
864 'default' => 'off',
865 'desc' => __( 'Enable classic editor to edit lesson.', 'tutor' ),
866 ),
867 array(
868 'key' => 'autoload_next_course_content',
869 'type' => 'toggle_switch',
870 'label' => __( 'Automatically Load Next Course Content.', 'tutor' ),
871 'label_title' => '',
872 'default' => 'off',
873 'desc' => __( 'Enable this feature to automatically load the next course content after the current one is finished.', 'tutor' ),
874 ),
875 array(
876 'key' => 'enable_comment_for_lesson',
877 'type' => 'toggle_switch',
878 'label' => __( 'Enable Lesson Comment', 'tutor' ),
879 'label_title' => '',
880 'default' => 'off',
881 'desc' => __( 'Enable this feature to allow students to post comments on lessons.', 'tutor' ),
882 ),
883 ),
884 ),
885 'block_quiz' => array(
886 'label' => __( 'Quiz', 'tutor' ),
887 'slug' => 'quiz',
888 'block_type' => 'uniform',
889 'fields' => array(
890 array(
891 'key' => 'quiz_when_time_expires',
892 'type' => 'radio_vertical',
893 'label' => __( 'When time expires', 'tutor' ),
894 'default' => 'auto_abandon',
895 'select_options' => false,
896 'options' => array(
897 'auto_submit' => __( 'The current quiz answers are submitted automatically.', 'tutor' ),
898 // 'grace_period' => __( 'The current quiz answers are submitted by students.', 'tutor' )
899 'auto_abandon' => __( 'Attempts must be submitted before time expires, otherwise they will not be counted', 'tutor' ),
900 ),
901 'desc' => __( 'Choose which action to follow when the quiz time expires.', 'tutor' ),
902 ),
903 array(
904 'key' => 'quiz_answer_display_time',
905 'type' => 'number',
906 'label' => __( 'Correct Answer Display Time (When Reveal Mode is enabled)', 'tutor' ),
907 'default' => '2',
908 'desc' => __( 'Put the answer display time in seconds', 'tutor' ),
909 ),
910 array(
911 'key' => 'quiz_attempts_allowed',
912 'type' => 'number',
913 'number_type' => 'integer',
914 'label' => __( 'Default Quiz Attempt limit (When Retry Mode is enabled)', 'tutor' ),
915 'default' => '10',
916 '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' ),
917 ),
918 array(
919 'key' => 'quiz_previous_button_enabled',
920 'type' => 'toggle_switch',
921 'label' => __( 'Show Quiz Previous Button', 'tutor' ),
922 'default' => 'on',
923 'desc' => __( 'Choose whether to show or hide the previous button for each question.', 'tutor' ),
924 ),
925 array(
926 'key' => 'quiz_grade_method',
927 'type' => 'radio_horizontal_full',
928 'label' => __( 'Final Grade Calculation', 'tutor' ),
929 'desc' => __( 'When multiple attempts are allowed, select which method should be used to calculate a student\'s final grade for the quiz.', 'tutor' ),
930 'default' => 'highest_grade',
931 'options' => array(
932 'highest_grade' => __( 'Highest Grade', 'tutor' ),
933 'average_grade' => __( 'Average Grade', 'tutor' ),
934 'first_attempt' => __( 'First Attempt', 'tutor' ),
935 'last_attempt' => __( 'Last Attempt', 'tutor' ),
936 ),
937 ),
938 ),
939 ),
940 array(
941 'label' => __( 'Video', 'tutor' ),
942 'slug' => 'video',
943 'block_type' => 'uniform',
944 'fields' => array(
945 array(
946 'key' => 'supported_video_sources',
947 'type' => 'checkbox_vertical',
948 'default' => array( 'youtube', 'vimeo' ),
949 'label' => __( 'Preferred Video Source', 'tutor' ),
950 'label_title' => __( 'Preferred Video Source', 'tutor' ),
951 'options' => tutor_utils()->get_video_sources( true ),
952 'desc' => __( 'Select the video hosting platform(s) you want to enable.', 'tutor' ),
953 ),
954 ),
955 ),
956 ),
957 ),
958 'monetization' => array(
959 'label' => __( 'Monetization', 'tutor' ),
960 'slug' => 'monetization',
961 'desc' => __( 'Monetization Settings', 'tutor' ),
962 'template' => 'basic',
963 'icon' => 'tutor-icon-badge-discount',
964 'blocks' => array(
965 'block_options' => array(
966 'label' => __( 'Options', 'tutor' ),
967 'slug' => 'options',
968 'block_type' => 'uniform',
969 'fields' => array(
970 array(
971 'key' => 'monetize_by',
972 'type' => 'select',
973 'label' => __( 'Select eCommerce Engine', 'tutor' ),
974 'select_options' => false,
975 'options' => apply_filters(
976 'tutor_monetization_options',
977 array(
978 'free' => __( 'Disable Monetization', 'tutor' ),
979 )
980 ),
981 'default' => 'free',
982 'desc' => __( 'Select a monetization option to generate revenue by selling courses.', 'tutor' ),
983 ),
984 ),
985 ),
986 'block_woocommerce' => array(
987 'label' => __( 'Woocommerce', 'tutor' ),
988 'slug' => 'woocommerce',
989 'block_type' => 'uniform',
990 'fields' => array(
991 array(
992 'key' => 'tutor_woocommerce_order_auto_complete',
993 'type' => 'toggle_switch',
994 'label' => __( 'Automatically Complete WooCommerce Orders', 'tutor' ),
995 'label_title' => '',
996 'default' => 'off',
997 'desc' => __( 'If enabled, in the case of Courses, WooCommerce Orders will get the "Completed" status .', 'tutor' ),
998 ),
999 ),
1000 ),
1001 'block_revenue_sharing' => array(
1002 'label' => __( 'Revenue Sharing', 'tutor' ),
1003 'slug' => 'revenue_sharing',
1004 'block_type' => 'uniform',
1005 'fields' => array(
1006 array(
1007 'key' => 'enable_revenue_sharing',
1008 'type' => 'toggle_switch',
1009 'label' => __( 'Enable Revenue Sharing', 'tutor' ),
1010 'label_title' => '',
1011 'default' => 'off',
1012 'desc' => __( 'Allow revenue generated from selling courses to be shared with course creators.', 'tutor' ),
1013 'toggle_fields' => 'sharing_percentage',
1014 'toggle_blocks' => 'fees,withdraw',
1015 ),
1016 array(
1017 'key' => 'sharing_percentage',
1018 'type' => 'double_input',
1019 'label' => __( 'Sharing Percentage', 'tutor' ),
1020 'label_title' => '',
1021 'default' => '',
1022 'fields' => array(
1023 'earning_instructor_commission' => array(
1024 'id' => 'revenue-instructor',
1025 'type' => 'ratio',
1026 'title' => 'Instructor Takes',
1027 'default' => 20,
1028 ),
1029 'earning_admin_commission' => array(
1030 'id' => 'revenue-admin',
1031 'type' => 'ratio',
1032 'title' => 'Admin Takes',
1033 'default' => 80,
1034 ),
1035 ),
1036 'desc' => __( 'Set how the sales revenue will be shared among admins and instructors.', 'tutor' ),
1037 ),
1038 ),
1039 ),
1040 'block_fees' => array(
1041 'label' => __( 'Fees', 'tutor' ),
1042 'slug' => 'fees',
1043 'block_type' => 'uniform',
1044 'fields' => array(
1045 array(
1046 'key' => 'enable_fees_deducting',
1047 'type' => 'toggle_switch',
1048 'label' => __( 'Deduct Fees', 'tutor' ),
1049 'label_title' => '',
1050 'default' => 'off',
1051 'desc' => __( 'Fees are charged from the entire sales amount. The remaining amount will be divided among admin and instructors.', 'tutor' ),
1052 'toggle_fields' => 'fees_name,fee_amount_type',
1053 ),
1054 array(
1055 'key' => 'fees_name',
1056 'type' => 'textarea',
1057 'label' => __( 'Fee Description', 'tutor' ),
1058 'placeholder' => __( 'Fee Description', 'tutor' ),
1059 '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' ),
1060 'maxlength' => 200,
1061 'rows' => 5,
1062 'default' => 'Maintenance Fees',
1063 ),
1064 array(
1065 'key' => 'fee_amount_type',
1066 'type' => 'group_fields',
1067 'label' => __( 'Fee Amount & Type', 'tutor' ),
1068 'desc' => __( 'Select the fee type and add fee amount/percentage', 'tutor' ),
1069 'group_fields' => array(
1070 'fees_type' => array(
1071 'type' => 'select',
1072 'default' => 'fixed',
1073 'select_options' => false,
1074 'options' => array(
1075 'percent' => __( 'Percent', 'tutor' ),
1076 'fixed' => __( 'Fixed', 'tutor' ),
1077 ),
1078 ),
1079 'fees_amount' => array(
1080 'type' => 'number',
1081 'default' => '0',
1082 ),
1083 ),
1084 ),
1085 ),
1086 ),
1087 'block_withdraw' => array(
1088 'label' => __( 'Withdraw', 'tutor' ),
1089 'slug' => 'withdraw',
1090 'block_type' => 'uniform',
1091 'fields' => array(
1092 array(
1093 'key' => 'min_withdraw_amount',
1094 'type' => 'number',
1095 'label' => __( 'Minimum Withdrawal Amount', 'tutor' ),
1096 'default' => '80',
1097 'desc' => __( 'Instructors should earn equal or above this amount to make a withdraw request.', 'tutor' ),
1098 ),
1099 array(
1100 'key' => 'minimum_days_for_balance_to_be_available',
1101 'type' => 'number',
1102 'number_type' => 'integer',
1103 'label' => __( 'Minimum Days Before Balance is Available', 'tutor' ),
1104 'default' => '7',
1105 'min' => 1,
1106 'desc' => __( 'Any income has to remain this many days in the platform before it is available for withdrawal.', 'tutor' ),
1107 ),
1108 array(
1109 'key' => 'tutor_withdrawal_methods',
1110 'type' => 'checkbox_horizontal',
1111 'label' => __( 'Enable Withdraw Method', 'tutor' ),
1112 'default' => array( 'bank_transfer_withdraw' ),
1113 'options' => $methods_array,
1114 'desc' => __( 'Set how you would like to withdraw money from the website.', 'tutor' ),
1115 ),
1116 array(
1117 'key' => 'tutor_bank_transfer_withdraw_instruction',
1118 'type' => 'textarea',
1119 'label' => __( 'Bank Instructions', 'tutor' ),
1120 'default' => __( 'Write the up to date bank informations of your instructor here.', 'tutor' ),
1121 'desc' => __( 'Write bank instructions for the instructors to conduct withdrawals.', 'tutor' ),
1122 ),
1123 ),
1124 ),
1125 ),
1126 ),
1127 'design' => array(
1128 'label' => __( 'Design', 'tutor' ),
1129 'slug' => 'design',
1130 'desc' => __( 'Design Settings', 'tutor' ),
1131 'template' => 'design',
1132 'icon' => 'tutor-icon-color-palette',
1133 'blocks' => array(
1134 'block_course' => array(
1135 'label' => __( 'Course', 'tutor' ),
1136 'slug' => 'course',
1137 'block_type' => 'uniform',
1138 'fields' => array(
1139 array(
1140 'key' => 'courses_col_per_row',
1141 'type' => 'radio_horizontal',
1142 'label' => __( 'Column Per Row', 'tutor' ),
1143 'default' => '3',
1144 'options' => array(
1145 '1' => 'One',
1146 '2' => 'Two',
1147 '3' => 'Three',
1148 '4' => 'Four',
1149 ),
1150 'desc' => __( 'Define how many columns you want to use to display courses.', 'tutor' ),
1151 ),
1152 array(
1153 'key' => 'course_archive_filter',
1154 'type' => 'toggle_switch',
1155 'label' => __( 'Course Filter', 'tutor' ),
1156 'label_title' => '',
1157 'default' => 'off',
1158 'desc' => __( 'Show sorting and filtering options on course archive page', 'tutor' ),
1159 ),
1160 array(
1161 'key' => 'courses_per_page',
1162 'type' => 'number',
1163 'number_type' => 'integer',
1164 'label' => __( 'Courses Per Page', 'tutor' ),
1165 'default' => '12',
1166 'desc' => __( 'Set the number of courses to display per page on the Course List page.', 'tutor' ),
1167 ),
1168 array(
1169 'key' => 'supported_course_filters',
1170 'type' => 'checkbox_horizontal',
1171 'label' => __( 'Preferred Course Filters', 'tutor' ),
1172 'default' => array( 'search', 'category' ),
1173 'options' => array(
1174 'search' => __( 'Keyword Search', 'tutor' ),
1175 'category' => __( 'Category', 'tutor' ),
1176 'tag' => __( 'Tag', 'tutor' ),
1177 'difficulty_level' => __( 'Difficulty Level', 'tutor' ),
1178 'price_type' => __( 'Price Type', 'tutor' ),
1179 ),
1180 'desc' => __( 'Choose preferred filter options you\'d like to show on the course archive page.', 'tutor' ),
1181 ),
1182 array(
1183 'key' => 'course_archive_filter_sorting',
1184 'type' => 'toggle_switch',
1185 'label' => __( 'Course Sorting', 'tutor' ),
1186 'label_title' => '',
1187 'default' => 'on',
1188 'desc' => __( 'If enabled, the courses will be sortable by Course Name or Creation Date in either Ascending or Descending order', 'tutor' ),
1189 ),
1190 ),
1191 ),
1192 'layout' => array(
1193 'label' => __( 'Layout', 'tutor' ),
1194 'slug' => 'layout',
1195 'block_type' => 'uniform',
1196 'fields' => array(
1197 array(
1198 'key' => 'instructor_list_layout',
1199 'type' => 'group_radio',
1200 'label' => __( 'Instructor List Layout', 'tutor' ),
1201 'desc' => __( 'Choose a layout for the list of instructors inside a course page. You can change this at any time.', 'tutor' ),
1202 'default' => 'portrait',
1203 'group_options' => array(
1204 'vertical' => array(
1205 'default' => array(
1206 'title' => 'Portrait',
1207 'image' => 'instructor-layout/instructor-portrait.svg',
1208 ),
1209 'cover' => array(
1210 'title' => 'Cover',
1211 'image' => 'instructor-layout/instructor-cover.svg',
1212 ),
1213 'minimal' => array(
1214 'title' => 'Minimal',
1215 'image' => 'instructor-layout/instructor-minimal.svg',
1216 ),
1217 ),
1218 'horizontal' => array(
1219 'portrait-horizontal' => array(
1220 'title' => 'Portrait Horizontal',
1221 'image' => 'instructor-layout/instructor-horizontal-portrait.svg',
1222 ),
1223 'minimal-horizontal' => array(
1224 'title' => 'Minimal Horizontal',
1225 'image' => 'instructor-layout/instructor-horizontal-minimal.svg',
1226 ),
1227 ),
1228 ),
1229 ),
1230 array(
1231 'key' => 'public_profile_layout',
1232 'type' => 'group_radio_full_3',
1233 'label' => __( 'Instructor Public Profile Layout', 'tutor' ),
1234 'desc' => __( 'Choose a layout design for a instructor’s public profile', 'tutor' ),
1235 'default' => 'pp-rectangle',
1236 'group_options' => array(
1237 'private' => array(
1238 'title' => 'Private',
1239 'image' => 'profile-layout/profile-private.svg',
1240 ),
1241 'pp-circle' => array(
1242 'title' => 'Modern',
1243 'image' => 'profile-layout/profile-modern.svg',
1244 ),
1245 'no-cp' => array(
1246 'title' => 'Minimal',
1247 'image' => 'profile-layout/profile-minimal.svg',
1248 ),
1249 'pp-rectangle' => array(
1250 'title' => 'Classic',
1251 'image' => 'profile-layout/profile-classic.svg',
1252 ),
1253 ),
1254 ),
1255 array(
1256 'key' => 'student_public_profile_layout',
1257 'type' => 'group_radio_full_3',
1258 'label' => __( 'Student Public Profile Layout', 'tutor' ),
1259 'desc' => __( 'Choose a layout design for a student’s public profile', 'tutor' ),
1260 'default' => 'pp-rectangle',
1261 'group_options' => array(
1262 'private' => array(
1263 'title' => 'Private',
1264 'image' => 'profile-layout/profile-private.svg',
1265 ),
1266 'pp-circle' => array(
1267 'title' => 'Modern',
1268 'image' => 'profile-layout/profile-modern.svg',
1269 ),
1270 'no-cp' => array(
1271 'title' => 'Minimal',
1272 'image' => 'profile-layout/profile-minimal.svg',
1273 ),
1274 'pp-rectangle' => array(
1275 'title' => 'Classic',
1276 'image' => 'profile-layout/profile-classic.svg',
1277 ),
1278 ),
1279 ),
1280 ),
1281 ),
1282 'course-details' => array(
1283 'label' => __( 'Course Details', 'tutor' ),
1284 'slug' => 'course-details',
1285 'block_type' => 'isolate',
1286 'fields' => array(
1287 array(
1288 'key' => 'course_details_adjustments',
1289 'type' => 'checkgroup',
1290 'label' => __( 'Page Features', 'tutor' ),
1291 'desc' => __( 'You can keep the following features active or inactive as per the need of your business model', 'tutor' ),
1292 'group_options' => array(
1293 array(
1294 'key' => 'display_course_instructors',
1295 'type' => 'toggle_single',
1296 'label' => __( 'Instructor Info', 'tutor' ),
1297 'default' => 'on',
1298 'desc' => __( 'Toggle to show instructor info', 'tutor' ),
1299 ),
1300 array(
1301 'key' => 'enable_q_and_a_on_course',
1302 'type' => 'toggle_single',
1303 'label' => __( 'Q&A', 'tutor' ),
1304 'default' => 'on',
1305 'desc' => __( 'Enable to add a Q&A section', 'tutor' ),
1306 ),
1307 array(
1308 'key' => 'enable_course_author',
1309 'type' => 'toggle_single',
1310 'label' => __( 'Author', 'tutor' ),
1311 'label_title' => __( 'Enable', 'tutor' ),
1312 'default' => 'off',
1313 'desc' => __( 'Enable to show course author name', 'tutor' ),
1314 ),
1315 array(
1316 'key' => 'enable_course_level',
1317 'type' => 'toggle_single',
1318 'label' => __( 'Level', 'tutor' ),
1319 'label_title' => __( 'Enable', 'tutor' ),
1320 'default' => 'on',
1321 'desc' => __( 'Enable to show course level', 'tutor' ),
1322 ),
1323 array(
1324 'key' => 'enable_course_share',
1325 'type' => 'toggle_single',
1326 'label' => __( 'Social Share', 'tutor' ),
1327 'label_title' => __( 'Enable', 'tutor' ),
1328 'default' => 'on',
1329 'desc' => __( 'Toggle to enable course social share', 'tutor' ),
1330 ),
1331 array(
1332 'key' => 'enable_course_duration',
1333 'type' => 'toggle_single',
1334 'label' => __( 'Duration', 'tutor' ),
1335 'label_title' => __( 'Disable', 'tutor' ),
1336 'default' => 'on',
1337 'desc' => __( 'Enable to show course duration', 'tutor' ),
1338 ),
1339 array(
1340 'key' => 'enable_course_total_enrolled',
1341 'type' => 'toggle_single',
1342 'label' => __( 'Total Enrolled', 'tutor' ),
1343 'label_title' => __( 'Enable', 'tutor' ),
1344 'default' => 'on',
1345 'desc' => __( 'Enable to show total enrolled students', 'tutor' ),
1346 ),
1347 array(
1348 'key' => 'enable_course_update_date',
1349 'type' => 'toggle_single',
1350 'label' => __( 'Update Date', 'tutor' ),
1351 'label_title' => __( 'Enable', 'tutor' ),
1352 'default' => 'on',
1353 'desc' => __( 'Enable to show course update information', 'tutor' ),
1354 ),
1355 array(
1356 'key' => 'enable_course_progress_bar',
1357 'type' => 'toggle_single',
1358 'label' => __( 'Progress Bar', 'tutor' ),
1359 'label_title' => __( 'Enable', 'tutor' ),
1360 'default' => 'on',
1361 'desc' => __( 'Enable to show course progress for Students', 'tutor' ),
1362 ),
1363 array(
1364 'key' => 'enable_course_material',
1365 'type' => 'toggle_single',
1366 'label' => __( 'Material', 'tutor' ),
1367 'label_title' => __( 'Enable', 'tutor' ),
1368 'default' => 'on',
1369 'desc' => __( 'Enable to show course materials', 'tutor' ),
1370 ),
1371 array(
1372 'key' => 'enable_course_about',
1373 'type' => 'toggle_single',
1374 'label' => __( 'About', 'tutor' ),
1375 'label_title' => __( 'Enable', 'tutor' ),
1376 'default' => 'on',
1377 'desc' => __( 'Enable to show course about section', 'tutor' ),
1378 ),
1379 array(
1380 'key' => 'enable_course_description',
1381 'type' => 'toggle_single',
1382 'label' => __( 'Description', 'tutor' ),
1383 'label_title' => __( 'Enable', 'tutor' ),
1384 'default' => 'on',
1385 'desc' => __( 'Enable to show course description', 'tutor' ),
1386 ),
1387 array(
1388 'key' => 'enable_course_benefits',
1389 'type' => 'toggle_single',
1390 'label' => __( 'Benefits', 'tutor' ),
1391 'label_title' => __( 'Enable', 'tutor' ),
1392 'default' => 'on',
1393 'desc' => __( 'Enable to show course benefits section', 'tutor' ),
1394 ),
1395 array(
1396 'key' => 'enable_course_requirements',
1397 'type' => 'toggle_single',
1398 'label' => __( 'Requirements', 'tutor' ),
1399 'label_title' => __( 'Enable', 'tutor' ),
1400 'default' => 'on',
1401 'desc' => __( 'Enable to show courses requirements setion', 'tutor' ),
1402 ),
1403 array(
1404 'key' => 'enable_course_target_audience',
1405 'type' => 'toggle_single',
1406 'label' => __( 'Target Audience', 'tutor' ),
1407 'label_title' => __( 'Disable', 'tutor' ),
1408 'default' => 'on',
1409 'desc' => __( 'Enable to show course target audience section', 'tutor' ),
1410 ),
1411 array(
1412 'key' => 'enable_course_announcements',
1413 'type' => 'toggle_single',
1414 'label' => __( 'Announcements', 'tutor' ),
1415 'label_title' => __( 'Enable', 'tutor' ),
1416 'default' => 'on',
1417 'desc' => __( 'Enable to show course announcements section', 'tutor' ),
1418 ),
1419 array(
1420 'key' => 'enable_course_review',
1421 'type' => 'toggle_single',
1422 'label' => __( 'Review', 'tutor' ),
1423 'label_title' => __( 'Enable', 'tutor' ),
1424 'default' => 'on',
1425 'desc' => __( 'Enable to show course review section', 'tutor' ),
1426 ),
1427 ),
1428 ),
1429 ),
1430 ),
1431 'colors' => array(
1432 'label' => __( 'Colors', 'tutor' ),
1433 'slug' => 'colors',
1434 'block_type' => 'color_picker',
1435 'fields_group' => array(
1436 array(
1437 'key' => 'color_preset_type',
1438 'type' => 'color_preset',
1439 'label' => __( 'Preset Colors', 'tutor' ),
1440 'desc' => __( 'These colors will be used throughout your website. Choose between these presets or create your own custom palette.', 'tutor' ),
1441 'default' => 'default',
1442 'fields' => array(
1443 /* First 4 preset_name should be same as color_fields */
1444 array(
1445 'key' => 'default',
1446 'label' => 'Default',
1447 'colors' => array(
1448 array(
1449 'slug' => 'tutor_primary_color',
1450 'preset_name' => 'primary',
1451 'value' => '#3E64DE',
1452 ),
1453 array(
1454 'slug' => 'tutor_primary_hover_color',
1455 'preset_name' => 'hover',
1456 'value' => '#395BCA',
1457 ),
1458 array(
1459 'slug' => 'tutor_text_color',
1460 'preset_name' => 'text',
1461 'value' => '#212327',
1462 ),
1463 array(
1464 'slug' => 'tutor_gray_color',
1465 'preset_name' => 'gray',
1466 'value' => '#E3E5EB',
1467 ),
1468 array(
1469 'slug' => 'tutor_border_color',
1470 'preset_name' => 'border',
1471 'value' => '#CDCFD5',
1472 ),
1473 ),
1474 ),
1475 array(
1476 'key' => 'landscape',
1477 'label' => 'Landscape',
1478 'colors' => array(
1479 array(
1480 'slug' => 'tutor_primary_color',
1481 'preset_name' => 'primary',
1482 'value' => '#239371',
1483 ),
1484 array(
1485 'slug' => 'tutor_primary_hover_color',
1486 'preset_name' => 'hover',
1487 'value' => '#117D5D',
1488 ),
1489 array(
1490 'slug' => 'tutor_text_color',
1491 'preset_name' => 'text',
1492 'value' => '#212327',
1493 ),
1494 array(
1495 'slug' => 'tutor_gray_color',
1496 'preset_name' => 'gray',
1497 'value' => '#E3E5EB',
1498 ),
1499 array(
1500 'slug' => 'tutor_border_color',
1501 'preset_name' => 'border',
1502 'value' => '#CDCFD5',
1503 ),
1504 ),
1505 ),
1506 array(
1507 'key' => 'ocean',
1508 'label' => 'Ocean',
1509 'colors' => array(
1510 array(
1511 'slug' => 'tutor_primary_color',
1512 'preset_name' => 'primary',
1513 'value' => '#5A18C2',
1514 ),
1515 array(
1516 'slug' => 'tutor_primary_hover_color',
1517 'preset_name' => 'hover',
1518 'value' => '#3F02A0',
1519 ),
1520 array(
1521 'slug' => 'tutor_text_color',
1522 'preset_name' => 'text',
1523 'value' => '#212327',
1524 ),
1525 array(
1526 'slug' => 'tutor_gray_color',
1527 'preset_name' => 'gray',
1528 'value' => '#E3E5EB',
1529 ),
1530 array(
1531 'slug' => 'tutor_border_color',
1532 'preset_name' => 'border',
1533 'value' => '#CDCFD5',
1534 ),
1535 ),
1536 ),
1537 array(
1538 'key' => 'custom',
1539 'label' => 'Custom',
1540 'colors' => array(
1541 array(
1542 'slug' => 'tutor_primary_color',
1543 'preset_name' => 'primary',
1544 'value' => '#3E64DE',
1545 ),
1546 array(
1547 'slug' => 'tutor_primary_hover_color',
1548 'preset_name' => 'hover',
1549 'value' => '#28408E',
1550 ),
1551 array(
1552 'slug' => 'tutor_text_color',
1553 'preset_name' => 'text',
1554 'value' => '#1A1B1E',
1555 ),
1556 array(
1557 'slug' => 'tutor_gray_color',
1558 'preset_name' => 'gray',
1559 'value' => '#E3E5EB',
1560 ),
1561 array(
1562 'slug' => 'tutor_border_color',
1563 'preset_name' => 'border',
1564 'value' => '#CDCFD5',
1565 ),
1566 ),
1567 ),
1568 ),
1569 ),
1570 array(
1571 'key' => 'tutor_color_presets',
1572 'type' => 'color_fields',
1573 'label' => __( 'Preset Colors', 'tutor' ),
1574 'fields' => array(
1575 array(
1576 'key' => 'tutor_primary_color',
1577 'type' => 'color_field',
1578 'preset_name' => 'primary',
1579 'preset_exist' => true,
1580 'label' => __( 'Primary Color', 'tutor' ),
1581 'default' => '#3E64DE',
1582 'desc' => __( 'Choose a primary color', 'tutor' ),
1583 ),
1584 array(
1585 'key' => 'tutor_primary_hover_color',
1586 'type' => 'color_field',
1587 'preset_name' => 'hover',
1588 'preset_exist' => true,
1589 'label' => __( 'Primary Hover Color', 'tutor' ),
1590 'default' => '#395BCA',
1591 'desc' => __( 'Choose a primary hover color', 'tutor' ),
1592 ),
1593 array(
1594 'key' => 'tutor_text_color',
1595 'type' => 'color_field',
1596 'preset_name' => 'text',
1597 'preset_exist' => true,
1598 'label' => __( 'Text Color', 'tutor' ),
1599 'default' => '#212327',
1600 'desc' => __( 'Choose a text color for your website', 'tutor' ),
1601 ),
1602 array(
1603 'key' => 'tutor_gray_color',
1604 'type' => 'color_field',
1605 'preset_name' => 'gray',
1606 'preset_exist' => false,
1607 'label' => __( 'Gray', 'tutor' ),
1608 'default' => '#E3E5EB',
1609 'desc' => __( 'Choose a color for elements like table, card etc', 'tutor' ),
1610 ),
1611 array(
1612 'key' => 'tutor_border_color',
1613 'type' => 'color_field',
1614 'preset_name' => 'border',
1615 'preset_exist' => false,
1616 'label' => __( 'Border', 'tutor' ),
1617 'default' => '#CDCFD5',
1618 'desc' => __( 'Choose a border color for your website', 'tutor' ),
1619 ),
1620 ),
1621 ),
1622 ),
1623 ),
1624 'video_player' => array(
1625 'label' => __( 'Video Player', 'tutor' ),
1626 'slug' => 'video_player',
1627 'block_type' => 'uniform',
1628 'fields' => array(
1629 array(
1630 'key' => 'disable_default_player_youtube',
1631 'type' => 'toggle_switch',
1632 'label' => __( 'Use Tutor Player for YouTube', 'tutor' ),
1633 'label_title' => '',
1634 'default' => 'off',
1635 'desc' => __( 'Enable this option to use Tutor LMS video player for YouTube.', 'tutor' ),
1636 ),
1637 array(
1638 'key' => 'disable_default_player_vimeo',
1639 'type' => 'toggle_switch',
1640 'label' => __( 'Use Tutor Player for Vimeo', 'tutor' ),
1641 'label_title' => '',
1642 'default' => 'off',
1643 'desc' => __( 'Enable this option to use Tutor LMS video player for Vimeo.', 'tutor' ),
1644 ),
1645 ),
1646 ),
1647 ),
1648 ),
1649 'advanced' => array(
1650 'label' => __( 'Advanced', 'tutor' ),
1651 'slug' => 'advanced',
1652 'desc' => __( 'Advanced Settings', 'tutor' ),
1653 'template' => 'basic',
1654 'icon' => 'tutor-icon-filter',
1655 'blocks' => array(
1656 array(
1657 'label' => __( 'Course', 'tutor' ),
1658 'slug' => 'options',
1659 'block_type' => 'uniform',
1660 'fields' => array(
1661 array(
1662 'key' => 'enable_gutenberg_course_edit',
1663 'type' => 'toggle_switch',
1664 'label' => __( 'Gutenberg Editor', 'tutor' ),
1665 'default' => 'off',
1666 'desc' => __( 'Enable this to create courses using the Gutenberg Editor.', 'tutor' ),
1667 ),
1668 array(
1669 'key' => 'hide_course_from_shop_page',
1670 'type' => 'toggle_switch',
1671 'label' => __( 'Hide Course Products on Shop Page', 'tutor' ),
1672 'default' => 'off',
1673 'desc' => __( 'Enable to hide course products on shop page.', 'tutor' ),
1674 ),
1675 array(
1676 'key' => 'course_archive_page',
1677 'type' => 'select',
1678 'label' => __( 'Course Archive Page', 'tutor' ),
1679 'default' => $course_archive_page_id->ID ?? '0',
1680 'options' => $pages,
1681 'desc' => __( 'This page will be used to list all the published courses.', 'tutor' ),
1682 'searchable' => true,
1683 ),
1684 array(
1685 'key' => 'instructor_register_page',
1686 'type' => 'select',
1687 'label' => __( 'Instructor Registration Page', 'tutor' ),
1688 'default' => '0',
1689 'options' => $pages,
1690 'desc' => __( 'Choose the page for instructor registration.', 'tutor' ),
1691 'searchable' => true,
1692 ),
1693 array(
1694 'key' => 'student_register_page',
1695 'type' => 'select',
1696 'label' => __( 'Student Registration Page', 'tutor' ),
1697 'default' => '0',
1698 'options' => $pages,
1699 'desc' => __( 'Choose the page for student registration.', 'tutor' ),
1700 'searchable' => true,
1701 ),
1702 array(
1703 'key' => 'lesson_video_duration_youtube_api_key',
1704 'type' => 'text',
1705 'label' => __( 'YouTube API Key', 'tutor' ),
1706 'default' => '',
1707 'desc' => __(
1708 'To host live videos on your platform using YouTube, enter your YouTube API key.',
1709 'tutor'
1710 ),
1711 'placeholder' => __( 'Insert API key here', 'tutor' ),
1712 ),
1713 ),
1714 ),
1715 array(
1716 'label' => __( 'Base Permalink', 'tutor' ),
1717 'slug' => 'base_permalink',
1718 'block_type' => 'uniform',
1719 'fields' => array(
1720 array(
1721 'key' => 'course_permalink_base',
1722 'type' => 'text',
1723 'label' => __( 'Course Permalink', 'tutor' ),
1724 'default' => 'courses',
1725 'desc' => $course_url,
1726 ),
1727 array(
1728 'key' => 'lesson_permalink_base',
1729 'type' => 'text',
1730 'label' => __( 'Lesson Permalink', 'tutor' ),
1731 'default' => 'lessons',
1732 'desc' => $lesson_url,
1733 ),
1734 array(
1735 'key' => 'quiz_permalink_base',
1736 'type' => 'text',
1737 'label' => __( 'Quiz Permalink', 'tutor' ),
1738 'default' => 'quizzes',
1739 'desc' => $quiz_url,
1740 ),
1741 ),
1742 ),
1743 array(
1744 'label' => __( 'Options', 'tutor' ),
1745 'slug' => 'options',
1746 'block_type' => 'uniform',
1747 'fields' => array(
1748 array(
1749 'key' => 'enable_profile_completion',
1750 'type' => 'toggle_switch',
1751 'label' => __( 'Profile Completion', 'tutor' ),
1752 'label_title' => '',
1753 'default' => 'off',
1754 'desc' => __( 'Enabling this feature will show a notification bar to students and instructors to complete their profile information', 'tutor' ),
1755 ),
1756 array(
1757 'key' => 'enable_tutor_native_login',
1758 'type' => 'toggle_switch',
1759 'label' => __( 'Enable Tutor Login', 'tutor' ),
1760 'label_title' => '',
1761 'default' => 'on',
1762 'desc' => __( 'Enable to use the tutor login modal instead of the default WordPress login page', 'tutor' ),
1763 ),
1764 array(
1765 'key' => 'delete_on_uninstall',
1766 'type' => 'toggle_switch',
1767 'label' => __( 'Erase upon uninstallation', 'tutor' ),
1768 'label_title' => '',
1769 'default' => 'off',
1770 'desc' => __( 'Delete all data during uninstallation', 'tutor' ),
1771 ),
1772 array(
1773 'key' => 'enable_tutor_maintenance_mode',
1774 'type' => 'toggle_switch',
1775 'label' => __( 'Maintenance Mode', 'tutor' ),
1776 'label_title' => '',
1777 'default' => 'off',
1778 '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' ),
1779 ),
1780 ),
1781 ),
1782 ),
1783 ),
1784 );
1785
1786 $attrs = apply_filters( 'tutor/options/extend/attr', apply_filters( 'tutor/options/attr', $attr ) );
1787
1788 // Get the active tab.
1789 $tab_page = tutor_utils()->array_get( 'tab_page', $_REQUEST, 'general' );
1790 $tab_data = null;
1791 $template = null;
1792
1793 foreach ( $attrs as $key => $section ) {
1794 if ( $tab_page == $key ) {
1795 if ( isset( $section['template_path'] ) && $section['template_path'] ) {
1796 $template = $section['template_path'];
1797 $tab_data = $section;
1798 }
1799 break;
1800 }
1801 }
1802
1803 // Store in runtime cache.
1804 $this->setting_fields = array(
1805 'option_fields' => $attrs,
1806 'active_tab' => $tab_page,
1807 'active_tab_data' => $tab_data,
1808 'template_path' => $template,
1809 );
1810
1811 return $this->setting_fields;
1812 }
1813
1814 /**
1815 * Generate field
1816 *
1817 * @since 2.0.0
1818 *
1819 * @param array $field field array.
1820 * @param array $blocks blocks array.
1821 *
1822 * @return void
1823 *
1824 * Generate Option Field
1825 */
1826 public function generate_field( $field = array(), $blocks = array() ) {
1827 ob_start();
1828 if ( isset( $field['type'] ) ) {
1829 include tutor()->path . "views/options/field-types/{$field['type']}.php";
1830 }
1831 echo ob_get_clean();//phpcs:ignore
1832 }
1833
1834 /**
1835 * Include field type template & return buffered
1836 * string data.
1837 *
1838 * @since 2.0.0
1839 *
1840 * @param array $field field.
1841 *
1842 * @return string
1843 */
1844 public function field_type( $field = array() ) {
1845 ob_start();
1846 if ( isset( $field['type'] ) ) {
1847 include tutor()->path . "views/options/field-types/{$field['type']}.php";
1848 }
1849 return ob_get_clean();
1850 }
1851
1852 /**
1853 * Include Option blocks template & return
1854 * buffered string data.
1855 *
1856 * @since 2.0.0
1857 *
1858 * @param array $blocks blocks.
1859 *
1860 * @return string
1861 */
1862 public function blocks( $blocks = array() ) {
1863 ob_start();
1864 include tutor()->path . 'views/options/option_blocks.php';
1865 return ob_get_clean();
1866 }
1867
1868 /**
1869 * Include options template & returns
1870 * buffered string data.
1871 *
1872 * @since 2.0.0
1873 *
1874 * @param array $section section.
1875 *
1876 * @return string
1877 */
1878 public function template( $section = array() ) {
1879 ob_start();
1880 $blocks = $section['blocks'];
1881 if ( isset( $section['template'] ) ) {
1882 include tutor()->path . "views/options/template/{$section['template']}.php";
1883 }
1884 return ob_get_clean();
1885 }
1886
1887 /**
1888 * Load template inside template directory
1889 *
1890 * @since 2.0.0
1891 *
1892 * @param mixed $template_slug template slug.
1893 * @param mixed $section section.
1894 *
1895 * @return string
1896 */
1897 public function view_template( $template_slug, $section = array() ) {
1898 ob_start();
1899 if ( isset( $template_slug ) ) {
1900 require tutor()->path . "views/options/template/{$template_slug}";
1901 }
1902 return ob_get_clean();
1903 }
1904 }
1905