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