ILIAS  release_8 Revision v8.24
PostingReplySubjectBuilder.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22{
23 private const EXPECTED_REPLY_PREFIX_END = ':';
28
30 private static ?array $f = null;
31
32 private string $reply_prefix;
34
40 {
41 $this->reply_prefix = trim($reply_prefix);
42 $this->optimized_repeated_reply_prefix = trim($optimized_repeated_reply_prefix);
43
44 if (self::$f === null) {
45 self::$f = [
46 'strpos' => function (string $haystack, string $needle, ?int $offset = 0) {
47 return function_exists('mb_strpos') ? mb_strpos($haystack, $needle, $offset, 'UTF-8') : strpos(
48 $haystack,
49 $needle,
50 $offset
51 );
52 },
53 'strrpos' => function (string $haystack, string $needle, ?int $offset = 0) {
54 return function_exists('mb_strrpos') ? mb_strrpos($haystack, $needle, $offset, 'UTF-8') : strrpos(
55 $haystack,
56 $needle,
57 $offset
58 );
59 },
60 'strlen' => function (string $string): int {
61 return function_exists('mb_strlen') ? mb_strlen($string, 'UTF-8') : strlen($string);
62 },
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(
65 $string,
66 $start,
67 $length
68 );
69 }
70 ];
71 }
72 }
73
74 public function build(string $subject_of_parent_posting): string
75 {
76 $subject_of_parent_posting = trim($subject_of_parent_posting);
77 $subject_of_reply = '';
78
80 if ((self::$f['substr'])(
82 -((self::$f['strlen'])(self::EXPECTED_REPLY_PREFIX_END))
83 ) !== self::EXPECTED_REPLY_PREFIX_END) {
85 }
86
88 if ((self::$f['substr'])(
90 -((self::$f['strlen'])(self::EXPECTED_REPLY_PREFIX_END))
91 ) !== self::EXPECTED_REPLY_PREFIX_END) {
93 }
94
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)
100 );
101
102 $optimized_repeated_reply_prefix_begin_pattern = preg_quote(
103 (self::$f['substr'])(
104 $optimized_repeated_reply_prefix_start,
105 0,
106 (self::$f['strrpos'])(
107 $optimized_repeated_reply_prefix_start,
108 self::EXPECTED_NUMBER_WRAPPER_CHAR_START
109 )
110 ),
111 '/'
112 );
113
114 $optimized_repeated_reply_prefix_regex = implode('', [
115 '/^',
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,
118 '/'
119 ]);
120
121 if (preg_match($optimized_repeated_reply_prefix_regex, $subject_of_parent_posting)) {
122 // i.e. $subj_of_parent_posting = "Re(12):" or "Re (12):"
124 $subject_of_parent_posting
125 );
126 } else {
127 // i.e. $subj_of_parent_posting = "Re: Re: Re: ..."
129 $subject_of_parent_posting,
132 );
133 }
134
135 return $subject_of_reply;
136 }
137
139 string $subject_of_parent_posting,
140 string $effective_reply_prefix,
141 string $effective_optimized_repeated_reply_prefix
142 ): string {
143 $subject_of_reply = $subject_of_parent_posting;
144
145 $reply_prefix_start = (self::$f['substr'])(
146 $effective_reply_prefix,
147 0,
149 );
150
151 $repeated_reply_prefix_regex = implode('', [
152 '/^',
153 '(' . preg_quote($reply_prefix_start, '/') . '\s*' . self::EXPECTED_REPLY_PREFIX_END . '\s*)+',
154 '/'
155 ]);
156
157 $matches = null;
158 preg_match($repeated_reply_prefix_regex, $subject_of_parent_posting, $matches);
159 $number_of_repetitions = isset($matches[0]) ?
160 preg_match_all(
161 '/' . preg_quote($reply_prefix_start, '/') . '\s*' . self::EXPECTED_REPLY_PREFIX_END . '\s*/',
162 $matches[0]
163 ) : 0;
164
165 if ($number_of_repetitions >= 1) {
166 // i.e. $final_subject = "Re: Re: Re: ... " -> "Re(4):"
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) {
173 // the first reply to a thread
174 $subject_of_reply = $effective_reply_prefix . ' ' . $subject_of_parent_posting;
175 }
176
177 return $subject_of_reply;
178 }
179
180 private function handleSubjectStartsWithOptimizedRepetitionReplyPattern(string $subject_of_parent_posting): string
181 {
182 $subject_of_reply = $subject_of_parent_posting;
183
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);
186
187 if ($wrapper_start_pos === false || $wrapper_end_pos === false || $wrapper_end_pos < $wrapper_start_pos) {
188 return $subject_of_reply;
189 }
190
191 $length = $wrapper_end_pos - $wrapper_start_pos;
192 $wrapper_start_pos++;
193
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,
199 0,
200 $wrapper_start_pos
201 ) . $number_of_replies . (self::$f['substr'])(
202 $subject_of_parent_posting,
203 $wrapper_end_pos
204 );
205 }
206
207 return $subject_of_reply;
208 }
209}
handleSubjectWithoutReplyPrefixOrRepeatedReplyPrefix(string $subject_of_parent_posting, string $effective_reply_prefix, string $effective_optimized_repeated_reply_prefix)
build(string $subject_of_parent_posting)
__construct(string $reply_prefix, string $optimized_repeated_reply_prefix)
handleSubjectStartsWithOptimizedRepetitionReplyPattern(string $subject_of_parent_posting)