PluginProbe
Search & Replace Everything – Quick and Easy Way to Find and Replace Text, Links / trunk
Search & Replace Everything – Quick and Easy Way to Find and Replace Text, Links vtrunk
1.5.2 1.5.0 1.5.1 1.4.7 1.4.6 1.4.4 1.4.5 1.4.3 trunk 1.0.2 1.0.3 1.0.4 1.0.4.1 1.1 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.2 1.2.3 1.2.4 1.2.5 All 34 releases
update-urls / lite / includes / Settings.php

Settings.php in Search & Replace Everything – Quick and Easy Way to Find and Replace Text, Links trunk, at lite/includes/Settings.php

1,446 lines 52.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace KaizenCoders\UpdateURLS;
4
5 class Settings {
6 /**
7 * @access private
8 * @var array
9 */
10 private $settings_wrapper;
11
12 /**
13 * @access private
14 * @var array
15 */
16 private $settings;
17
18 /**
19 * @access private
20 * @var array
21 */
22 private $tabs;
23
24 /**
25 * @access private
26 * @var string
27 */
28 private $option_group;
29
30 private $dependent_fields = [];
31
32 /**
33 * @access private
34 * @var array
35 */
36 private $settings_page = [];
37
38 /**
39 * @access private
40 * @var string
41 */
42 private $options_path;
43
44 /**
45 * @access private
46 * @var string
47 */
48 private $options_url;
49
50 /**
51 * @access protected
52 * @var array
53 */
54 protected $setting_defaults = [
55 'id' => 'default_field',
56 'title' => '',
57 'desc' => '',
58 'std' => '',
59 'type' => 'text',
60 'placeholder' => '',
61 'choices' => [],
62 'class' => '',
63 'subfields' => [],
64 'parent' => '', // ID of parent field
65 'show_if' => [], // Conditions when to show: ['parent_value' => 'expected_value']
66 'hide_if' => [],
67 ];
68
69 /**
70 * WordPressSettingsFramework constructor.
71 *
72 * @param null|string $settings_file Path to a settings file, or null if you pass the option_group manually and construct your settings with a filter.
73 * @param bool|string $option_group Option group name, usually a short slug.
74 */
75 public function __construct( $settings_file = null, $option_group = false ) {
76 $this->option_group = $option_group;
77
78 if ( $settings_file ) {
79 if ( ! is_file( $settings_file ) ) {
80 return;
81 }
82
83 require_once( $settings_file );
84
85 if ( ! $this->option_group ) {
86 $this->option_group = preg_replace( "/[^a-z0-9]+/i", "", basename( $settings_file, '.php' ) );
87 }
88 }
89
90 if ( empty( $this->option_group ) ) {
91 return;
92 }
93
94 $this->options_path = plugin_dir_path( __FILE__ );
95 //$this->options_url = plugin_dir_url( __FILE__ );
96 $this->options_url = KC_UU_PLUGIN_ASSETS_DIR_URL . '/';
97
98 $this->construct_settings();
99
100 if ( is_admin() ) {
101 global $pagenow;
102
103 add_action( 'admin_init', [ $this, 'admin_init' ] );
104 add_action( 'wpsf_do_settings_sections_' . $this->option_group, [
105 $this,
106 'do_tabless_settings_sections',
107 ], 10 );
108
109 if ( isset( $_GET['page'] ) && $_GET['page'] === $this->settings_page['slug'] ) {
110 if ( $pagenow !== "options-general.php" ) {
111 add_action( 'admin_notices', [ $this, 'admin_notices' ] );
112 }
113 add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
114 }
115
116 if ( $this->has_tabs() ) {
117 add_action( 'wpsf_before_settings_' . $this->option_group, [ $this, 'tab_links' ] );
118
119 remove_action( 'wpsf_do_settings_sections_' . $this->option_group, [
120 $this,
121 'do_tabless_settings_sections',
122 ], 10 );
123
124 add_action( 'wpsf_do_settings_sections_' . $this->option_group, [
125 $this,
126 'do_tabbed_settings_sections',
127 ], 10 );
128 }
129 }
130 }
131
132 /**
133 * Construct Settings.
134 */
135 public function construct_settings() {
136 $this->settings_wrapper = apply_filters( 'wpsf_register_settings_' . $this->option_group, [] );
137
138 if ( ! is_array( $this->settings_wrapper ) ) {
139 return new WP_Error( 'broke', __( 'WPSF settings must be an array', 'url-shortify' ) );
140 }
141
142 // If "sections" is set, this settings group probably has tabs
143 if ( isset( $this->settings_wrapper['sections'] ) ) {
144 $this->tabs = ( isset( $this->settings_wrapper['tabs'] ) ) ? $this->settings_wrapper['tabs'] : [];
145 $this->settings = $this->settings_wrapper['sections'];
146 // If not, it's probably just an array of settings
147 } else {
148 $this->settings = $this->settings_wrapper;
149 }
150
151 $this->settings_page['slug'] = sprintf( '%s-settings', str_replace( '_', '-', $this->option_group ) );
152 }
153
154 /**
155 * Get the option group for this instance
156 *
157 * @return string the "option_group"
158 */
159 public function get_option_group() {
160 return $this->option_group;
161 }
162
163 /**
164 * Registers the internal WordPress settings
165 */
166 public function admin_init() {
167 register_setting( $this->option_group, $this->option_group . '_settings', [ $this, 'settings_validate' ] );
168 $this->process_settings();
169 }
170
171 /**
172 * Add Settings Page
173 *
174 * @param array $args
175 */
176 public function add_settings_page( $args ) {
177 $defaults = [
178 'parent_slug' => false,
179 'page_slug' => "",
180 'page_title' => "",
181 'menu_title' => "",
182 'capability' => 'manage_options',
183 ];
184
185 $args = wp_parse_args( $args, $defaults );
186
187 $this->settings_page['title'] = $args['page_title'];
188 $this->settings_page['capability'] = $args['capability'];
189
190 if ( $args['parent_slug'] ) {
191 add_submenu_page(
192 $args['parent_slug'],
193 $this->settings_page['title'],
194 $args['menu_title'],
195 $args['capability'],
196 $this->settings_page['slug'],
197 [ $this, 'settings_page_content' ]
198 );
199 } else {
200 add_menu_page(
201 $this->settings_page['title'],
202 $args['menu_title'],
203 $args['capability'],
204 $this->settings_page['slug'],
205 [ $this, 'settings_page_content' ],
206 apply_filters( 'wpsf_menu_icon_url_' . $this->option_group, '' ),
207 apply_filters( 'wpsf_menu_position_' . $this->option_group, null )
208 );
209 }
210 }
211
212 /**
213 * Settings Page Content
214 */
215
216 public function settings_page_content() {
217 if ( ! current_user_can( $this->settings_page['capability'] ) ) {
218 wp_die( __( 'You do not have sufficient permissions to access this page.', 'url-shortify' ) );
219 }
220 ?>
221 <div class="wrap">
222 <div id="icon-options-general" class="icon32"></div>
223 <h2><?php
224 echo $this->settings_page['title']; ?></h2>
225 <?php
226 // Output your settings form
227 $this->settings();
228 ?>
229 </div>
230 <?php
231 }
232
233 /**
234 * Displays any errors from the WordPress settings API
235 */
236 public function admin_notices() {
237 settings_errors();
238 }
239
240 /**
241 * Enqueue scripts and styles
242 */
243 public function admin_enqueue_scripts() {
244 // scripts
245 // wp_register_script( 'jquery-ui-timepicker', $this->options_url . 'settings/assets/vendor/jquery-timepicker/jquery.ui.timepicker.js', [
246 // 'jquery',
247 // 'jquery-ui-core',
248 // ], false, true );
249 wp_register_script( 'wpsf', $this->options_url . 'settings/assets/js/main.js', [ 'jquery' ], false, true );
250
251 wp_enqueue_script( 'jquery' );
252 wp_enqueue_script( 'farbtastic' );
253 wp_enqueue_script( 'media-upload' );
254 wp_enqueue_script( 'thickbox' );
255 wp_enqueue_script( 'jquery-ui-core' );
256 wp_enqueue_script( 'jquery-ui-datepicker' );
257 // wp_enqueue_script( 'jquery-ui-timepicker' );
258 wp_enqueue_script( 'wpsf' );
259
260 // styles
261 // wp_register_style( 'jquery-ui-timepicker', $this->options_url . 'settings/assets/vendor/jquery-timepicker/jquery.ui.timepicker.css' );
262 wp_register_style( 'wpsf', $this->options_url . 'settings/assets/css/main.css' );
263 wp_register_style( 'jquery-ui-css',
264 '//ajax.googleapis.com/ajax/libs/jqueryui/1.8.21/themes/ui-darkness/jquery-ui.css' );
265
266 wp_enqueue_style( 'farbtastic' );
267 wp_enqueue_style( 'thickbox' );
268 // wp_enqueue_style( 'jquery-ui-timepicker' );
269 wp_enqueue_style( 'jquery-ui-css' );
270 wp_enqueue_style( 'wpsf' );
271
272 wp_add_inline_script('wpsf', '
273 (function($) {
274 function updateFieldAndChildren($field, shouldShow) {
275 // Update current field visibility
276 $field.toggle(shouldShow);
277
278 // Find and update all child fields
279 var fieldId = $field.find("[id]").first().attr("id");
280 if (fieldId) {
281 $("[data-parent=\'" + fieldId + "\']").each(function() {
282 var $childField = $(this);
283 // Recursively update children
284 // If parent is hidden, children should always be hidden
285 // If parent is visible, check child\'s own conditions
286 if (!shouldShow) {
287 updateFieldAndChildren($childField, false);
288 } else {
289 checkAndUpdateField($childField);
290 }
291 });
292 }
293 }
294
295 function checkAndUpdateField($field) {
296 var parentId = $field.data("parent");
297 if (!parentId) return;
298
299 var $parent = $("#" + parentId);
300 var parentValue = $parent.val();
301
302 if ($parent.is(":checkbox")) {
303 parentValue = $parent.is(":checked") ? "1" : "0";
304 }
305
306 var showIf = $field.data("show-if");
307 var hideIf = $field.data("hide-if");
308 var shouldShow = true;
309
310 if (showIf && !Object.entries(showIf).some(([key, value]) => parentValue === value)) {
311 shouldShow = false;
312 }
313
314 if (hideIf && Object.entries(hideIf).some(([key, value]) => parentValue === value)) {
315 shouldShow = false;
316 }
317
318 // Check if parent is visible
319 if (!$parent.closest(".wpsf-field").is(":visible")) {
320 shouldShow = false;
321 }
322
323 updateFieldAndChildren($field, shouldShow);
324 }
325
326 function recheckAllDependencies() {
327 $("[data-parent]").each(function() {
328 checkAndUpdateField($(this));
329 });
330 }
331
332 function handleFieldDependencies() {
333 $("[data-parent]").each(function() {
334 var $field = $(this);
335 var parentId = $field.data("parent");
336 var $parent = $("#" + parentId);
337
338 $parent.on("change", function() {
339 checkAndUpdateField($field);
340 });
341 });
342
343 // Initial check
344 recheckAllDependencies();
345 }
346
347 $(document).ready(function() {
348 handleFieldDependencies();
349
350 // Re-check dependencies when switching tabs,
351 // since hidden tabs cause :visible checks to fail
352 $(document).on("click", ".wpsf-tab-link", function() {
353 setTimeout(recheckAllDependencies, 50);
354 });
355 });
356 })(jQuery);
357 ');
358 }
359
360 /**
361 * Adds a filter for settings validation.
362 *
363 * @param $input
364 *
365 * @return array
366 */
367 public function settings_validate( $input ) {
368 return apply_filters( $this->option_group . '_settings_validate', $input );
369 }
370
371 /**
372 * Displays the "section_description" if specified in $this->settings
373 *
374 * @param array callback args from add_settings_section()
375 */
376 public function section_intro( $args ) {
377 if ( ! empty( $this->settings ) ) {
378 foreach ( $this->settings as $section ) {
379 if ( $section['section_id'] == $args['id'] ) {
380 if ( isset( $section['section_description'] ) && $section['section_description'] ) {
381 echo '<div class="wpsf-section-description wpsf-section-description--' . esc_attr( $section['section_id'] ) . '">' . $section['section_description'] . '</div>';
382 }
383 break;
384 }
385 }
386 }
387 }
388
389 /**
390 * Add dependency attributes to field wrapper
391 */
392 private function generate_field_wrapper( $args, $content ) {
393 $attributes = [];
394
395 if ( ! empty( $args['parent'] ) ) {
396 $attributes[] = 'data-parent="' . esc_attr( $args['parent'] ) . '"';
397
398 if ( ! empty( $args['show_if'] ) ) {
399 $attributes[] = 'data-show-if="' . esc_attr( json_encode( $args['show_if'] ) ) . '"';
400 }
401
402 if ( ! empty( $args['hide_if'] ) ) {
403 $attributes[] = 'data-hide-if="' . esc_attr( json_encode( $args['hide_if'] ) ) . '"';
404 }
405
406 //$attributes[] = 'style="display:none;"';
407 }
408
409 if ( ! empty( $this->dependent_fields[ $args['id'] ] ) ) {
410 $attributes[] = 'data-has-dependencies="true"';
411 }
412
413 $wrapper_attrs = ! empty( $attributes ) ? ' ' . implode( ' ', $attributes ) : '';
414
415 return sprintf(
416 '<div class="wpsf-field%s"%s>%s</div>',
417 ! empty( $args['parent'] ) ? ' wpsf-field--dependent' : '',
418 $wrapper_attrs,
419 $content
420 );
421 }
422
423 /**
424 * Processes $this->settings and adds the sections and fields via the WordPress settings API
425 */
426 private function process_settings() {
427 if ( ! empty( $this->settings ) ) {
428
429 if (!empty($this->settings)) {
430 foreach ($this->settings as $section) {
431 if (isset($section['fields']) && is_array($section['fields'])) {
432 foreach ($section['fields'] as $field) {
433 if (!empty($field['parent'])) {
434 $this->dependent_fields[$field['parent']][] = $field['id'];
435 }
436 }
437 }
438 }
439 }
440
441 usort( $this->settings, [ $this, 'sort_array' ] );
442
443 $options = get_option( $this->option_group . '_settings' );
444
445 foreach ( $this->settings as $section ) {
446 if ( isset( $section['section_id'] ) && $section['section_id'] && isset( $section['section_title'] ) ) {
447 $page_name = ( $this->has_tabs() ) ? sprintf( '%s_%s', $this->option_group,
448 $section['tab_id'] ) : $this->option_group;
449
450 add_settings_section( $section['section_id'], $section['section_title'], [
451 $this,
452 'section_intro',
453 ], $page_name );
454
455 if ( isset( $section['fields'] ) && is_array( $section['fields'] ) && ! empty( $section['fields'] ) ) {
456 usort( $section['fields'], [ $this, 'sort_fields' ] );
457 foreach ( $section['fields'] as $field ) {
458 if ( isset( $field['id'] ) && $field['id'] && isset( $field['title'] ) ) {
459 $name = $this->get_field_name_to_get_value( $section['tab_id'], $section['section_id'],
460 $field['id'] );
461
462 $value = Helper::get_data( $options, $name, Helper::get_data( $field, 'default', '' ) );
463
464 $title = ! empty( $field['subtitle'] ) ? sprintf( '%s <span class="wpsf-subtitle">%s</span>',
465 $field['title'], $field['subtitle'] ) : $field['title'];
466
467 add_settings_field( $field['id'], $title, [
468 $this,
469 'generate_setting',
470 ], $page_name, $section['section_id'],
471 [
472 'section' => $section,
473 'field' => $field,
474 'name' => $name,
475 'value' => $value,
476 ] );
477 }
478 }
479 }
480 }
481 }
482 }
483 }
484
485 /**
486 * Usort callback. Sorts $this->settings by "section_order"
487 *
488 * @param $a
489 * @param $b
490 *
491 * @return bool
492 */
493 public function sort_array( $a, $b ) {
494 if ( ! isset( $a['section_order'] ) || ! isset( $b['section_order'] ) ) {
495 return 0;
496 }
497
498 return ( $a['section_order'] == $b['section_order'] ? 0 : ( $a['section_order'] > $b['section_order'] ? 1 : - 1 ) );
499 }
500
501 /**
502 * Sort fields by order.
503 *
504 * @param $a
505 * @param $b
506 *
507 * @return false|int
508 */
509 public function sort_fields( $a, $b ) {
510 if ( ! isset( $a['order'] ) ) {
511 $a['order'] = 0;
512 }
513
514 if ( ! isset( $b['order'] ) ) {
515 $b['order'] = 0;
516 }
517
518 return ( $a['order'] == $b['order'] ? 0 : ( $a['order'] > $b['order'] ? 1 : - 1 ) );
519 }
520
521 /**
522 * Generates the HTML output of the settings fields
523 *
524 * @param array callback args from add_settings_field()
525 */
526 public function generate_setting( $args ) {
527 $section = $args['section'];
528 $this->setting_defaults = apply_filters( 'wpsf_defaults_' . $this->option_group, $this->setting_defaults );
529
530 $value = $args['value'];
531 $args = wp_parse_args( $args['field'], $this->setting_defaults );
532
533 $name = $this->generate_field_name( $section['tab_id'], $section['section_id'], $args['id'] );
534
535 $args['id'] = $this->has_tabs() ? sprintf( '%s_%s_%s', $section['tab_id'], $section['section_id'],
536 $args['id'] ) : sprintf( '%s_%s', $section['section_id'], $args['id'] );
537 $args['name'] = $name;
538 $args['value'] = $value;
539
540 do_action( 'wpsf_before_field_' . $this->option_group );
541 do_action( 'wpsf_before_field_' . $this->option_group . '_' . $args['id'] );
542
543 $this->do_field_method( $args );
544
545 do_action( 'wpsf_after_field_' . $this->option_group );
546 do_action( 'wpsf_after_field_' . $this->option_group . '_' . $args['id'] );
547 }
548
549 /**
550 * Do field method, if it exists
551 *
552 * @param array $args
553 */
554 public function do_field_method( $args ) {
555 $generate_field_method = sprintf( 'generate_%s_field', $args['type'] );
556
557 if ( method_exists( $this, $generate_field_method ) ) {
558 $this->$generate_field_method( $args );
559 }
560 }
561
562 /**
563 * Generate: Hidden field.
564 *
565 * @param array $args
566 */
567 public function generate_hidden_field( $args ) {
568 $args['value'] = esc_attr( stripslashes( $args['value'] ) );
569
570 echo '<input type="hidden" name="' . $args['name'] . '" id="' . $args['id'] . '" value="' . $args['value'] . '" class="hidden-field ' . $args['class'] . '" />';
571 }
572
573 /**
574 * Generate: Group field
575 *
576 * Generates a table of subfields, and a javascript template for create new repeatable rows
577 *
578 * @param array $args
579 */
580 public function generate_group_field( $args ) {
581 $value = (array) $args['value'];
582 $row_count = ! empty( $value ) ? count( $value ) : 1;
583
584 $output = '<table class="widefat wpsf-group" cellspacing="0">';
585
586 $output .= "<tbody>";
587
588 for ( $row = 0; $row < $row_count; $row ++ ) {
589 $output .= $this->generate_group_row_template( $args, false, $row );
590 }
591
592 $output .= "</tbody>";
593 $output .= "</table>";
594 $output .= sprintf( '<script type="text/html" id="%s_template">%s</script>', $args['id'],
595 $this->generate_group_row_template( $args, true ) );
596
597 $output .= $this->generate_description( $args['desc'] );
598
599 echo $output;
600 }
601
602 /**
603 * Generate: Fieldset field
604 *
605 * @param $args
606 *
607 * @return void
608 *
609 * @since 1.1.7
610 */
611 public function generate_fieldset_field( $args) {
612 $output = '';
613 $output .= '<fieldset class="wpsf-fieldset">';
614
615 // if ( ! empty( $args['title'] ) ) {
616 // $output .= '<legend class="wpsf-fieldset-legend">' . esc_html( $args['title'] ) . '</legend>';
617 // }
618
619 foreach ( $args['subfields'] as $subfield ) {
620 $row_template = '';
621 $subfield = wp_parse_args( $subfield, $this->setting_defaults );
622
623 $subfield['value'] = ( isset( $args['value'][ $subfield['id'] ] ) ? $args['value'][ $subfield['id'] ] : "" );
624 $subfield['name'] = sprintf( '%s[%s]', $args['name'], $subfield['id'] );
625 $subfield['id'] = sprintf( '%s_%s', $args['id'], $subfield['id'] );
626
627 // Pass fieldset context for inline_sentence fields.
628 $subfield['fieldset_name'] = $args['name'];
629 $subfield['fieldset_value'] = $args['value'];
630
631 $class = sprintf( 'wpsf-fieldset__field-wrapper--%s', $subfield['type'] );
632
633 $row_template .= sprintf( '<div class="wpsf-fieldset__field-wrapper %s">', $class );
634
635 if ( ! empty( $subfield['title'] ) ) {
636 $row_template .= sprintf( '<label for="%s" class="wpsf-fieldset__field-label">%s</label>', $subfield['id'],
637 $subfield['title'] );
638 }
639
640 ob_start();
641 $this->do_field_method( $subfield );
642 $row_template .= ob_get_clean();
643
644 $row_template .= '</div>';
645
646 $row_template = $this->generate_field_wrapper( $subfield, $row_template );
647
648 $output .= $row_template;
649 }
650 $output .= '</fieldset>';
651
652 echo $this->generate_field_wrapper( $args, $output );
653 }
654
655 /**
656 * Generate: Inline Sentence field
657 *
658 * Renders a sentence with inline input fields embedded in the text.
659 * Placeholders in the sentence (e.g. {field_name}) are replaced with input fields.
660 * Input values are saved at the fieldset level for backward compatibility.
661 *
662 * @param array $args
663 *
664 * @return void
665 *
666 * @since 1.2.0
667 */
668 public function generate_inline_sentence_field( $args ) {
669 $sentence = isset( $args['sentence'] ) ? $args['sentence'] : '';
670 $inputs = isset( $args['inputs'] ) ? $args['inputs'] : [];
671 $fieldset_name = isset( $args['fieldset_name'] ) ? $args['fieldset_name'] : '';
672 $fieldset_value = isset( $args['fieldset_value'] ) ? $args['fieldset_value'] : [];
673
674 $field_html = '<p class="wpsf-inline-sentence" style="display: flex; align-items: center; flex-wrap: wrap; gap: 4px; font-size: 14px; line-height: 2.5; border: 1px solid #dcdcde; border-radius: 4px; padding: 8px 12px; background: #f9f9f9;">';
675
676 $parts = preg_split( '/\{(\w+)\}/', $sentence, -1, PREG_SPLIT_DELIM_CAPTURE );
677
678 foreach ( $parts as $i => $part ) {
679 if ( $i % 2 === 0 ) {
680 $field_html .= esc_html( $part );
681 } elseif ( isset( $inputs[ $part ] ) ) {
682 $input = $inputs[ $part ];
683 $input_name = sprintf( '%s[%s]', $fieldset_name, $part );
684 $input_id = sprintf( '%s_%s', $args['id'], $part );
685 $value = isset( $fieldset_value[ $part ] ) ? $fieldset_value[ $part ] : ( isset( $input['default'] ) ? $input['default'] : '' );
686 $placeholder = isset( $input['placeholder'] ) ? $input['placeholder'] : '';
687 $type = isset( $input['type'] ) ? $input['type'] : 'number';
688
689 $field_html .= sprintf(
690 '<input type="%s" name="%s" id="%s" value="%s" placeholder="%s" class="form-input h-9 text-sm border-gray-400 text-center" style="width: 70px;" />',
691 esc_attr( $type ),
692 esc_attr( $input_name ),
693 esc_attr( $input_id ),
694 esc_attr( $value ),
695 esc_attr( $placeholder )
696 );
697 }
698 }
699
700 $field_html .= '</p>';
701
702 if ( ! empty( $args['desc'] ) ) {
703 $field_html .= $this->generate_description( $args['desc'] );
704 }
705
706 echo $this->generate_field_wrapper( $args, $field_html );
707 }
708
709 public function generate_child_field($args) {
710 if (empty($args['children']) || !is_array($args['children'])) {
711 return;
712 }
713
714 echo '<div class="wpsf-child-fields" data-parent="' . $args['parent'] . '">';
715 foreach ($args['children'] as $child) {
716 $child = wp_parse_args($child, $this->setting_defaults);
717
718 // Set up the child field
719 $options = get_option($this->option_group . '_settings');
720 $child['id'] = sprintf('%s_%s', $args['id'], $child['id']);
721 $child['name'] = $this->generate_field_name('t', 's', $child['id']);
722 $child['value'] = isset($options[$child['id']]) ? $options[$child['id']] :
723 (isset($child['default']) ? $child['default'] : '');
724
725 // Generate the child field wrapper
726 echo '<div class="wpsf-child-field">';
727
728 // Only show label and field, no th element
729 if (!empty($child['title'])) {
730 echo '<label class="wpsf-child-field__label">' . $child['title'] . '</label>';
731 }
732
733 // Generate the actual field
734 $this->do_field_method($child);
735
736 echo '</div>';
737 }
738
739 echo '</div>';
740
741 // Add JavaScript to handle visibility
742 $this->add_child_fields_script($args['parent']);
743 }
744
745 private function add_child_fields_script($parent_id) {
746 ?>
747 <script type="text/javascript">
748 (function($) {
749 $(document).ready(function() {
750 var $parent = $('#<?php echo esc_js($parent_id); ?>');
751 console.log($parent);
752 var $childFields = $('.wpsf-child-fields[data-parent="<?php echo esc_js($parent_id); ?>"]');
753
754 function toggleChildFields() {
755 if ($parent.is(':checkbox')) {
756 $childFields.toggle($parent.is(':checked'));
757 } else {
758 $childFields.toggle($parent.val() !== '');
759 }
760 }
761
762 $parent.on('change', toggleChildFields);
763 toggleChildFields(); // Initial state
764 });
765 })(jQuery);
766 </script>
767 <?php
768 }
769
770 /**
771 * Generate group row template
772 *
773 * @param array $args Field arguments
774 * @param bool $blank Blank values
775 * @param int $row Iterator
776 *
777 * @return string|bool
778 */
779 public function generate_group_row_template( $args, $blank = false, $row = 0 ) {
780 $row_template = false;
781 $row_id = ! empty( $args['value'][ $row ]['row_id'] ) ? $args['value'][ $row ]['row_id'] : $row;
782 $row_id_value = $blank ? '' : $row_id;
783
784 if ( $args['subfields'] ) {
785 $row_class = $row % 2 == 0 ? "alternate" : "";
786
787 $row_template .= sprintf( '<tr class="wpsf-group__row %s">', $row_class );
788
789 $row_template .= sprintf( '<td class="wpsf-group__row-index"><span>%d</span></td>', $row );
790
791 $row_template .= '<td class="wpsf-group__row-fields">';
792
793 $row_template .= '<input type="hidden" class="wpsf-group__row-id" name="' . sprintf( '%s[%d][row_id]',
794 esc_attr( $args['name'] ), esc_attr( $row ) ) . '" value="' . esc_attr( $row_id_value ) . '" />';
795
796 foreach ( $args['subfields'] as $subfield ) {
797 $subfield = wp_parse_args( $subfield, $this->setting_defaults );
798
799 $subfield['value'] = ( $blank ) ? "" : ( isset( $args['value'][ $row ][ $subfield['id'] ] ) ? $args['value'][ $row ][ $subfield['id'] ] : "" );
800 $subfield['name'] = sprintf( '%s[%d][%s]', $args['name'], $row, $subfield['id'] );
801 $subfield['id'] = sprintf( '%s_%d_%s', $args['id'], $row, $subfield['id'] );
802
803 $class = sprintf( 'wpsf-group__field-wrapper--%s', $subfield['type'] );
804
805 $row_template .= sprintf( '<div class="wpsf-group__field-wrapper %s">', $class );
806 $row_template .= sprintf( '<label for="%s" class="wpsf-group__field-label">%s</label>', $subfield['id'],
807 $subfield['title'] );
808
809 ob_start();
810 $this->do_field_method( $subfield );
811 $row_template .= ob_get_clean();
812
813 $row_template .= '</div>';
814 }
815
816 $row_template .= "</td>";
817
818 $row_template .= '<td class="wpsf-group__row-actions">';
819
820 $row_template .= sprintf( '<a href="javascript: void(0);" class="wpsf-group__row-add" data-template="%s_template"><span class="dashicons dashicons-plus-alt"></span></a>',
821 $args['id'] );
822 $row_template .= '<a href="javascript: void(0);" class="wpsf-group__row-remove"><span class="dashicons dashicons-trash"></span></a>';
823
824 $row_template .= "</td>";
825
826 $row_template .= '</tr>';
827
828 $row_template .= $this->generate_field_wrapper( $args, $row );
829 }
830
831 return $row_template;
832 }
833
834 /**
835 * Generate: Checkboxes field
836 *
837 * @param array $args
838 */
839 public function generate_checkboxes_field( $args ) {
840 echo '<input type="hidden" name="' . $args['name'] . '" value="0" />';
841
842 if ( count( $args['choices'] ) > 6 ) {
843 echo '<ul class="wpsf-list wpsf-list--checkboxes columns-3">';
844 } else {
845 echo '<ul class="wpsf-list wpsf-list--checkboxes">';
846 }
847
848 foreach ( $args['choices'] as $value => $text ) {
849 $checked = is_array( $args['value'] ) && in_array( strval( $value ), array_map( 'strval', $args['value'] ),
850 true ) ? 'checked="checked"' : '';
851 $field_id = sprintf( '%s_%s', $args['id'], $value );
852
853 echo sprintf( '<li class="mb-3"><label><input type="checkbox" name="%s[]" id="%s" value="%s" class="%s" %s> %s</label></li>',
854 $args['name'], $field_id, $value, $args['class'] . ' form-checkbox text-indigo-600', $checked, $text );
855 }
856
857 echo '</ul>';
858
859 $this->generate_description( $args['desc'] );
860 }
861
862 /**
863 * Generate Social Networks.
864 *
865 * @param $args
866 *
867 * @return void
868 *
869 * @since 1.8.1
870 *
871 */
872 public function generate_social_networks_field( $args ) {
873 if ( count( $args['choices'] ) > 6 ) {
874 $output = "<ul class='social-linkz-social-networks social-linkz-sortable columns-4'>";
875 } else {
876 $output = "<ul class='social-linkz-social-networks social-linkz-sortable'>";
877 }
878
879 foreach ( $args['choices'] as $id => $details ) {
880 $checked = is_array( $args['value'] ) && in_array( strval( $id ), array_map( 'strval', $args['value'] ),
881 true ) ? 'checked="checked"' : '';
882
883 $field_id = sprintf( '%s_%s', $args['id'], $id );
884
885 $output .= "<li class='social-linkz-social-network-" . $id . " mb-3'>";
886 $output .= "<label for='social-linkz" . ( ! empty( $args['section'] ) ? "-" . $args['section'] : "" ) . "-social-network-input-" . $id . "' class='" . ( $checked ? "active" : "" ) . "'>";
887 $output .= $details['icon'];
888 $output .= $details['name'];
889 $output .= "<input type='checkbox' id='social-linkz" . ( ! empty( $args['section'] ) ? "-" . $args['section'] : "" ) . "-social-network-input-" . $id . "' name='" . $args['name'] . "[]' value='" . $id . "'" . ( $checked ? " checked" : "" ) . " />";
890 $output .= "</label>";
891 $output .= "</li>";
892 }
893 $output .= "</ul>";
894
895 echo $output;
896
897 $this->generate_description( $args['desc'] );
898 }
899
900 /**
901 * Generate: Text field
902 */
903 public function generate_text_field($args) {
904 $args['value'] = esc_attr(stripslashes($args['value']));
905
906 $field_html = '<input type="text" name="' . $args['name'] . '" id="' . $args['id'] . '" value="' . $args['value'] . '" placeholder="' . $args['placeholder'] . '" class="form-input h-9 mb-1 text-sm border-gray-400 w-2/5 ' . $args['class'] . '" />';
907 $field_html .= $this->generate_description($args['desc']);
908
909 echo $this->generate_field_wrapper($args, $field_html);
910 }
911
912 /**
913 * Generate: Number field
914 */
915 public function generate_number_field($args) {
916
917 $args['value'] = esc_attr(stripslashes($args['value']));
918
919 $field_html = '<input type="number" name="' . $args['name'] . '" id="' . $args['id'] . '" value="' . $args['value'] . '" placeholder="' . $args['placeholder'] . '" class="form-input h-9 mb-1 text-sm border-gray-400 w-1/5 ' . $args['class'] . '" />';
920 $field_html .= $this->generate_description($args['desc']);
921
922 echo $this->generate_field_wrapper($args, $field_html);
923 }
924
925 /**
926 * Generate: Select field
927 */
928 public function generate_select_field($args) {
929 $args['value'] = esc_html(esc_attr($args['value']));
930
931 $field_html = '<select name="' . $args['name'] . '" id="' . $args['id'] . '" class="' . $args['class'] . ' form-select rounded-lg w-2/5 h-9 mb-1 border-gray-400">';
932 foreach ($args['choices'] as $value => $text) {
933 $selected = $value == $args['value'] ? 'selected="selected"' : '';
934 $field_html .= sprintf('<option value="%s" %s>%s</option>', $value, $selected, $text);
935 }
936 $field_html .= '</select>';
937 $field_html .= $this->generate_description($args['desc']);
938
939 echo $this->generate_field_wrapper($args, $field_html);
940 }
941
942 /**
943 * Generate: Radio field
944 */
945 public function generate_radio_field($args) {
946 $args['value'] = esc_html(esc_attr($args['value']));
947
948 $field_html = '<div class="space-y-4">';
949 foreach ($args['choices'] as $value => $text) {
950 $field_html .= '<div class="flex items-center">';
951 $field_id = sprintf('%s_%s', $args['id'], $value);
952 $checked = $value == $args['value'] ? 'checked="checked"' : '';
953
954 $field_html .= sprintf(
955 '<input type="radio" name="%s" id="%s" value="%s" class="%s %s" %s><label for="%s" class="ml-1 block text-sm font-medium text-gray-700">%s</label>',
956 $args['name'], $field_id, $value, $args['class'],
957 'form-radio focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300',
958 $checked, $field_id, $text
959 );
960 $field_html .= '</div>';
961 }
962 $field_html .= '</div>';
963 $field_html .= '<div class="mt-2">' . $this->generate_description($args['desc']) . '</div>';
964
965 echo $this->generate_field_wrapper($args, $field_html);
966 }
967
968 /**
969 * Generate: Checkbox field
970 */
971 public function generate_checkbox_field($args) {
972 $args['value'] = esc_attr(stripslashes($args['value']));
973 $checked = $args['value'] ? 'checked="checked"' : '';
974
975 $field_html = '<input type="hidden" name="' . $args['name'] . '" value="0" />';
976 $field_html .= '<label><input type="checkbox" name="' . $args['name'] . '" id="' . $args['id'] . '" value="1" class="' . $args['class'] . ' form-checkbox text-indigo-600" ' . $checked . '> ' . $args['desc'] . '</label>';
977
978 echo $this->generate_field_wrapper($args, $field_html);
979 }
980
981 /**
982 * Generate: Switch field
983 */
984 public function generate_switch_field($args) {
985 $args['value'] = esc_attr(stripslashes($args['value']));
986 $checked = $args['value'] ? 'checked="checked"' : '';
987
988 $field_html = '<label class="inline-flex items-center mb-1 cursor-pointer"><span class="relative">';
989 $field_html .= '<input type="hidden" name="' . $args['name'] . '" value="0" />';
990 $field_html .= '<input id="' . $args['id'] . '" type="checkbox" name="' . $args['name'] . '" value="1" class="absolute w-0 h-0 mt-6 opacity-0 kc-us-check-toggle ' . $args['class'] . '" ' . $checked . ' />';
991 $field_html .= '<span class="kc-us-mail-toggle-line"></span>';
992 $field_html .= '<span class="kc-us-mail-toggle-dot"></span>';
993 $field_html .= '</span></label>';
994
995 if ( ! empty( $args['desc'] ) ) {
996 $field_html .= '<span class="ml-3 text-sm text-gray-700">' . $args['desc'] . '</span>';
997 }
998
999 echo $this->generate_field_wrapper($args, $field_html);
1000 }
1001
1002 public function generate_time_field($args) {
1003 $args['value'] = esc_attr(stripslashes($args['value']));
1004 $timepicker = !empty($args['timepicker']) ? htmlentities(json_encode($args['timepicker'])) : null;
1005
1006 $field_html = '<input type="text" name="' . $args['name'] . '" id="' . $args['id'] . '" value="' . $args['value'] . '" class="timepicker regular-text ' . $args['class'] . '" data-timepicker="' . $timepicker . '" />';
1007 $field_html .= $this->generate_description($args['desc']);
1008
1009 echo $this->generate_field_wrapper($args, $field_html);
1010 }
1011
1012 public function generate_date_field($args) {
1013 $args['value'] = esc_attr(stripslashes($args['value']));
1014 $datepicker = !empty($args['datepicker']) ? htmlentities(json_encode($args['datepicker'])) : null;
1015
1016 $field_html = '<input type="text" name="' . $args['name'] . '" id="' . $args['id'] . '" value="' . $args['value'] . '" class="datepicker regular-text ' . $args['class'] . '" data-datepicker="' . $datepicker . '" />';
1017 $field_html .= $this->generate_description($args['desc']);
1018
1019 echo $this->generate_field_wrapper($args, $field_html);
1020 }
1021
1022 public function generate_password_field($args) {
1023 $args['value'] = esc_attr(stripslashes($args['value']));
1024
1025 $field_html = '<input type="password" name="' . $args['name'] . '" id="' . $args['id'] . '" value="' . $args['value'] . '" placeholder="' . $args['placeholder'] . '" class="regular-text ' . $args['class'] . '" />';
1026 $field_html .= $this->generate_description($args['desc']);
1027
1028 echo $this->generate_field_wrapper($args, $field_html);
1029 }
1030
1031 public function generate_textarea_field($args) {
1032 $args['value'] = esc_html(esc_attr($args['value']));
1033
1034 $field_html = '<textarea name="' . $args['name'] . '" id="' . $args['id'] . '" placeholder="' . $args['placeholder'] . '" rows="5" cols="60" class="' . $args['class'] . '">' . $args['value'] . '</textarea>';
1035 $field_html .= $this->generate_description($args['desc']);
1036
1037 echo $this->generate_field_wrapper($args, $field_html);
1038 }
1039
1040 public function generate_color_field($args) {
1041 $color_picker_id = sprintf('%s_cp', $args['id']);
1042 $args['value'] = esc_attr(stripslashes($args['value']));
1043
1044 $field_html = '<div style="position:relative;">';
1045 $field_html .= sprintf('<input type="text" name="%s" id="%s" value="%s" class="%s">', $args['name'], $args['id'], $args['value'], $args['class']);
1046 $field_html .= sprintf('<div id="%s" style="position:absolute;top:0;left:190px;background:#fff;z-index:9999;"></div>', $color_picker_id);
1047 $field_html .= $this->generate_description($args['desc']);
1048 $field_html .= '<script type="text/javascript">jQuery(document).ready(function($){$("#' . $color_picker_id . '").farbtastic("#' . $args['id'] . '");});</script>';
1049 $field_html .= '</div>';
1050
1051 echo $this->generate_field_wrapper($args, $field_html);
1052 }
1053
1054 public function generate_file_field($args) {
1055 $args['value'] = esc_attr($args['value']);
1056 $button_id = sprintf('%s_button', $args['id']);
1057
1058 $field_html = sprintf('<input type="text" name="%s" id="%s" value="%s" class="regular-text %s"> ', $args['name'], $args['id'], $args['value'], $args['class']);
1059 $field_html .= sprintf('<input type="button" class="button wpsf-browse" id="%s" value="Browse" />', $button_id);
1060 $field_html .= '<script type="text/javascript">jQuery(document).ready(function($){$("#' . $button_id . '").click(function(){tb_show("","media-upload.php?type=image&amp;TB_iframe=true");window.send_to_editor = function(html) {$("#' . $args['id'] . '").val($(html).attr("href"));tb_remove();}return false;})});</script>';
1061 $field_html .= $this->generate_description($args['desc']);
1062
1063 echo $this->generate_field_wrapper($args, $field_html);
1064 }
1065
1066 /**
1067 * Generate: Editor field.
1068 */
1069 public function generate_editor_field($args) {
1070 $field_html = '';
1071 ob_start();
1072 wp_editor($args['value'], $args['id'], ['textarea_name' => $args['name']]);
1073 $field_html .= ob_get_clean();
1074 $field_html .= $this->generate_description($args['desc']);
1075
1076 echo $this->generate_field_wrapper($args, $field_html);
1077 }
1078
1079 public function generate_custom_field($args) {
1080 $field_html = isset($args['output']) ? $args['output'] : $args['default'];
1081 echo $this->generate_field_wrapper($args, $field_html);
1082 }
1083
1084 public function generate_multiinputs_field($args) {
1085 $field_titles = array_keys($args['default']);
1086 $values = array_values($args['value']);
1087
1088 $field_html = '<div class="wpsf-multifields">';
1089 $i = 0;
1090 while ($i < count($values)) {
1091 $field_html .= '<div class="wpsf-multifields__field">';
1092 $field_html .= '<div class="wpsf-multifields__field-label">' . $field_titles[$i] . '</div>';
1093 $field_html .= '<input type="text" name="' . $args['name'] . '[]" value="' . esc_attr($values[$i]) . '" class="regular-text" />';
1094 $field_html .= '</div>';
1095 $i++;
1096 }
1097 $field_html .= '</div>';
1098 $field_html .= $this->generate_description($args['desc']);
1099
1100 echo $this->generate_field_wrapper($args, $field_html);
1101 }
1102
1103 /**
1104 * Generate Field Name.
1105 *
1106 * @param $section_id
1107 * @param $field_id
1108 *
1109 * @param $tab_id
1110 *
1111 * @return string
1112 *
1113 * @since 1.8.1
1114 *
1115 */
1116 public function generate_field_name( $tab_id, $section_id, $field_id ) {
1117 if ( empty( $tab_id ) ) {
1118 return sprintf( '%s_settings[%s][%s]', $this->option_group, $section_id, $field_id );
1119 }
1120
1121 return sprintf( '%s_settings[%s][%s][%s]', $this->option_group, $tab_id, $section_id, $field_id );
1122 }
1123
1124 /**
1125 * Get field name to get value.
1126 *
1127 * @param $section_id
1128 * @param $field_id
1129 *
1130 * @param $tab_id
1131 *
1132 * @return string
1133 *
1134 * @since 1.8.1
1135 *
1136 */
1137 public function get_field_name_to_get_value( $tab_id, $section_id, $field_id ) {
1138 if ( empty( $tab_id ) ) {
1139 return sprintf( '%s|%s', $section_id, $field_id );
1140 }
1141
1142 return sprintf( '%s|%s|%s', $tab_id, $section_id, $field_id );
1143 }
1144
1145 /**
1146 * Generate: Description
1147 *
1148 * @param mixed $description
1149 */
1150 public function generate_description( $description ) {
1151 $desc_output = '';
1152 if ( $description && $description !== "" ) {
1153 $desc_output .= '<p class="description">' . $description . '</p>';
1154 }
1155
1156 return $desc_output;
1157 }
1158
1159 public function generate_heading_field( $args ) {
1160 }
1161
1162 /**
1163 * Output the settings form
1164 */
1165 public function settings() {
1166 do_action( 'wpsf_before_settings_' . $this->option_group );
1167 ?>
1168 <form action="options.php" method="post" novalidate>
1169 <?php
1170 do_action( 'wpsf_before_settings_fields_' . $this->option_group ); ?>
1171 <?php
1172 settings_fields( $this->option_group ); ?>
1173
1174 <?php
1175 do_action( 'wpsf_do_settings_sections_' . $this->option_group ); ?>
1176
1177 <?php
1178 if ( apply_filters( 'wpsf_show_save_changes_button_' . $this->option_group, true ) ) { ?>
1179 <p class="submit">
1180 <input type="submit" class="align-middle cursor-pointer kc-uu-primary-button"
1181 value="<?php
1182 echo esc_attr( 'Save Changes' ); ?>"/>
1183 </p>
1184 <?php
1185 } ?>
1186 </form>
1187 <?php
1188 do_action( 'wpsf_after_settings_' . $this->option_group );
1189 }
1190
1191 /**
1192 * Helper: Get Settings
1193 *
1194 * @return array
1195 */
1196 public function get_settings() {
1197 $settings_name = $this->option_group . '_settings';
1198
1199 static $settings = [];
1200
1201 if ( isset( $settings[ $settings_name ] ) ) {
1202 return $settings[ $settings_name ];
1203 }
1204
1205 $saved_settings = get_option( $this->option_group . '_settings' );
1206 $settings[ $settings_name ] = [];
1207
1208 foreach ( $this->settings as $section ) {
1209 if ( empty( $section['fields'] ) ) {
1210 continue;
1211 }
1212
1213 foreach ( $section['fields'] as $field ) {
1214 if ( ! empty( $field['default'] ) && is_array( $field['default'] ) ) {
1215 $field['default'] = array_values( $field['default'] );
1216 }
1217
1218 $setting_key = $this->has_tabs() ? sprintf( '%s_%s_%s', $section['tab_id'], $section['section_id'],
1219 $field['id'] ) : sprintf( '%s_%s', $section['section_id'], $field['id'] );
1220
1221 if ( isset( $saved_settings[ $setting_key ] ) ) {
1222 $settings[ $settings_name ][ $setting_key ] = $saved_settings[ $setting_key ];
1223 } else {
1224 $settings[ $settings_name ][ $setting_key ] = ( isset( $field['default'] ) ) ? $field['default'] : false;
1225 }
1226 }
1227 }
1228
1229 return $settings[ $settings_name ];
1230 }
1231
1232 /**
1233 * Tabless Settings sections
1234 */
1235 public function do_tabless_settings_sections() {
1236 ?>
1237 <div class="wpsf-section wpsf-tabless">
1238 <?php
1239 $this->do_settings_sections( $this->option_group ); ?>
1240 </div>
1241 <?php
1242 }
1243
1244 /**
1245 * Tabbed Settings sections
1246 */
1247 public function do_tabbed_settings_sections() {
1248 $i = 0;
1249 foreach ( $this->tabs as $tab_data ) {
1250 ?>
1251 <div id="tab-<?php
1252 echo $tab_data['id']; ?>"
1253 class="wpsf-section wpsf-tab wpsf-tab--<?php
1254 echo $tab_data['id']; ?> <?php
1255 if ( $i == 0 ) {
1256 echo 'wpsf-tab--active';
1257 } ?>">
1258 <div class="postbox">
1259 <?php
1260 $this->do_settings_sections( sprintf( '%s_%s', $this->option_group, $tab_data['id'] ) ); ?>
1261 </div>
1262 </div>
1263 <?php
1264 $i ++;
1265 }
1266 }
1267
1268 /**
1269 * Output the tab links
1270 */
1271 public function tab_links() {
1272 if ( ! apply_filters( 'wpsf_show_tab_links_' . $this->option_group, true ) ) {
1273 return;
1274 }
1275
1276 do_action( 'wpsf_before_tab_links_' . $this->option_group );
1277 ?>
1278 <h2 class="nav-tab-wrapper">
1279 <?php
1280 $i = 0;
1281 foreach ( $this->tabs as $tab_data ) {
1282 $active = $i == 0 ? 'nav-tab-active' : '';
1283 ?>
1284 <a class="nav-tab wpsf-tab-link <?php
1285 echo $active; ?>"
1286 href="#tab-<?php
1287 echo $tab_data['id']; ?>"><?php
1288 echo $tab_data['title']; ?></a>
1289 <?php
1290 $i ++;
1291 }
1292 ?>
1293 </h2>
1294 <?php
1295 do_action( 'wpsf_after_tab_links_' . $this->option_group );
1296 }
1297
1298 /**
1299 * Check if this settings instance has tabs
1300 */
1301 public function has_tabs() {
1302 if ( ! empty( $this->tabs ) ) {
1303 return true;
1304 }
1305
1306 return false;
1307 }
1308
1309 /**
1310 * Prints out all settings sections added to a particular settings page
1311 *
1312 * Part of the Settings API. Use this in a settings page callback function
1313 * to output all the sections and fields that were added to that $page with
1314 * add_settings_section() and add_settings_field()
1315 *
1316 * @param string $page The slug name of the page whose settings sections you want to output.
1317 *
1318 * @since 2.7.0
1319 *
1320 * @global array $wp_settings_fields Storage array of settings fields and info about their pages/sections.
1321 * @global array $wp_settings_sections Storage array of all settings sections added to admin pages.
1322 */
1323 function do_settings_sections( $page ) {
1324 global $wp_settings_sections, $wp_settings_fields;
1325
1326 if ( ! isset( $wp_settings_sections[ $page ] ) ) {
1327 return;
1328 }
1329
1330 foreach ( (array) $wp_settings_sections[ $page ] as $section ) {
1331 if ( $section['title'] ) {
1332 echo "<h2>{$section['title']}</h2>\n";
1333 }
1334
1335 if ( $section['callback'] ) {
1336 call_user_func( $section['callback'], $section );
1337 }
1338
1339 if ( ! isset( $wp_settings_fields ) || ! isset( $wp_settings_fields[ $page ] ) || ! isset( $wp_settings_fields[ $page ][ $section['id'] ] ) ) {
1340 continue;
1341 }
1342 echo '<table class="form-table" role="presentation">';
1343 $this->do_settings_fields( $page, $section['id'] );
1344 echo '</table>';
1345 }
1346 }
1347
1348 /**
1349 * Print out the settings fields for a particular settings section.
1350 *
1351 * Part of the Settings API. Use this in a settings page to output
1352 * a specific section. Should normally be called by do_settings_sections()
1353 * rather than directly.
1354 *
1355 * @param string $section Slug title of the settings section whose fields you want to show.
1356 *
1357 * @param string $page Slug title of the admin page whose settings fields you want to show.
1358 *
1359 * @since 2.7.0
1360 *
1361 * @global array $wp_settings_fields Storage array of settings fields and their pages/sections.
1362 *
1363 */
1364 function do_settings_fields( $page, $section ) {
1365 global $wp_settings_fields;
1366
1367 if ( ! isset( $wp_settings_fields[ $page ][ $section ] ) ) {
1368 return;
1369 }
1370
1371 foreach ( (array) $wp_settings_fields[ $page ][ $section ] as $field ) {
1372 $output = '';
1373 $class = '';
1374
1375 if ( ! empty( $field['args']['class'] ) ) {
1376 $class = ' class="' . esc_attr( $field['args']['class'] ) . '"';
1377 }
1378
1379 $output .= "<tr{$class}>";
1380
1381 if ( ! empty( $field['args']['label_for'] ) ) {
1382 $html = '<th scope="row"><label for="' . esc_attr( $field['args']['label_for'] ) . '">' . $field['title'];
1383
1384 if ( ! empty( $field['args']['field']['tooltip'] ) ) {
1385 $html .= Helper::get_tooltip_html( $field['args']['field']['tooltip'] );
1386 }
1387
1388 $html .= '</label></th>';
1389 $output .= $html;
1390 } elseif ( ! empty( $field['title'] ) ) {
1391 $html = '<th scope="row">' . $field['title'];
1392
1393 if ( ! empty( $field['args']['field']['title_desc'] ) ) {
1394 $html .= "<p class='mt-1 text-sm/12 text-gray-400'>{$field['args']['field']['title_desc']}</p>";
1395 }
1396
1397 if ( ! empty( $field['args']['field']['tooltip'] ) ) {
1398 $html .= Helper::get_tooltip_html( $field['args']['field']['tooltip'] );
1399 }
1400
1401 $html .= '</th>';
1402 $output .= $html;
1403 }
1404
1405 $output .= '<td>';
1406 ob_start();
1407 call_user_func( $field['callback'], $field['args'] );
1408 $output .= ob_get_clean();
1409 $output .= '</td>';
1410 $output .= '</tr>';
1411
1412 echo $this->generate_field_wrapper( $field['args']['field'], $output );
1413 }
1414 }
1415 }
1416
1417 if ( ! function_exists( 'wpsf_get_setting' ) ) {
1418 /**
1419 * Get a setting from an option group
1420 *
1421 * @param string $option_group
1422 * @param string $section_id May also be prefixed with tab ID
1423 * @param string $field_id
1424 *
1425 * @return mixed
1426 */
1427 function wpsf_get_setting( $option_group, $section_id, $field_id ) {
1428 $options = get_option( $option_group . '_settings' );
1429 if ( isset( $options[ $section_id . '_' . $field_id ] ) ) {
1430 return $options[ $section_id . '_' . $field_id ];
1431 }
1432
1433 return false;
1434 }
1435 }
1436
1437 if ( ! function_exists( 'wpsf_delete_settings' ) ) {
1438 /**
1439 * Delete all the saved settings from a settings file/option group
1440 *
1441 * @param string $option_group
1442 */
1443 function wpsf_delete_settings( $option_group ) {
1444 delete_option( $option_group . '_settings' );
1445 }
1446 }