88use StellarWP \Validation \Contracts \ValidatesOnFrontEnd ;
99use StellarWP \Validation \Contracts \ValidationRule ;
1010
11+ /**
12+ * Currency validation rule.
13+ *
14+ * Validates that a value is a valid 3-letter currency code. Supports both ISO 4217
15+ * standard currency codes and custom currency codes (like cryptocurrencies).
16+ *
17+ * Features:
18+ * - Case-insensitive validation
19+ * - Complete ISO 4217 currency code support (169 codes as of 2024)
20+ * - Support for custom currency codes
21+ * - Option to combine custom codes with ISO codes
22+ * - Includes commonly used non-ISO codes (GGP, IMP, JEP, TVD)
23+ *
24+ * @example Basic usage with default ISO codes:
25+ * $rule = new Currency();
26+ * // Validates: USD, EUR, JPY, GBP, etc.
27+ *
28+ * @example Custom codes only:
29+ * $rule = new Currency(['BTC', 'ETH', 'XRP']);
30+ * // Validates: BTC, ETH, XRP only
31+ *
32+ * @example Custom codes with ISO codes:
33+ * $rule = new Currency(['BTC', 'ETH'], true);
34+ * // Validates: BTC, ETH, USD, EUR, JPY, etc.
35+ *
36+ * @example String configuration:
37+ * $rule = Currency::fromString('BTC,ETH,XRP|include_defaults');
38+ * // Validates: BTC, ETH, XRP, USD, EUR, JPY, etc.
39+ *
40+ * @since 1.0.0
41+ */
1142class Currency implements ValidationRule, ValidatesOnFrontEnd
1243{
1344 /**
@@ -16,7 +47,36 @@ class Currency implements ValidationRule, ValidatesOnFrontEnd
1647 protected $ currencyCodes ;
1748
1849 /**
19- * @unreleased
50+ * Creates a new Currency validation rule.
51+ *
52+ * @unreleased Added $includeDefaultCurrencyCodes parameter for enhanced flexibility.
53+ *
54+ * This rule validates that a value is a valid 3-letter currency code (case-insensitive).
55+ * By default, it uses the complete list of ISO 4217 currency codes plus some commonly
56+ * used non-ISO codes like GGP, IMP, JEP, and TVD.
57+ *
58+ * @param array|null $currencyCodes Optional array of custom currency codes to validate against.
59+ * If null or empty, uses default ISO 4217 codes.
60+ * @param bool $includeDefaultCurrencyCodes Whether to merge custom codes with default ISO codes.
61+ * Only applies when $currencyCodes is provided and not empty.
62+ * Default: false (use only custom codes).
63+ *
64+ * @example
65+ * // Use default ISO 4217 codes only
66+ * $rule = new Currency();
67+ * // Validates: USD, EUR, JPY, GBP, etc.
68+ *
69+ * @example
70+ * // Use only custom currency codes
71+ * $rule = new Currency(['BTC', 'ETH', 'XRP']);
72+ * // Validates: BTC, ETH, XRP only (ISO codes will fail)
73+ *
74+ * @example
75+ * // Use custom codes AND default ISO codes
76+ * $rule = new Currency(['BTC', 'ETH', 'XRP'], true);
77+ * // Validates: BTC, ETH, XRP, USD, EUR, JPY, GBP, etc.
78+ *
79+ * @since 1.0.0
2080 */
2181 public function __construct (?array $ currencyCodes = null , bool $ includeDefaultCurrencyCodes = false )
2282 {
@@ -40,8 +100,45 @@ public static function id(): string
40100 }
41101
42102 /**
103+ * Creates a Currency validation rule from a string configuration.
104+ *
43105 * @inheritDoc
44106 *
107+ * @unreleased Enhanced to support include_defaults syntax for merging custom codes with ISO codes.
108+ *
109+ * The options string can contain:
110+ * - Empty/null: Uses default ISO 4217 currency codes
111+ * - Comma-separated codes: Uses only the specified custom codes
112+ * - Codes with "|include_defaults": Uses custom codes plus default ISO codes
113+ *
114+ * @param string|null $options Configuration string in one of these formats:
115+ * - null or empty: Use default ISO codes
116+ * - "BTC,ETH,XRP": Use only custom codes
117+ * - "BTC,ETH,XRP|include_defaults": Use custom + ISO codes
118+ *
119+ * @return ValidationRule A configured Currency validation rule instance.
120+ *
121+ * @example
122+ * // Use default ISO 4217 codes
123+ * $rule = Currency::fromString('');
124+ * $rule = Currency::fromString(null);
125+ * // Validates: USD, EUR, JPY, GBP, etc.
126+ *
127+ * @example
128+ * // Use only custom cryptocurrency codes
129+ * $rule = Currency::fromString('BTC,ETH,XRP,ADA');
130+ * // Validates: BTC, ETH, XRP, ADA only (ISO codes will fail)
131+ *
132+ * @example
133+ * // Use custom codes plus all default ISO codes
134+ * $rule = Currency::fromString('BTC,ETH,XRP|include_defaults');
135+ * // Validates: BTC, ETH, XRP, USD, EUR, JPY, GBP, etc.
136+ *
137+ * @example
138+ * // Single custom code with defaults
139+ * $rule = Currency::fromString('GOLD|include_defaults');
140+ * // Validates: GOLD, USD, EUR, JPY, GBP, etc.
141+ *
45142 * @since 1.0.0
46143 */
47144 public static function fromString (string $ options = null ): ValidationRule
@@ -68,8 +165,26 @@ public function serializeOption()
68165 }
69166
70167 /**
168+ * Validates that the given value is a valid currency code.
169+ *
71170 * @inheritDoc
72171 *
172+ * Performs case-insensitive validation against the configured currency codes.
173+ * The value must be a string and match one of the allowed currency codes.
174+ *
175+ * @param mixed $value The value to validate (should be a 3-letter currency code string).
176+ * @param Closure $fail Callback to call if validation fails.
177+ * @param string $key The field name being validated.
178+ * @param array $values All field values from the request.
179+ *
180+ * @example
181+ * // These will pass validation (case-insensitive):
182+ * // 'USD', 'usd', 'EUR', 'eur', 'JPY', 'jpy'
183+ *
184+ * @example
185+ * // These will fail validation:
186+ * // 'US', 'USDD', 'XYZ', 123, null, ''
187+ *
73188 * @since 1.0.0
74189 */
75190 public function __invoke ($ value , Closure $ fail , string $ key , array $ values )
0 commit comments