';
}
/**
* Returns postbox footer
*
* @return void
*/
public static function postbox_footer() {
echo '
';
}
/**
* Retrieves a specific tab's content based on the provided key and tab type.
*
* @since 2.8.3
*
* This function dynamically loads content for a specified tab type (e.g., tutorials, premium services)
* based on a given configuration key. It uses a mapping to fetch the correct tab content, which is then
* wrapped in a `
` element with a `data-tab-type` attribute for identification.
*
* @param string $key The configuration key used to retrieve tab settings.
* @param string $tab_type The type of tab to retrieve (e.g., 'tutorials', 'premium-services').
*
* @return string|null The HTML content for the specified tab, or null if the tab or key is not found.
*
* Usage:
* ```
* echo wp_kses_post( Util_Ui::get_tab('example_key', 'tutorials'); // Retrieves the tutorials tab for 'example_key'
* ```
*/
public static function get_tab( string $key, string $tab_type ): ?string {
// If for any reason the key or tab type is empty, return an empty string.
if ( empty( $key ) || empty( $tab_type ) ) {
return '';
}
require_once 'ConfigSettingsTabs.php';
$configs = Config_Tab_Settings::get_config( $key );
// Define a mapping of tab types to the corresponding config keys.
$tab_mapping = array(
'help' => 'help',
'premium-services' => 'premium_support',
);
// Check if the provided tab type exists in the mapping and in the configs.
if ( isset( $tab_mapping[ $tab_type ] ) && isset( $configs['tabs'][ $tab_mapping[ $tab_type ] ] ) ) {
return '
',
$id ? 'id="' . esc_attr( $id ) . '"' : '',
$logo . wp_kses( $message, self::get_allowed_html_for_wp_kses_from_content( $message ) )
);
echo wp_kses(
$v,
self::get_allowed_html_for_wp_kses_from_content( $v )
);
}
/**
* Format bytes into B, KB, MB, GB and TB
*
* phpcs:disable Squiz.PHP.CommentedOutCode.Found
*
* @param int $bytes Bytes.
* @param int $precision Precision.
*
* @return string
*/
public static function format_bytes( $bytes, $precision = 2 ) {
$units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
$bytes = max( $bytes, 0 );
$pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
$pow = min( $pow, count( $units ) - 1 );
// Uncomment one of the following alternatives.
$bytes /= pow( 1024, $pow );
// $bytes /= ( 1 << ( 10 * $pow ) );
return round( $bytes, $precision ) . ' ' . $units[ $pow ];
}
/**
* Format mbytes into B, KB, MB, GB and TB
*
* phpcs:disable Squiz.PHP.CommentedOutCode.Found
*
* @param int $bytes Bytes.
* @param int $precision Precision.
*
* @return string
*/
public static function format_mbytes( $bytes, $precision = 2 ) {
$units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
$bytes = max( $bytes, 0 );
$pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
$pow = min( $pow, count( $units ) - 1 );
// Uncomment one of the following alternatives.
$bytes /= pow( 1024, $pow );
// $bytes /= ( 1 << ( 10 * $pow ) );
return round( $bytes, $precision ) . ' ' . $units[ $pow + 2 ];
}
/**
* Returns an hidden input text element
*
* @param string $id ID.
* @param string $name Name.
* @param string $value Value.
*
* @return string
*/
public static function r_hidden( $id, $name, $value ) {
return '';
}
/**
* Echos a hidden input text element
*
* @param string $id ID.
* @param string $name Name.
* @param string $value Value.
*
* @return void
*/
public static function hidden( $id, $name, $value ) {
$hidden = self::r_hidden( $id, $name, $value );
echo wp_kses(
$hidden,
self::get_allowed_html_for_wp_kses_from_content( $hidden )
);
}
/**
* Echos an label element
*
* @param string $id ID.
* @param string $text Text.
*
* @return void
*/
public static function label( $id, $text ) {
$label = '';
echo wp_kses(
$label,
self::get_allowed_html_for_wp_kses_from_content( $label )
);
}
/**
* Echos an input text element
*
* @param string $id ID.
* @param string $name Name.
* @param string $value Value.
* @param bool $disabled Disabled.
* @param int $size Size.
* @param string $type Type.
* @param string $placeholder Placeholder.
*
* @return void
*/
public static function textbox( $id, $name, $value, $disabled = false, $size = 40, $type = 'text', $placeholder = '' ) {
$placeholder = ! empty( $placeholder ) ? ' placeholder="' . esc_attr( $placeholder ) . '"' : '';
echo '';
}
/**
* Echos an input password element
*
* @param string $id ID.
* @param string $name Name.
* @param string $value Value.
* @param bool $disabled Diabled.
* @param int $size Size.
*
* @return void
*/
public static function passwordbox( $id, $name, $value, $disabled = false, $size = 40 ) {
echo '';
}
/**
* Echoes a select element.
*
* @param string $id The ID attribute for the select element.
* @param string $name The name attribute for the select element.
* @param string $value The selected value.
* @param array $values An array of options, where the key is the option value and the value is the label.
* @param bool $disabled Whether the select element should be disabled. Default false.
* @param array $optgroups {
* Optional. An associative array of optgroup labels.
*
* @type int|string $key The optgroup identifier.
* @type string $label The label for the optgroup.
* }
*
* @return void
*/
public static function selectbox( $id, $name, $value, $values, $disabled = false, $optgroups = null ) {
echo '';
}
/**
* Echos a select option
*
* @param string $key Key.
* @param string $selected_value Name.
* @param string $descriptor Descriptor.
*
* @return void
*/
private static function option( $key, $selected_value, $descriptor ) {
if ( ! is_array( $descriptor ) ) {
$label = $descriptor;
$disabled = false;
} else {
$label = $descriptor['label'];
$disabled = ! empty( $descriptor['disabled'] );
}
echo '' . "\n";
}
/**
* Echos a group of radio elements values: value => label pair or value => array(label, disabled, postfix).
*
* @param string $name Name.
* @param string $value Value.
* @param array $values {
* Values.
*
* @type string $label Label for the radio button.
* @type bool $disabled Whether the radio button is disabled.
* @type string $postfix Postfix to be appended to the label.
* @type bool $pro_feature Whether the radio button is a pro feature.
* @type string $pro_excerpt Excerpt for pro feature description.
* @type string $pro_description Full description for the pro feature.
* @type string $intro_label Intro label for pro feature.
* @type string $score Score associated with the pro feature.
* @type string $score_label Label for the score.
* @type string $score_description Description for the score.
* @type string $score_link Link related to the score.
* @type bool $show_learn_more Whether to show the "learn more" option for the pro feature.
* }
* @param bool $disabled Disabled flag for all radio buttons.
* @param string $separator Separator to be used between radio buttons.
*
* @return void
*/
public static function radiogroup( $name, $value, $values, $disabled = false, $separator = '' ) {
$c = Dispatcher::config();
$is_pro = Util_Environment::is_w3tc_pro( $c );
$first = true;
foreach ( $values as $key => $label_or_array ) {
if ( $first ) {
$first = false;
} else {
echo wp_kses(
$separator,
self::get_allowed_html_for_wp_kses_from_content( $separator )
);
}
$label = '';
$item_disabled = false;
$postfix = '';
$pro_feature = false;
if ( ! is_array( $label_or_array ) ) {
$label = $label_or_array;
} else {
$label = $label_or_array['label'];
$item_disabled = $label_or_array['disabled'];
$postfix = isset( $label_or_array['postfix'] ) ? $label_or_array['postfix'] : '';
$pro_feature = isset( $label_or_array['pro_feature'] ) ? $label_or_array['pro_feature'] : false;
}
if ( $pro_feature ) {
self::pro_wrap_maybe_start();
}
echo '' .
wp_kses( $postfix, self::get_allowed_html_for_wp_kses_from_content( $postfix ) ) . "\n";
if ( $pro_feature ) {
self::pro_wrap_description(
$label_or_array['pro_excerpt'],
$label_or_array['pro_description'],
$name . '__' . $key
);
if ( ! $is_pro && isset( $label_or_array['intro_label'] ) && isset( $label_or_array['score'] ) && isset( $label_or_array['score_label'] ) && isset( $label_or_array['score_description'] ) && isset( $label_or_array['score_link'] ) ) {
$score_block = self::get_score_block( $label_or_array['intro_label'], $label_or_array['score'], $label_or_array['score_label'], $label_or_array['score_description'], $label_or_array['score_link'] );
echo wp_kses( $score_block, self::get_allowed_html_for_wp_kses_from_content( $score_block ) );
}
$show_learn_more = isset( $label_or_array['show_learn_more'] ) && is_bool( $label_or_array['show_learn_more'] ) ? $label_or_array['show_learn_more'] : true;
self::pro_wrap_maybe_end( $name . '__' . $key, $show_learn_more );
}
}
}
/**
* Echos an input text element
*
* @param string $id ID.
* @param string $name Name.
* @param string $value Value.
* @param bool $disabled Disabled.
*
* @return void
*/
public static function textarea( $id, $name, $value, $disabled = false ) {
// The "textarea" element must not have padding around the value.
?>
';
}
echo '' . "\n";
echo ' ';
if ( ! is_null( $label ) ) {
echo wp_kses( $label, self::get_allowed_html_for_wp_kses_from_content( $label ) ) . '';
}
}
/**
* Echos an element
*
* @param string $type Type.
* @param string $id ID.
* @param string $name Name.
* @param mixed $value Value.
* @param bool $disabled Disabled.
*
* @return void
*/
public static function element( $type, $id, $name, $value, $disabled = false ) {
switch ( $type ) {
case 'textbox':
self::textbox( $id, $name, $value, $disabled );
break;
case 'password':
self::passwordbox( $id, $name, $value, $disabled );
break;
case 'textarea':
self::textarea( $id, $name, $value, $disabled );
break;
case 'checkbox':
default:
self::checkbox( $id, $name, $value, $disabled );
break;
}
}
/**
* Checkbox
*
* @param array $e {
* Config.
*
* @type string $name The name of the checkbox.
* @type mixed $value The value of the checkbox.
* @type bool $disabled Optional. Whether the checkbox is disabled. Defaults to false.
* @type string $label Optional. The label for the checkbox. Defaults to null.
* }
*
* @return void
*/
public static function checkbox2( $e ) {
self::checkbox(
$e['name'],
$e['name'],
$e['value'],
( isset( $e['disabled'] ) ? $e['disabled'] : false ),
( isset( $e['label'] ) ? $e['label'] : null )
);
}
/**
* Radio
*
* @param array $e {
* Config.
*
* @type string $name The name of the radio group.
* @type mixed $value The selected value.
* @type array $values Array of radio button options.
* @type bool $disabled Whether the radio group is disabled.
* @type string $separator The separator between radio buttons.
* }
*
* @return void
*/
public static function radiogroup2( $e ) {
self::radiogroup(
$e['name'],
$e['value'],
$e['values'],
$e['disabled'],
$e['separator']
);
}
/**
* Select
*
* @param array $e {
* Config.
*
* @type string $name The name of the select element.
* @type mixed $value The selected value.
* @type array $values The available options.
* @type bool $disabled Optional. Whether the select should be disabled. Default false.
* @type array|null $optgroups Optional. The optgroups for grouping options. Default null.
* }
*
* @return void
*/
public static function selectbox2( $e ) {
self::selectbox(
$e['name'],
$e['name'],
$e['value'],
$e['values'],
( isset( $e['disabled'] ) ? $e['disabled'] : false ),
( isset( $e['optgroups'] ) ? $e['optgroups'] : null )
);
}
/**
* Textbox
*
* @param array $e {
* Config.
*
* @type string $name Name of the textbox.
* @type string $value Value of the textbox.
* @type bool $disabled Whether the textbox is disabled. Default is false.
* @type int $size Size of the textbox. Default is 20.
* @type string $type Type of the textbox. Default is 'text'.
* @type string $placeholder Placeholder text for the textbox. Default is an empty string.
* }
*
* @return void
*/
public static function textbox2( $e ) {
self::textbox(
$e['name'],
$e['name'],
$e['value'],
( isset( $e['disabled'] ) ? $e['disabled'] : false ),
( ! empty( $e['size'] ) ? $e['size'] : 20 ),
( ! empty( $e['type'] ) ? $e['type'] : 'text' ),
( ! empty( $e['placeholder'] ) ? $e['placeholder'] : '' )
);
}
/**
* Textarea
*
* @param array $e {
* Config.
*
* @type string $name Name of the textarea.
* @type string $value Value of the textarea.
* @type bool $disabled Whether the textarea is disabled. Default is false.
* }
*
* @return void
*/
public static function textarea2( $e ) {
self::textarea(
$e['name'],
$e['name'],
$e['value'],
( isset( $e['disabled'] ) ? $e['disabled'] : false )
);
}
/**
* Control various types of input elements based on configuration.
*
* Handles rendering of different input controls (checkbox, radiogroup, selectbox, textbox, textarea, none, and button)
* based on the configuration provided in the input array.
*
* @param array $a {
* Configuration for the control.
*
* @type string $control The type of control to render. Possible values are 'checkbox', 'radiogroup', 'selectbox', 'textbox', 'textarea', 'none', 'button'.
* @type string $control_name The name of the control.
* @type mixed $value The value of the control.
* @type bool $disabled Whether the control is disabled.
* @type string $checkbox_label The label for the checkbox (if applicable).
* @type array $radiogroup_values The values for the radiogroup (if applicable).
* @type string $radiogroup_separator The separator for the radiogroup (if applicable).
* @type array $selectbox_values The values for the selectbox (if applicable).
* @type mixed $selectbox_optgroups The optgroups for the selectbox (if applicable).
* @type string $textbox_type The type of the textbox (if applicable).
* @type int $textbox_size The size of the textbox (if applicable).
* @type string $textbox_placeholder The placeholder text for the textbox (if applicable).
* @type string $none_label The label for 'none' or 'button' controls.
* }
*
* @return void
*/
public static function control2( $a ) {
if ( 'checkbox' === $a['control'] ) {
self::checkbox2(
array(
'name' => $a['control_name'],
'value' => $a['value'],
'disabled' => $a['disabled'],
'label' => $a['checkbox_label'],
)
);
} elseif ( 'radiogroup' === $a['control'] ) {
self::radiogroup2(
array(
'name' => $a['control_name'],
'value' => $a['value'],
'disabled' => $a['disabled'],
'values' => $a['radiogroup_values'],
'separator' => isset( $a['radiogroup_separator'] ) ? $a['radiogroup_separator'] : '',
)
);
} elseif ( 'selectbox' === $a['control'] ) {
self::selectbox2(
array(
'name' => $a['control_name'],
'value' => $a['value'],
'disabled' => $a['disabled'],
'values' => $a['selectbox_values'],
'optgroups' => isset( $a['selectbox_optgroups'] ) ? $a['selectbox_optgroups'] : null,
)
);
} elseif ( 'textbox' === $a['control'] ) {
self::textbox2(
array(
'name' => $a['control_name'],
'value' => $a['value'],
'disabled' => $a['disabled'],
'type' => isset( $a['textbox_type'] ) ? $a['textbox_type'] : null,
'size' => isset( $a['textbox_size'] ) ? $a['textbox_size'] : null,
'placeholder' => isset( $a['textbox_placeholder'] ) ? $a['textbox_placeholder'] : null,
)
);
} elseif ( 'textarea' === $a['control'] ) {
self::textarea2(
array(
'name' => $a['control_name'],
'value' => $a['value'],
'disabled' => $a['disabled'],
)
);
} elseif ( 'none' === $a['control'] ) {
echo wp_kses( $a['none_label'], self::get_allowed_html_for_wp_kses_from_content( $a['none_label'] ) );
} elseif ( 'button' === $a['control'] ) {
echo '';
}
}
/**
* Get table classes for tables including pro features.
*
* When on the free version, tables with pro features have additional classes added to help highlight
* the premium feature. If the user is on pro, this class is omitted.
*
* @since 0.14.3
*
* @return string
*/
public static function table_class() {
$table_class[] = 'form-table';
if ( ! Util_Environment::is_w3tc_pro( Dispatcher::config() ) ) {
$table_class[] = 'w3tc-pro-feature';
}
return implode( ' ', $table_class );
}
/**
* Renders
element with controls.
*
* Renders a table row with various controls, such as checkboxes, select boxes, textboxes, etc.
* The control type is determined by the keys in the `$a` array.
*
* @param array $a {
* Configuration options for rendering the controls.
*
* @type string $id The ID for the control.
* @type string $label The label for the control.
* @type string $label_class The class to apply to the label.
* @type string $style The style of the table row. Default is 'label', alternative is 'one-column'.
* @type array $checkbox The configuration for a checkbox control.
* @type string $description The description to display below the control.
* @type array $hidden The configuration for hidden inputs.
* @type string $html Raw HTML to insert.
* @type array $radiogroup The configuration for a radio group.
* @type array $selectbox The configuration for a select box.
* @type array $textbox The configuration for a textbox.
* @type array $textarea The configuration for a textarea.
* }
*
* @return void
*/
public static function table_tr( $a ) {
$id = isset( $a['id'] ) ? $a['id'] : '';
$a = apply_filters( 'w3tc_ui_settings_item', $a );
echo '
\n";
}
/**
* Prints configuration item UI based on description.
*
* @param array $a {
* Config.
*
* @type string $key Configuration key.
* @type string $label Configuration key's label as introduced to the user.
* @type mixed $value The value of the configuration item.
* @type bool $disabled If the control is disabled.
* @type string $control Type of control (checkbox, radiogroup, selectbox, textbox).
* @type string $checkbox_label Text shown after the checkbox.
* @type array $radiogroup_values Array of possible values for radiogroup.
* @type array $selectbox_values Array of possible values for dropdown.
* @type array $selectbox_optgroups Option groups for selectbox.
* @type string $textbox_size Size of the textbox.
* @type string $control_after Content to add after control.
* @type string $description Description shown to the user below the control.
* @type bool $show_in_free Whether to show the item in the free edition. Defaults to true.
* @type string $label_class CSS class for the label.
* @type string $control_name Name attribute for the control.
* @type string $intro_label Introductory label for the score block.
* @type mixed $score Score for the item.
* @type string $score_label Label for the score.
* @type string $score_description Description for the score.
* @type string $score_link Link for more information about the score.
* @type string $style CSS style for the control.
* }
*
* @return void
*/
public static function config_item( $a ) {
/*
* Some items we do not want shown in the free edition.
*
* By default, they will show in free, unless 'show_in_free' is specifically passed in as false.
*/
$is_w3tc_free = ! Util_Environment::is_w3tc_pro( Dispatcher::config() );
$show_in_free = ! isset( $a['show_in_free'] ) || (bool) $a['show_in_free'];
if ( ! $show_in_free && $is_w3tc_free ) {
return;
}
$a = self::config_item_preprocess( $a );
if ( 'w3tc_single_column' === $a['label_class'] ) {
echo '
\n";
}
/**
* Config item extension enabled.
*
* Outputs the HTML for the config item extension, including a checkbox for enabling the extension,
* and additional information such as description, score block, and pro features.
*
* @param array $a {
* Config.
*
* @type string $label_class The label class for the config item.
* @type string $control_name The control name for the config item.
* @type string $label The label for the config item.
* @type string $checkbox_label The label for the checkbox.
* @type string $extension_id The extension ID.
* @type bool $disabled Whether the checkbox should be disabled.
* @type string $description The description for the config item.
* @type string $intro_label The intro label for the score block (if applicable).
* @type int $score The score for the score block (if applicable).
* @type string $score_label The label for the score (if applicable).
* @type string $score_description The description for the score (if applicable).
* @type string $score_link The link for the score (if applicable).
* @type bool $pro Whether the config item is pro.
* @type bool $show_learn_more Whether to show the "learn more" link (if applicable).
* @type string $style Custom style for the config item (optional).
* }
*
* @return void
*/
public static function config_item_extension_enabled( $a ) {
$c = Dispatcher::config();
$is_pro = Util_Environment::is_w3tc_pro( $c );
if ( 'w3tc_single_column' === $a['label_class'] ) {
echo '
\n";
}
/**
* Config item pro.
*
* @param array $a {
* Configuration settings for the item.
*
* @type string $label_class The CSS class for the label.
* @type string $control_name The name of the control.
* @type string $label The label text for the control.
* @type string $wrap_separate Whether to wrap the description separately.
* @type string $no_wrap Whether to disable wrapping.
* @type string $control_after HTML to output after the control.
* @type string $description The description of the control.
* @type string $excerpt The excerpt text for the description.
* @type string $intro_label The intro label for the score block.
* @type string $score The score value.
* @type string $score_label The label for the score.
* @type string $score_description The description for the score.
* @type string $score_link The link associated with the score.
* @type bool $show_learn_more Whether to show the "Learn More" link.
* }
*
* @return void
*/
public static function config_item_pro( $a ) {
$c = Dispatcher::config();
$is_pro = Util_Environment::is_w3tc_pro( $c );
$a = self::config_item_preprocess( $a );
if ( 'w3tc_single_column' === $a['label_class'] ) {
echo '
\n";
}
// If wrap_separate is not set we wrap everything.
if ( ! isset( $a['wrap_separate'] ) && ! isset( $a['no_wrap'] ) ) {
self::pro_wrap_maybe_start();
}
self::control2( $a );
if ( isset( $a['control_after'] ) ) {
echo wp_kses( $a['control_after'], self::get_allowed_html_for_wp_kses_from_content( $a['control_after'] ) );
}
// If wrap_separate is set we wrap only the description.
if ( isset( $a['wrap_separate'] ) && ! isset( $a['no_wrap'] ) ) {
// If not pro we add a spacer for better separation of control element and wrapper.
if ( ! $is_pro ) {
echo '