# ebook-store/trunk/settings-General.php

Ebook Store, version trunk. 603 lines.

- Page: https://pluginprobe.com/plugins/ebook-store/trunk/code/settings-General.php
- Raw: https://pluginprobe.com/plugins/ebook-store/trunk/raw/settings-General.php
- Modified: 2026-07-20T15:04:02+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/ebook-store/trunk/code/settings-General.php#L10-L20`.

```php
<?php
/**
 * Ebook Store - "General" settings tab.
 *
 * Rendered inside the settings <form> of ebook_options.php, within a plain
 * <div class="ebook-settings-panel">. This file must therefore never emit table
 * markup; it prints <section> blocks through the shared settings-UI helpers.
 *
 * PHP 7.4 compatible.
 *
 * @package EbookStore
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

settings_fields( 'ebook-settings-group-general' );
do_settings_sections( 'ebook-settings-group-general' );

/*
 * ---------------------------------------------------------------------------
 * Saved values.
 * ---------------------------------------------------------------------------
 * $op is the QSWPOptions defaults object created by ebook_options.php. It is
 * read defensively so this tab still renders if it is ever included on its own.
 */
$default_locale        = isset( $op->ebook_store_locale ) ? (string) $op->ebook_store_locale : '';
$default_expiration    = isset( $op->link_expiration ) ? (string) $op->link_expiration : '1 year';
$default_email_flag    = isset( $op->email_delivery ) ? (string) $op->email_delivery : '';
$default_download_cap  = isset( $op->downloads_limit ) ? (string) $op->downloads_limit : '5';
$default_vat_percent   = isset( $op->vat_percent ) ? (string) $op->vat_percent : '0';
$default_form_scale    = isset( $op->form_scale ) ? (string) $op->form_scale : '1';

$license_key = function_exists( 'ebook_store_get_license_key' )
	? ebook_store_get_license_key()
	: trim( (string) get_option( 'ebook_store_license_key', '' ) );

$license_summary = function_exists( 'ebook_store_get_license_summary' )
	? ebook_store_get_license_summary()
	: array();

$license_summary = wp_parse_args(
	is_array( $license_summary ) ? $license_summary : array(),
	array(
		'label'   => __( 'Free version', 'ebook-store' ),
		'tone'    => 'muted',
		'message' => __( 'Enter your license key to unlock the Pro features.', 'ebook-store' ),
	)
);

$selected_locale        = (string) get_option( 'ebook_store_locale', $default_locale );
$link_expiration        = trim( (string) get_option( 'link_expiration', $default_expiration ) );
$link_expiration        = $link_expiration !== '' ? $link_expiration : '1 year';
$downloads_limit        = function_exists( 'ebook_store_get_download_limit' )
	? (string) ebook_store_get_download_limit()
	: (string) get_option( 'downloads_limit', $default_download_cap );
$email_delivery_enabled = (string) get_option( 'email_delivery', $default_email_flag );
$attach_files_enabled   = (string) get_option( 'attach_files', '' );
$vat_percent            = function_exists( 'ebook_store_get_vat_percent' )
	? (string) ebook_store_get_vat_percent()
	: (string) get_option( 'vat_percent', $default_vat_percent );
$current_currency       = function_exists( 'ebook_store_get_store_currency' )
	? ebook_store_get_store_currency()
	: (string) get_option( 'paypal_currency', 'USD' );
$form_scale             = trim( (string) get_option( 'form_scale', $default_form_scale ) );
$form_scale             = $form_scale !== '' ? $form_scale : '1';
$default_form_template  = function_exists( 'ebook_store_resolve_form_template' )
	? ebook_store_resolve_form_template( (string) get_option( 'ebook_store_form_template', '2026' ) )
	: (string) get_option( 'ebook_store_form_template', '2026' );

/*
 * ---------------------------------------------------------------------------
 * Option lists.
 * ---------------------------------------------------------------------------
 */
$form_templates = function_exists( 'ebook_store_get_form_templates' ) ? ebook_store_get_form_templates() : array();
$template_choices = array();
foreach ( (array) $form_templates as $template_key => $template_config ) {
	$template_choices[ $template_key ] = is_array( $template_config ) && isset( $template_config['label'] )
		? $template_config['label']
		: (string) $template_key;
}
if ( empty( $template_choices ) ) {
	$template_choices = array( '2026' => __( '2026', 'ebook-store' ) );
}

// The full label list is used here (not only installed language packs) so an
// already-saved language never disappears from the list after an update.
if ( ! isset( $languages ) || ! is_array( $languages ) || empty( $languages ) ) {
	$languages = function_exists( 'ebook_store_get_active_languages' )
		? ebook_store_get_active_languages()
		: array( 0 => __( 'Default', 'ebook-store' ) );
}

$common_currencies = array(
	'USD' => __( 'US Dollar', 'ebook-store' ),
	'EUR' => __( 'Euro', 'ebook-store' ),
	'GBP' => __( 'British Pound', 'ebook-store' ),
	'AUD' => __( 'Australian Dollar', 'ebook-store' ),
	'CAD' => __( 'Canadian Dollar', 'ebook-store' ),
	'JPY' => __( 'Japanese Yen', 'ebook-store' ),
	'NZD' => __( 'New Zealand Dollar', 'ebook-store' ),
	'CHF' => __( 'Swiss Franc', 'ebook-store' ),
	'HKD' => __( 'Hong Kong Dollar', 'ebook-store' ),
	'SGD' => __( 'Singapore Dollar', 'ebook-store' ),
	'SEK' => __( 'Swedish Krona', 'ebook-store' ),
	'DKK' => __( 'Danish Krone', 'ebook-store' ),
	'NOK' => __( 'Norwegian Krone', 'ebook-store' ),
	'MXN' => __( 'Mexican Peso', 'ebook-store' ),
	'PLN' => __( 'Polish Zloty', 'ebook-store' ),
	'BRL' => __( 'Brazilian Real', 'ebook-store' ),
);

$additional_currencies = array(
	'CZK' => __( 'Czech Koruna', 'ebook-store' ),
	'ILS' => __( 'Israeli New Sheqel', 'ebook-store' ),
	'HUF' => __( 'Hungarian Forint', 'ebook-store' ),
	'MYR' => __( 'Malaysian Ringgit', 'ebook-store' ),
	'PHP' => __( 'Philippine Peso', 'ebook-store' ),
	'TWD' => __( 'Taiwan New Dollar', 'ebook-store' ),
	'THB' => __( 'Thai Baht', 'ebook-store' ),
	'INR' => __( 'Indian Rupee', 'ebook-store' ),
	'TRY' => __( 'Turkish Lira', 'ebook-store' ),
	'ZAR' => __( 'South African Rand', 'ebook-store' ),
	'NGN' => __( 'Nigerian Naira', 'ebook-store' ),
	'RUB' => __( 'Russian Ruble', 'ebook-store' ),
	'RON' => __( 'Romanian Leu', 'ebook-store' ),
);

if ( $current_currency !== '' && ! isset( $common_currencies[ $current_currency ] ) && ! isset( $additional_currencies[ $current_currency ] ) ) {
	$additional_currencies[ $current_currency ] = $current_currency;
}

$currency_groups = array();
foreach ( $common_currencies as $code => $label ) {
	/* translators: 1: currency name, 2: three-letter currency code. */
	$currency_groups[ __( 'Common currencies', 'ebook-store' ) ][ $code ] = sprintf( __( '%1$s (%2$s)', 'ebook-store' ), $label, $code );
}
foreach ( $additional_currencies as $code => $label ) {
	/* translators: 1: currency name, 2: three-letter currency code. */
	$currency_groups[ __( 'Additional currencies', 'ebook-store' ) ][ $code ] = sprintf( __( '%1$s (%2$s)', 'ebook-store' ), $label, $code );
}

/*
 * ---------------------------------------------------------------------------
 * Live preview of the download-link expiry.
 * ---------------------------------------------------------------------------
 * The sanitiser accepts any non-empty text, and functions.php feeds the value
 * to strtotime( '+' . $value ). If that fails the comparison is made against
 * false, so every download link is treated as already expired. Showing the
 * resulting date here is the only way a shop owner can spot a typo.
 */
$expiration_expression = ltrim( $link_expiration, '+ ' );
$expiration_timestamp  = $expiration_expression !== '' ? strtotime( '+' . $expiration_expression, time() ) : false;
$expiration_is_valid   = ( is_int( $expiration_timestamp ) && $expiration_timestamp > time() );

if ( $expiration_is_valid ) {
	$expiration_note = sprintf(
		/* translators: %s: formatted date, e.g. 19 July 2027. */
		__( 'A link bought today would keep working until %s.', 'ebook-store' ),
		'<strong>' . esc_html( date_i18n( get_option( 'date_format' ), $expiration_timestamp ) ) . '</strong>'
	);
	$expiration_note_tone = 'success';
} else {
	$expiration_note = sprintf(
		/* translators: %s: the value the shop owner typed, shown in code style. */
		__( 'WordPress cannot read %s as a length of time, so every download link would be treated as already expired and buyers would see an error instead of their file. Use wording such as 1 year, 6 months, 30 days or 48 hours.', 'ebook-store' ),
		'<code>' . esc_html( $link_expiration ) . '</code>'
	);
	$expiration_note_tone = 'error';
}

/*
 * ---------------------------------------------------------------------------
 * Cross-tab links.
 * ---------------------------------------------------------------------------
 */
if ( function_exists( 'ebook_store_get_settings_tab_url' ) ) {
	$templates_tab_url = ebook_store_get_settings_tab_url( 'Templates' );
	$paypal_tab_url    = ebook_store_get_settings_tab_url( 'PayPal' );
} else {
	$templates_tab_url = admin_url( 'options-general.php?page=ebook_options.php&tab=Templates' );
	$paypal_tab_url    = admin_url( 'options-general.php?page=ebook_options.php&tab=PayPal' );
}

$license_recheck_url = wp_nonce_url(
	admin_url( 'admin-post.php?action=ebook_store_license_recheck' ),
	'ebook_store_license_recheck'
);

/*
 * ---------------------------------------------------------------------------
 * Hero.
 * ---------------------------------------------------------------------------
 */
$currency_label = isset( $common_currencies[ $current_currency ] )
	? $common_currencies[ $current_currency ]
	: ( isset( $additional_currencies[ $current_currency ] ) ? $additional_currencies[ $current_currency ] : $current_currency );

$hero_aside = function () use ( $license_summary, $email_delivery_enabled, $attach_files_enabled, $expiration_is_valid, $link_expiration, $current_currency, $currency_label, $vat_percent ) {
	$vat_number = (float) $vat_percent;
	?>
	<aside class="ebook-settings-status-card">
		<h4><?php echo esc_html__( 'How your store behaves right now', 'ebook-store' ); ?></h4>
		<ul class="ebook-settings-status-list">
			<?php
			ebook_store_status_row(
				__( 'License', 'ebook-store' ),
				$license_summary['tone'],
				$license_summary['message']
			);

			ebook_store_status_row(
				__( 'Order confirmation emails', 'ebook-store' ),
				$email_delivery_enabled === '1' ? 'ok' : 'warn',
				$email_delivery_enabled === '1'
					? ( $attach_files_enabled === '1'
						? __( 'Buyers are emailed their download links, with the ebook attached.', 'ebook-store' )
						: __( 'Buyers are emailed their download links after paying.', 'ebook-store' ) )
					: __( 'Turned off. Buyers only get their download links on the thank-you page.', 'ebook-store' )
			);

			ebook_store_status_row(
				__( 'Download links', 'ebook-store' ),
				$expiration_is_valid ? 'ok' : 'error',
				$expiration_is_valid
					? sprintf(
						/* translators: %s: a length of time, e.g. 1 year. */
						__( 'Each link stays usable for %s after the order.', 'ebook-store' ),
						$link_expiration
					)
					: __( 'The expiry wording below cannot be understood, so links stop working immediately.', 'ebook-store' )
			);

			ebook_store_status_row(
				__( 'Pricing', 'ebook-store' ),
				'ok',
				$vat_number > 0
					? sprintf(
						/* translators: 1: currency name, 2: three-letter code, 3: tax percentage. */
						__( 'Charged in %1$s (%2$s), plus %3$s%% tax at checkout.', 'ebook-store' ),
						$currency_label,
						$current_currency,
						rtrim( rtrim( number_format( $vat_number, 2, '.', '' ), '0' ), '.' )
					)
					: sprintf(
						/* translators: 1: currency name, 2: three-letter code. */
						__( 'Charged in %1$s (%2$s), with no tax added.', 'ebook-store' ),
						$currency_label,
						$current_currency
					)
			);
			?>
		</ul>
	</aside>
	<?php
};

ebook_store_render_hero(
	array(
		'eyebrow' => __( 'General settings', 'ebook-store' ),
		'title'   => __( 'The basics every store needs', 'ebook-store' ),
		'intro'   => __( 'Your license, the language buyers see, how long download links last, what happens by email after a sale, and the currency and tax you charge.', 'ebook-store' ),
		'aside'   => $hero_aside,
	)
);

ebook_store_pro_banner( __( 'The store language selector', 'ebook-store' ) );

/*
 * ---------------------------------------------------------------------------
 * Section: license.
 * ---------------------------------------------------------------------------
 */
ebook_store_section_open(
	array(
		'eyebrow' => __( 'Setup', 'ebook-store' ),
		'title'   => __( 'License & Pro features', 'ebook-store' ),
		'intro'   => __( 'A license unlocks the Pro features and keeps them working after updates. The free features on this page work either way.', 'ebook-store' ),
		'id'      => 'ebook-settings-license',
	)
);

ebook_store_split_open();
?>

<div class="ebook-settings-field"
	data-ebook-search="<?php echo esc_attr( __( 'License key or purchase email', 'ebook-store' ) . ' ' . __( 'Pro license', 'ebook-store' ) . ' ebook_store_license_key' ); ?>">
	<label for="ebook_store_license_key"><?php echo esc_html__( 'License key or purchase email', 'ebook-store' ); ?></label>
	<input
		id="ebook_store_license_key"
		class="ebook-settings-monospace-input"
		type="text"
		name="ebook_store_license_key"
		value="<?php echo esc_attr( $license_key ); ?>"
		placeholder="<?php echo esc_attr__( 'Paste your license key, or the email you paid with', 'ebook-store' ); ?>"
		autocomplete="off"
		spellcheck="false"
	/>
	<p class="description">
		<?php echo esc_html__( 'Paste the key from your receipt, or leave empty to keep running the free version.', 'ebook-store' ); ?>
	</p>
	<details class="ebook-settings-hint">
		<summary><?php echo esc_html__( 'Details', 'ebook-store' ); ?></summary>
		<div class="ebook-settings-hint__body">
			<?php echo esc_html__( 'For older purchases there is no key: use the PayPal email address the order was paid with instead. Both are accepted here, so this box does not force an email format.', 'ebook-store' ); ?>
		</div>
	</details>
</div>

<?php
ebook_store_split_aside();
?>

<ul class="ebook-settings-status-list">
	<?php
	ebook_store_status_row(
		$license_summary['label'],
		$license_summary['tone'],
		$license_summary['message']
	);
	?>
</ul>

<p class="ebook-settings-field__actions">
	<a class="button" href="<?php echo esc_url( $license_recheck_url ); ?>">
		<?php echo esc_html__( 'Check my license again', 'ebook-store' ); ?>
	</a>
</p>
<p class="description">
	<?php echo esc_html__( 'Rechecks daily on its own. Save this page before checking, or unsaved edits are lost.', 'ebook-store' ); ?>
</p>
<p class="description">
	<?php echo esc_html__( 'If the licensing server is unreachable your Pro features are never switched off — only when it explicitly rejects the key.', 'ebook-store' ); ?>
</p>

<?php
if ( isset( $_GET['ebook_license_checked'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only redirect flag.
	$checked_state = sanitize_key( wp_unslash( $_GET['ebook_license_checked'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
	if ( $checked_state === 'valid' ) {
		$checked_tone = 'is-success';
		$checked_text = __( 'Checked just now: confirmed by the licensing server. Pro features are unlocked.', 'ebook-store' );
	} elseif ( $checked_state === 'invalid' ) {
		$checked_tone = 'is-warning';
		$checked_text = __( 'Checked just now: not recognised. Check for stray spaces, or try the email you paid with, then contact support.', 'ebook-store' );
	} elseif ( $checked_state === 'empty' ) {
		$checked_tone = 'is-info';
		$checked_text = __( 'Nothing to check yet. Enter your license and save the page first.', 'ebook-store' );
	} else {
		$checked_tone = 'is-info';
		$checked_text = __( 'Checked just now: the licensing server could not be reached. Nothing is switched off and the plugin retries on its own.', 'ebook-store' );
	}
	printf(
		'<div class="ebook-settings-inline-note %1$s">%2$s</div>',
		esc_attr( $checked_tone ),
		esc_html( $checked_text )
	);
}

ebook_store_split_close();
ebook_store_section_close();

/*
 * ---------------------------------------------------------------------------
 * Card 2: Storefront & delivery.
 * ---------------------------------------------------------------------------
 * Three former sections (language / download access / order emails) merged into
 * one dense card, kept navigable by three labelled bands so no row is half-empty
 * and the wayfinding a shop owner scans for ("how long do links last?") survives.
 */
ebook_store_section_open(
	array(
		'eyebrow' => __( 'Storefront', 'ebook-store' ),
		'title'   => __( 'Storefront & delivery', 'ebook-store' ),
		'intro'   => __( 'The language buyers see, how their download links behave, and what they receive by email after paying.', 'ebook-store' ),
		'id'      => 'ebook-settings-storefront',
	)
);

ebook_store_subhead( __( 'Storefront', 'ebook-store' ) );
ebook_store_grid_open( 2 );

ebook_store_field(
	array(
		'type'    => 'select',
		'name'    => 'ebook_store_locale',
		'id'      => 'ebook_store_locale',
		'label'   => __( 'Store display language', 'ebook-store' ),
		'value'   => $selected_locale,
		'options' => $languages,
		'pro'     => true,
		'help'    => __( 'Leave on Default so the store follows your WordPress language. Pick a specific language only to pin the store while the rest of the site differs.', 'ebook-store' ),
		'hint'    => __( 'Default means the store speaks whatever language WordPress itself is set to, which is what almost every shop wants. This does not translate your own ebook titles or descriptions.', 'ebook-store' ),
	)
);

ebook_store_field(
	array(
		'type'    => 'select',
		'name'    => 'ebook_store_form_template',
		'id'      => 'ebook_store_form_template',
		'label'   => __( 'Default order form design', 'ebook-store' ),
		'value'   => $default_form_template,
		'options' => $template_choices,
		'help'    => sprintf(
			/* translators: %s: link to the Templates settings tab. */
			__( 'Used by new ebooks and by shortcodes with no design chosen. 2026 is recommended. Wording lives in the %s.', 'ebook-store' ),
			'<a href="' . esc_url( $templates_tab_url ) . '">' . esc_html__( 'Templates tab', 'ebook-store' ) . '</a>'
		),
		'hint'    => __( 'Existing ebooks keep whatever design you already picked for them; this only sets the starting point for new titles.', 'ebook-store' ),
	)
);

ebook_store_grid_close();

ebook_store_subhead( __( 'Downloads', 'ebook-store' ) );
ebook_store_grid_open( 2 );

ebook_store_field(
	array(
		'type'        => 'text',
		'name'        => 'link_expiration',
		'id'          => 'link_expiration',
		'label'       => __( 'Download links stop working after', 'ebook-store' ),
		'value'       => $link_expiration,
		'placeholder' => __( '1 year', 'ebook-store' ),
		'help'        => __( 'Counted from the order. Write a plain length of time: 1 year, 6 months, 30 days, 48 hours. Empty saves 1 year.', 'ebook-store' ),
		'note'        => $expiration_note,
		'note_tone'   => $expiration_note_tone,
	)
);

ebook_store_field(
	array(
		'type'        => 'number',
		'name'        => 'downloads_limit',
		'id'          => 'downloads_limit',
		'label'       => __( 'Downloads allowed per order', 'ebook-store' ),
		'value'       => $downloads_limit,
		'placeholder' => '5',
		'min'         => 1,
		'step'        => 1,
		'help'        => __( 'Retries for an interrupted download or a second device. Five is a sensible start; once used up the link stops working even before it expires. Empty saves 5.', 'ebook-store' ),
	)
);

ebook_store_grid_close();

ebook_store_subhead( __( 'After payment', 'ebook-store' ) );
ebook_store_toggle_grid_open();

ebook_store_toggle(
	array(
		'name'        => 'email_delivery',
		'id'          => 'email_delivery',
		'title'       => __( 'Email the order confirmation and download links', 'ebook-store' ),
		'description' => __( 'Strongly recommended. Without it, a buyer who closes the thank-you page has no way back to their files.', 'ebook-store' ),
		'checked'     => $email_delivery_enabled,
	)
);

ebook_store_toggle(
	array(
		'name'        => 'attach_files',
		'id'          => 'attach_files',
		'title'       => __( 'Also attach the ebook file to that email', 'ebook-store' ),
		'description' => __( 'Convenient for small files. Large attachments make emails slow, and many mail providers reject anything over a few megabytes.', 'ebook-store' ),
		'checked'     => $attach_files_enabled,
	)
);

ebook_store_toggle_grid_close();

ebook_store_callout(
	__( 'WordPress sends mail through your web server by default, and shop emails sent that way often land in spam. Installing an SMTP plugin and sending through a real mailbox is the single best way to make sure buyers actually receive their downloads.', 'ebook-store' ),
	'warning',
	__( 'Deliverability:', 'ebook-store' )
);

ebook_store_callout(
	sprintf(
		/* translators: %s: link to the Templates settings tab. */
		__( 'The subject line and wording of this email are edited in the %s. Attachments only go out when the confirmation email above is switched on.', 'ebook-store' ),
		'<a href="' . esc_url( $templates_tab_url ) . '">' . esc_html__( 'Templates tab', 'ebook-store' ) . '</a>'
	),
	'info',
	__( 'Where the wording lives:', 'ebook-store' )
);

ebook_store_advanced_open();

ebook_store_field(
	array(
		'type'        => 'number',
		'name'        => 'form_scale',
		'id'          => 'form_scale',
		'label'       => __( 'Order form size', 'ebook-store' ),
		'value'       => $form_scale,
		'placeholder' => '1',
		'min'         => '0.1',
		'step'        => '0.05',
		'help'        => __( 'Scales the whole order form on your site. 1 is normal, 0.8 smaller, 1.2 larger.', 'ebook-store' ),
		'hint'        => __( 'Useful when the form does not quite fit your theme\'s column width. Leave it at 1 unless you have a sizing problem.', 'ebook-store' ),
	)
);

ebook_store_advanced_close();

ebook_store_section_close();

/*
 * ---------------------------------------------------------------------------
 * Section: tax and currency.
 * ---------------------------------------------------------------------------
 */
ebook_store_section_open(
	array(
		'eyebrow' => __( 'Pricing', 'ebook-store' ),
		'title'   => __( 'Tax & currency', 'ebook-store' ),
		'intro'   => __( 'The money side: which currency buyers are charged in, and whether tax is added on top of your prices.', 'ebook-store' ),
		'id'      => 'ebook-settings-pricing',
	)
);

ebook_store_grid_open( 2 );

ebook_store_field(
	array(
		'type'        => 'number',
		'name'        => 'vat_percent',
		'id'          => 'vat_percent',
		'label'       => __( 'Tax added at checkout (%)', 'ebook-store' ),
		'value'       => $vat_percent,
		'placeholder' => '0',
		'min'         => 0,
		'step'        => '0.01',
		'help'        => __( 'Enter 0 if prices already include tax or you charge none. Enter 20 to add twenty percent at checkout. One rate only — no per-country rates. Negative values save as 0.', 'ebook-store' ),
	)
);

ebook_store_field(
	array(
		'type'      => 'select',
		'name'      => 'paypal_currency',
		'id'        => 'paypal_currency',
		'label'     => __( 'Store currency', 'ebook-store' ),
		'value'     => $current_currency,
		'optgroups' => $currency_groups,
		'help'      => __( 'Every price is charged in this currency, whichever payment method the buyer uses. A currency your provider rejects makes checkout fail, so check before switching.', 'ebook-store' ),
		'hint'      => sprintf(
			/* translators: 1: legacy option name in code style, 2: link to the PayPal settings tab. */
			__( 'For historical reasons this is stored under the name %1$s, but it is not PayPal-only. The payment methods themselves are set up in %2$s and the other gateway tabs.', 'ebook-store' ),
			'<code>paypal_currency</code>',
			'<a href="' . esc_url( $paypal_tab_url ) . '">' . esc_html__( 'the PayPal tab', 'ebook-store' ) . '</a>'
		),
	)
);

ebook_store_grid_close();

$sample_net   = 10.0;
$vat_number   = max( 0, (float) $vat_percent );
$sample_gross = $sample_net * ( 1 + $vat_number / 100 );
if ( $vat_number > 0 ) {
	$pricing_preview = sprintf(
		/* translators: 1: currency code, 2: net price, 3: gross price, 4: tax percentage. */
		__( 'Example: a %1$s %2$s book is charged as %1$s %3$s at checkout (%2$s + %4$s%% tax).', 'ebook-store' ),
		esc_html( $current_currency ),
		esc_html( number_format( $sample_net, 2 ) ),
		esc_html( number_format( $sample_gross, 2 ) ),
		esc_html( rtrim( rtrim( number_format( $vat_number, 2, '.', '' ), '0' ), '.' ) )
	);
} else {
	$pricing_preview = sprintf(
		/* translators: 1: currency code, 2: price. */
		__( 'Example: a %1$s %2$s book is charged as %1$s %2$s at checkout, with no tax added.', 'ebook-store' ),
		esc_html( $current_currency ),
		esc_html( number_format( $sample_net, 2 ) )
	);
}
printf(
	'<div class="ebook-settings-inline-note">%s</div>',
	$pricing_preview // Already escaped piecewise above.
);

ebook_store_section_close();

/*
 * ---------------------------------------------------------------------------
 * Internal flags carried through the save.
 * ---------------------------------------------------------------------------
 * ebookstorewpsc is not a shop setting: it records that the WP Super Cache
 * notice was dismissed. It is registered in this option group, and
 * wp-admin/options.php writes null over every registered option of the group
 * that the submitted form does not contain, so the dismissal would come back
 * on every save. Its current value is resubmitted unchanged instead.
 */
printf(
	'<input type="hidden" name="ebookstorewpsc" value="%s" />',
	esc_attr( (string) get_option( 'ebookstorewpsc', '' ) )
);

```
