19 declare(strict_types=1);
30 private static ?array
$f = null;
39 public function __construct(
string $reply_prefix,
string $optimized_repeated_reply_prefix)
41 $this->reply_prefix = trim($reply_prefix);
42 $this->optimized_repeated_reply_prefix = trim($optimized_repeated_reply_prefix);
46 'strpos' =>
function (
string $haystack,
string $needle, ?
int $offset = 0) {
47 return function_exists(
'mb_strpos') ? mb_strpos($haystack, $needle, $offset,
'UTF-8') : strpos(
53 'strrpos' =>
function (
string $haystack,
string $needle, ?
int $offset = 0) {
54 return function_exists(
'mb_strrpos') ? mb_strrpos($haystack, $needle, $offset,
'UTF-8') : strrpos(
60 'strlen' =>
function (
string $string):
int {
61 return function_exists(
'mb_strlen') ? mb_strlen($string,
'UTF-8') : strlen($string);
63 'substr' =>
function (
string $string,
int $start, ?
int $length = null):
string {
64 return function_exists(
'mb_substr') ? mb_substr($string, $start, $length,
'UTF-8') : substr(
74 public function build(
string $subject_of_parent_posting): string
76 $subject_of_parent_posting = trim($subject_of_parent_posting);
77 $subject_of_reply =
'';
82 -((
self::$f[
'strlen'])(self::EXPECTED_REPLY_PREFIX_END))
83 ) !== self::EXPECTED_REPLY_PREFIX_END) {
84 $reply_prefix .= self::EXPECTED_REPLY_PREFIX_END;
89 $optimized_repeated_reply_prefix,
90 -((
self::$f[
'strlen'])(self::EXPECTED_REPLY_PREFIX_END))
91 ) !== self::EXPECTED_REPLY_PREFIX_END) {
92 $optimized_repeated_reply_prefix .= self::EXPECTED_REPLY_PREFIX_END;
95 $optimized_repeated_reply_prefix_start = substr_replace(
97 self::EXPECTED_NUMBER_WRAPPER_CHAR_START,
98 (
self::$f[
'strrpos'])($reply_prefix, self::EXPECTED_REPLY_PREFIX_END),
99 (
self::$f[
'strlen'])(self::EXPECTED_REPLY_PREFIX_END)
102 $optimized_repeated_reply_prefix_begin_pattern = preg_quote(
104 $optimized_repeated_reply_prefix_start,
107 $optimized_repeated_reply_prefix_start,
108 self::EXPECTED_NUMBER_WRAPPER_CHAR_START
114 $optimized_repeated_reply_prefix_regex = implode(
'', [
116 $optimized_repeated_reply_prefix_begin_pattern,
117 '\s*?' . self::EXPECTED_NUMBER_WRAPPER_CHAR_START_PATTERN .
'\s*?\d+\s*?' . self::EXPECTED_NUMBER_WRAPPER_CHAR_END_PATTERN,
121 if (preg_match($optimized_repeated_reply_prefix_regex, $subject_of_parent_posting)) {
124 $subject_of_parent_posting
129 $subject_of_parent_posting,
131 $optimized_repeated_reply_prefix
135 return $subject_of_reply;
139 string $subject_of_parent_posting,
140 string $effective_reply_prefix,
141 string $effective_optimized_repeated_reply_prefix
143 $subject_of_reply = $subject_of_parent_posting;
145 $reply_prefix_start = (
self::$f[
'substr'])(
146 $effective_reply_prefix,
148 -(
self::$f[
'strlen'])(self::EXPECTED_REPLY_PREFIX_END)
151 $repeated_reply_prefix_regex = implode(
'', [
153 '(' . preg_quote($reply_prefix_start,
'/') .
'\s*' . self::EXPECTED_REPLY_PREFIX_END .
'\s*)+',
158 preg_match($repeated_reply_prefix_regex, $subject_of_parent_posting, $matches);
159 $number_of_repetitions = isset($matches[0]) ?
161 '/' . preg_quote($reply_prefix_start,
'/') .
'\s*' . self::EXPECTED_REPLY_PREFIX_END .
'\s*/',
165 if ($number_of_repetitions >= 1) {
167 $number_of_repetitions++;
168 $subject_of_reply = sprintf(
169 $effective_optimized_repeated_reply_prefix,
170 $number_of_repetitions
171 ) .
' ' . trim(str_replace($matches[0],
'', $subject_of_parent_posting));
172 } elseif ($number_of_repetitions === 0) {
174 $subject_of_reply = $effective_reply_prefix .
' ' . $subject_of_parent_posting;
177 return $subject_of_reply;
182 $subject_of_reply = $subject_of_parent_posting;
184 $wrapper_start_pos = (
self::$f[
'strpos'])($subject_of_parent_posting, self::EXPECTED_NUMBER_WRAPPER_CHAR_START);
185 $wrapper_end_pos = (
self::$f[
'strpos'])($subject_of_parent_posting, self::EXPECTED_NUMBER_WRAPPER_CHAR_END);
187 if ($wrapper_start_pos ===
false || $wrapper_end_pos ===
false || $wrapper_end_pos < $wrapper_start_pos) {
188 return $subject_of_reply;
191 $length = $wrapper_end_pos - $wrapper_start_pos;
192 $wrapper_start_pos++;
194 $txt_num_replies = (
self::$f[
'substr'])($subject_of_parent_posting, $wrapper_start_pos, $length - 1);
195 if (is_numeric($txt_num_replies) && $txt_num_replies > 0) {
196 $number_of_replies = ((
int) trim($txt_num_replies)) + 1;
197 $subject_of_reply = (
self::$f[
'substr'])(
198 $subject_of_parent_posting,
201 ) . $number_of_replies . (
self::$f[
'substr'])(
202 $subject_of_parent_posting,
207 return $subject_of_reply;
const EXPECTED_NUMBER_WRAPPER_CHAR_END_PATTERN
const EXPECTED_REPLY_PREFIX_END
__construct(string $reply_prefix, string $optimized_repeated_reply_prefix)
handleSubjectWithoutReplyPrefixOrRepeatedReplyPrefix(string $subject_of_parent_posting, string $effective_reply_prefix, string $effective_optimized_repeated_reply_prefix)
build(string $subject_of_parent_posting)
string $optimized_repeated_reply_prefix
const EXPECTED_NUMBER_WRAPPER_CHAR_END
const EXPECTED_NUMBER_WRAPPER_CHAR_START_PATTERN
handleSubjectStartsWithOptimizedRepetitionReplyPattern(string $subject_of_parent_posting)
const EXPECTED_NUMBER_WRAPPER_CHAR_START