19declare(strict_types=1);
32 private static ?array
$f =
null;
48 'strpos' =>
function (
string $haystack,
string $needle, ?
int $offset = 0) {
49 return function_exists(
'mb_strpos') ? mb_strpos($haystack, $needle, $offset,
'UTF-8') : strpos(
55 'strrpos' =>
function (
string $haystack,
string $needle, ?
int $offset = 0) {
56 return function_exists(
'mb_strrpos') ? mb_strrpos($haystack, $needle, $offset,
'UTF-8') : strrpos(
62 'strlen' =>
function (
string $string):
int {
63 return function_exists(
'mb_strlen') ? mb_strlen($string,
'UTF-8') : strlen($string);
65 'substr' =>
function (
string $string,
int $start, ?
int $length =
null):
string {
66 return function_exists(
'mb_substr') ? mb_substr($string, $start, $length,
'UTF-8') : substr(
76 public function build(
string $subject_of_parent_posting): string
78 $subject_of_parent_posting = trim($subject_of_parent_posting);
79 $subject_of_reply =
'';
84 -((
self::$f[
'strlen'])(self::EXPECTED_REPLY_PREFIX_END))
85 ) !== self::EXPECTED_REPLY_PREFIX_END) {
92 -((
self::$f[
'strlen'])(self::EXPECTED_REPLY_PREFIX_END))
93 ) !== self::EXPECTED_REPLY_PREFIX_END) {
97 $optimized_repeated_reply_prefix_start = substr_replace(
99 self::EXPECTED_NUMBER_WRAPPER_CHAR_START,
101 (
self::$f[
'strlen'])(self::EXPECTED_REPLY_PREFIX_END)
104 $optimized_repeated_reply_prefix_begin_pattern = preg_quote(
106 $optimized_repeated_reply_prefix_start,
109 $optimized_repeated_reply_prefix_start,
110 self::EXPECTED_NUMBER_WRAPPER_CHAR_START
116 $optimized_repeated_reply_prefix_regex = implode(
'', [
118 $optimized_repeated_reply_prefix_begin_pattern,
119 '\s*?' . self::EXPECTED_NUMBER_WRAPPER_CHAR_START_PATTERN .
'\s*?\d+\s*?' . self::EXPECTED_NUMBER_WRAPPER_CHAR_END_PATTERN,
123 if (preg_match($optimized_repeated_reply_prefix_regex, $subject_of_parent_posting)) {
126 $subject_of_parent_posting
131 $subject_of_parent_posting,
137 return $subject_of_reply;
141 string $subject_of_parent_posting,
142 string $effective_reply_prefix,
143 string $effective_optimized_repeated_reply_prefix
145 $subject_of_reply = $subject_of_parent_posting;
147 $reply_prefix_start = (
self::$f[
'substr'])(
148 $effective_reply_prefix,
153 $repeated_reply_prefix_regex = implode(
'', [
155 '(' . preg_quote($reply_prefix_start,
'/') .
'\s*' . self::EXPECTED_REPLY_PREFIX_END .
'\s*)+',
160 preg_match($repeated_reply_prefix_regex, $subject_of_parent_posting, $matches);
161 $number_of_repetitions = isset($matches[0]) ?
163 '/' . preg_quote($reply_prefix_start,
'/') .
'\s*' . self::EXPECTED_REPLY_PREFIX_END .
'\s*/',
167 if ($number_of_repetitions >= 1) {
169 $number_of_repetitions++;
170 $subject_of_reply = sprintf(
171 $effective_optimized_repeated_reply_prefix,
172 $number_of_repetitions
173 ) .
' ' . trim(str_replace($matches[0],
'', $subject_of_parent_posting));
174 } elseif ($number_of_repetitions === 0) {
176 $subject_of_reply = $effective_reply_prefix .
' ' . $subject_of_parent_posting;
179 return $subject_of_reply;
184 $subject_of_reply = $subject_of_parent_posting;
186 $wrapper_start_pos = (
self::$f[
'strpos'])($subject_of_parent_posting, self::EXPECTED_NUMBER_WRAPPER_CHAR_START);
187 $wrapper_end_pos = (
self::$f[
'strpos'])($subject_of_parent_posting, self::EXPECTED_NUMBER_WRAPPER_CHAR_END);
189 if ($wrapper_start_pos ===
false || $wrapper_end_pos ===
false || $wrapper_end_pos < $wrapper_start_pos) {
190 return $subject_of_reply;
193 $length = $wrapper_end_pos - $wrapper_start_pos;
194 $wrapper_start_pos++;
196 $txt_num_replies = (
self::$f[
'substr'])($subject_of_parent_posting, $wrapper_start_pos, $length - 1);
197 if (is_numeric($txt_num_replies) && $txt_num_replies > 0) {
198 $number_of_replies = ((
int) trim($txt_num_replies)) + 1;
199 $subject_of_reply = (
self::$f[
'substr'])(
200 $subject_of_parent_posting,
203 ) . $number_of_replies . (
self::$f[
'substr'])(
204 $subject_of_parent_posting,
209 return $subject_of_reply;
__construct(string $reply_prefix, string $optimized_repeated_reply_prefix)
const string EXPECTED_NUMBER_WRAPPER_CHAR_START_PATTERN
build(string $subject_of_parent_posting)
handleSubjectStartsWithOptimizedRepetitionReplyPattern(string $subject_of_parent_posting)
const string EXPECTED_NUMBER_WRAPPER_CHAR_END_PATTERN
handleSubjectWithoutReplyPrefixOrRepeatedReplyPrefix(string $subject_of_parent_posting, string $effective_reply_prefix, string $effective_optimized_repeated_reply_prefix)
const string EXPECTED_REPLY_PREFIX_END
const string EXPECTED_NUMBER_WRAPPER_CHAR_START
const string EXPECTED_NUMBER_WRAPPER_CHAR_END
readonly string $optimized_repeated_reply_prefix
readonly string $reply_prefix