| @@ -1,6 +1,11 @@ | ||
| 1 | 1 | <?php |
| 2 | -if ( ! defined( 'ABSPATH' ) && PHP_SAPI !== 'cli' ) { exit; } | |
| 2 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 3 | + // Composer autoloads this file, so CLI tooling loads it without WordPress. | |
| 4 | + if ( PHP_SAPI !== 'cli' ) { | |
| 5 | + exit; | |
| 6 | + } | |
| 7 | +} | |
| 3 | 8 | /** |
| 4 | 9 | * Get timezone list. |
| 5 | 10 | * |
| 6 | 11 | * @return array |
| @@ -788,8 +793,26 @@ | ||
| 788 | 793 | } |
| 789 | 794 | } |
| 790 | 795 | } |
| 791 | 796 | |
| 797 | +if ( ! function_exists( 'booktics_log' ) ) { | |
| 798 | + /** | |
| 799 | + * Write a debug line, but only when the site has debug logging switched on. | |
| 800 | + * | |
| 801 | + * @param string $message Message to log. | |
| 802 | + * | |
| 803 | + * @return void | |
| 804 | + */ | |
| 805 | + function booktics_log( $message ) { | |
| 806 | + if ( ! defined( 'WP_DEBUG_LOG' ) || ! WP_DEBUG_LOG ) { | |
| 807 | + return; | |
| 808 | + } | |
| 809 | + | |
| 810 | + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Guarded above; this is the plugin's only debug sink. | |
| 811 | + error_log( 'Booktics: ' . $message ); | |
| 812 | + } | |
| 813 | +} | |
| 814 | + | |
| 792 | 815 | if ( ! function_exists( 'booktics_get_multisite_table_name' ) ) { |
| 793 | 816 | /** |
| 794 | 817 | * Get multisite-safe table name |
| 795 | 818 | * |
| @@ -1068,6 +1091,64 @@ | ||
| 1068 | 1091 | |
| 1069 | 1092 | $settings = get_option( 'aisentic_settings', array() ); |
| 1070 | 1093 | |
| 1071 | 1094 | return ! empty( $settings['llmProviders']['aisentic']['apiKey'] ); |
| 1095 | + } | |
| 1096 | +} | |
| 1097 | + | |
| 1098 | +if ( ! function_exists( 'booktics_get_store_currency' ) ) { | |
| 1099 | + /** | |
| 1100 | + * The currency the merchant configured for the store, lowercased. | |
| 1101 | + * | |
| 1102 | + * Public checkout must always price in this currency. A currency sent by the | |
| 1103 | + * buyer cannot be trusted: the total is computed server side in the store | |
| 1104 | + * currency, so relabeling it as another currency changes what is charged. | |
| 1105 | + * | |
| 1106 | + * @return string Lowercase ISO 4217 currency code. | |
| 1107 | + */ | |
| 1108 | + function booktics_get_store_currency(): string { | |
| 1109 | + $currency = strtolower( trim( (string) booktics_get_option( 'currency', 'USD' ) ) ); | |
| 1110 | + | |
| 1111 | + // An empty or malformed setting would make every Stripe charge fail. | |
| 1112 | + return preg_match( '/^[a-z]{3}$/', $currency ) ? $currency : 'usd'; | |
| 1113 | + } | |
| 1114 | +} | |
| 1115 | + | |
| 1116 | +if ( ! function_exists( 'booktics_amount_to_minor_units' ) ) { | |
| 1117 | + /** | |
| 1118 | + * Convert a decimal amount to the smallest unit of a currency. | |
| 1119 | + * | |
| 1120 | + * Stripe takes amounts in minor units, and not every currency has two | |
| 1121 | + * decimals: 100 JPY is sent as 100, 100 USD as 10000 and 100 KWD as 100000. | |
| 1122 | + * ISK and UGX are zero-decimal but Stripe still expects them as whole | |
| 1123 | + * amounts times 100, so 5 UGX is sent as 500. | |
| 1124 | + * | |
| 1125 | + * @see https://docs.stripe.com/currencies#minor-units | |
| 1126 | + * | |
| 1127 | + * @param float|int|string $amount Amount in major units, e.g. 19.99. | |
| 1128 | + * @param string $currency ISO 4217 currency code. | |
| 1129 | + * | |
| 1130 | + * @return int Amount in minor units. | |
| 1131 | + */ | |
| 1132 | + function booktics_amount_to_minor_units( $amount, string $currency ): int { | |
| 1133 | + $zero_decimal = array( 'bif', 'clp', 'djf', 'gnf', 'jpy', 'kmf', 'krw', 'mga', 'pyg', 'rwf', 'vnd', 'vuv', 'xaf', 'xof', 'xpf' ); | |
| 1134 | + $whole_x100 = array( 'isk', 'ugx' ); | |
| 1135 | + $three_decimal = array( 'bhd', 'jod', 'kwd', 'omr', 'tnd' ); | |
| 1136 | + $currency = strtolower( $currency ); | |
| 1137 | + $amount = (float) $amount; | |
| 1138 | + | |
| 1139 | + if ( in_array( $currency, $zero_decimal, true ) ) { | |
| 1140 | + return (int) round( $amount ); | |
| 1141 | + } | |
| 1142 | + | |
| 1143 | + if ( in_array( $currency, $whole_x100, true ) ) { | |
| 1144 | + return (int) round( $amount ) * 100; | |
| 1145 | + } | |
| 1146 | + | |
| 1147 | + if ( in_array( $currency, $three_decimal, true ) ) { | |
| 1148 | + // Stripe requires the last digit of three-decimal amounts to be 0. | |
| 1149 | + return (int) ( round( $amount * 100 ) * 10 ); | |
| 1150 | + } | |
| 1151 | + | |
| 1152 | + return (int) round( $amount * 100 ); | |
| 1072 | 1153 | } |
| 1073 | 1154 | } |