group_settings_fields( $fields ); // Sort fields by priority (groups & fields). $fields = $this->sort_settings_fields( $fields ); return $fields; } /** * Group settings fields. * * @param array $fields Settings fields. * @return array Processed settings fields. */ public function group_settings_fields( $fields ) { $tmp_fields = []; foreach ( $fields as $field ) { $field_group = $field['group'] ?? 'main'; if ( $field['type'] === 'heading' ) { $group_priority = $field['priority'] ?? 0; $tmp_fields[ $field_group ]['priority'] = $group_priority; $field['priority'] = -1; } $tmp_fields[ $field_group ]['fields'][] = $field; } return $tmp_fields; } /** * Sort settings fields. * * @param array $fields Settings fields. * @return array Processed settings fields. */ public function sort_settings_fields( $fields ) { // Sort groups by priority. uasort( $fields, function ( $a, $b ) { $priority_a = $a['priority'] ?? 0; $priority_b = $b['priority'] ?? 0; return $priority_a <=> $priority_b; } ); // Sort fields within each group by priority. foreach ( $fields as $group_key => $group_data ) { uasort( $group_data['fields'], function ( $a, $b ) { $priority_a = $a['priority'] ?? 0; $priority_b = $b['priority'] ?? 0; return $priority_a <=> $priority_b; } ); $fields[ $group_key ]['fields'] = $group_data['fields']; } return $fields; } /** * Render specified settings field. * * @param string $field Field type. * @param array $args Field arguments. * @param bool $should_print Whether to print the field or return as HTML string. */ public static function render_settings_field( $field, $args, $should_print = true ) { if ( empty( $field ) ) { $field = 'input'; // Default field type. subscrpt_write_debug_log( "[SettingsHelper] Field type not specified. Defaulting to 'input'." ); } switch ( $field ) { case 'heading': return self::render_heading( $args, $should_print ); case 'switch': case 'toggle': return self::render_switch_field( $args, $should_print ); case 'select': return self::render_select_field( $args, $should_print ); case 'multi_select': return self::render_multiselect_field( $args, $should_print ); case 'join': return self::render_joined_field( $args, $should_print ); case 'input': default: return self::render_input_field( $args, $should_print ); } } /** * Pro badge markup, shown beside settings that require WPSubscription Pro. * * @return string Pre-escaped badge HTML. */ public static function pro_badge_html() { return '' . esc_html__( 'Pro', 'subscription' ) . ''; } /** * Text Element HTML. * * @param array $args Same as 'render_text_field'. * @param bool $join_item Whether to return element for 'join' container or not. */ public static function inp_element( $args = [], $join_item = false ) { $id = $args['id']; $value = $args['value'] ?? ''; $placeholder = $args['placeholder'] ?? ''; $type = $args['type'] ?? 'text'; $disabled_attr = isset( $args['disabled'] ) && $args['disabled'] ? 'disabled' : ''; $style_attr = ''; if ( isset( $args['style'] ) ) { $style_attr = $args['style']; } $other_attrs_html = ''; foreach ( ( $args['attributes'] ?? [] ) as $attr_key => $attr_value ) { $other_attrs_html .= sprintf( ' %s="%s" ', esc_attr( $attr_key ), esc_attr( $attr_value ) ); } ob_start(); ?> style="" type="" placeholder="" value="" /> $opt_label ) { $adv_options[] = array( 'value' => (string) $opt_value, 'label' => $opt_label, ); } ob_start(); wpsubs_render_tag_select( array( 'name' => $id, 'value' => $args['selected'] ?? ( $multiple ? array() : '' ), 'options' => $adv_options, 'multiple' => $multiple, ) ); return ob_get_clean(); } // Regular select → wpsubs-adv-select (button-based custom dropdown). $selected = (string) ( $args['selected'] ?? '' ); $adv_options = array(); foreach ( ( $args['options'] ?? [] ) as $opt_value => $opt_label ) { $adv_options[] = array( 'value' => (string) $opt_value, 'label' => $opt_label, 'disabled' => isset( $args['disabled'] ) && ( is_array( $args['disabled'] ) ? in_array( $opt_value, $args['disabled'], true ) : $args['disabled'] === $opt_value ), ); } ob_start(); wpsubs_render_adv_select( array( 'name' => $id, 'value' => $selected, 'options' => $adv_options, 'align' => 'left', ) ); return ob_get_clean(); } /** * Render Field Heading. * * - Args: * - title (string) - Field title. * - description (string) - Field description (optional). * * @param array $args Field arguments. * @param bool $should_print Whether to print the field or return as HTML string. */ public static function render_heading( $args = [], $should_print = true ) { $title = $args['title'] ?? ''; $description = $args['description'] ?? ''; ob_start(); ?>
%s
', wp_kses_post( $description ) ); } $style_attr = ''; if ( isset( $args['style'] ) ) { $style_attr .= ' ' . $args['style']; } $other_attrs_html = ''; foreach ( ( $args['attributes'] ?? [] ) as $attr_key => $attr_value ) { $other_attrs_html .= sprintf( ' %s="%s" ', esc_attr( $attr_key ), esc_attr( $attr_value ) ); } $checked_attr = isset( $args['checked'] ) && (bool) $args['checked'] ? 'checked' : ''; $disabled_attr = isset( $args['disabled'] ) && (bool) $args['disabled'] ? 'disabled' : ''; ob_start(); ?>' . $field_hint . ': ' . __( 'Field ID is required.', 'subscription' ) . '
'; return $should_print ? print wp_kses_post( $no_id_msg ) : $no_id_msg; } // Select HTML. $select_el_html = self::select_element( $args ); ob_start(); ?>