| 1 |
<?php |
| 2 |
|
| 3 |
|
| 4 |
if (!defined('ABSPATH')) { |
| 5 |
exit; |
| 6 |
} |
| 7 |
|
| 8 |
/** |
| 9 |
* Polymorphic mbstring/preg string-operation adapter. |
| 10 |
* |
| 11 |
* Defines the small set of byte-vs-multibyte string primitives the plugin |
| 12 |
* needs across hosts with and without the PHP mbstring extension. Two |
| 13 |
* concrete implementations live alongside this base class: |
| 14 |
* |
| 15 |
* - ABJ_404_Solution_MbStringAdapterMb - uses mb_* (mbstring extension) |
| 16 |
* - ABJ_404_Solution_MbStringAdapterPreg - uses native string / preg_* fallbacks |
| 17 |
* |
| 18 |
* Choose Mb when the mbstring extension is loaded; otherwise Preg. |
| 19 |
* |
| 20 |
* Regex primitives (regexMatch, regexMatchi, regexReplace) and the |
| 21 |
* urlLooksLikeRegex URL classifier live on ABJ_404_Solution_RegexHelper |
| 22 |
* (sibling extraction, task i826). This adapter now covers only the |
| 23 |
* byte-vs-multibyte string primitives. |
| 24 |
* |
| 25 |
* Extracted from ABJ_404_Solution_Functions per design-audit-2026-06-02 |
| 26 |
* M201 / M230 (parent task i802, this task i825). Functions previously |
| 27 |
* encoded these primitives as abstract methods on the utility base class, |
| 28 |
* with FunctionsMBString and FunctionsPreg implementing them via |
| 29 |
* inheritance. That made every collaborator that wanted these primitives |
| 30 |
* depend on the kitchen-sink Functions class and forced service-locator |
| 31 |
* re-entry from within Functions itself to fetch the polymorphic subclass. |
| 32 |
* Pulling the polymorphic surface into a dedicated adapter lets new callers |
| 33 |
* depend on only what they actually need without inheriting the rest of |
| 34 |
* Functions and without re-entering the container. |
| 35 |
*/ |
| 36 |
abstract class ABJ_404_Solution_MbStringAdapter { |
| 37 |
|
| 38 |
/** |
| 39 |
* Get the codepoint value of a single character. |
| 40 |
* |
| 41 |
* @param string $char |
| 42 |
* @return int |
| 43 |
*/ |
| 44 |
abstract public function ord(string $char): int; |
| 45 |
|
| 46 |
/** |
| 47 |
* Lowercase a string, honoring multibyte characters when available. |
| 48 |
* |
| 49 |
* @param string|null $string |
| 50 |
* @return string |
| 51 |
*/ |
| 52 |
abstract public function strtolower(?string $string): string; |
| 53 |
|
| 54 |
/** |
| 55 |
* String length, in characters when mbstring is available, in bytes otherwise. |
| 56 |
* |
| 57 |
* @param string $string |
| 58 |
* @return int |
| 59 |
*/ |
| 60 |
abstract public function strlen(string $string): int; |
| 61 |
|
| 62 |
/** |
| 63 |
* Position of $needle in $haystack starting at $offset, or false if not found. |
| 64 |
* |
| 65 |
* @param string $haystack |
| 66 |
* @param string $needle |
| 67 |
* @param int $offset |
| 68 |
* @return int|false |
| 69 |
*/ |
| 70 |
abstract public function strpos(string $haystack, string $needle, int $offset = 0); |
| 71 |
|
| 72 |
/** |
| 73 |
* Slice a string. |
| 74 |
* |
| 75 |
* @param string|null $str |
| 76 |
* @param int $start |
| 77 |
* @param int|null $length |
| 78 |
* @return string |
| 79 |
*/ |
| 80 |
abstract public function substr(?string $str, int $start, ?int $length = null): string; |
| 81 |
|
| 82 |
/** |
| 83 |
* Strip invalid UTF-8 byte sequences and problematic control bytes from |
| 84 |
* a string so it is safe to pass to wpdb and to other utf8-strict |
| 85 |
* sinks. |
| 86 |
* |
| 87 |
* @param string|null $string |
| 88 |
* @return string |
| 89 |
*/ |
| 90 |
abstract public function sanitizeInvalidUTF8(?string $string): string; |
| 91 |
} |
| 92 |
|