1 | <?php |
||||||
2 | |||||||
3 | /** |
||||||
4 | * Find and retrieve information about recently posted topics, messages, and the like. |
||||||
5 | * |
||||||
6 | * @package ElkArte Forum |
||||||
7 | * @copyright ElkArte Forum contributors |
||||||
8 | * @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
||||||
9 | * |
||||||
10 | * This file contains code covered by: |
||||||
11 | * copyright: 2011 Simple Machines (http://www.simplemachines.org) |
||||||
12 | * |
||||||
13 | * @version 2.0 dev |
||||||
14 | * |
||||||
15 | */ |
||||||
16 | |||||||
17 | namespace ElkArte\Controller; |
||||||
18 | |||||||
19 | use ElkArte\AbstractController; |
||||||
20 | use ElkArte\Exceptions\Exception; |
||||||
21 | |||||||
22 | /** |
||||||
23 | * Handles the finding of Unread posts and replies |
||||||
24 | */ |
||||||
25 | class Unread extends AbstractController |
||||||
26 | { |
||||||
27 | /** @var array The board ids we are marking */ |
||||||
28 | private $_boards = []; |
||||||
29 | |||||||
30 | /** @var bool */ |
||||||
31 | private $_is_topics = false; |
||||||
32 | |||||||
33 | /** @var int Number of topics */ |
||||||
34 | private $_num_topics = 0; |
||||||
35 | |||||||
36 | /** @var string The action being performed */ |
||||||
37 | private $_action = 'unread'; |
||||||
38 | |||||||
39 | /** @var bool */ |
||||||
40 | private $_action_unread = false; |
||||||
41 | |||||||
42 | /** @var bool */ |
||||||
43 | private $_action_unreadreplies = false; |
||||||
44 | |||||||
45 | /** |
||||||
46 | * The object that will retrieve the data |
||||||
47 | * |
||||||
48 | * @var Unread |
||||||
49 | */ |
||||||
50 | private $_grabber; |
||||||
51 | |||||||
52 | /** |
||||||
53 | * Called before any other action method in this class. |
||||||
54 | * |
||||||
55 | * - Allows for initializations, such as default values or |
||||||
56 | * loading templates or language files. |
||||||
57 | * |
||||||
58 | * @uses template_unread() in Recent.template.php |
||||||
59 | */ |
||||||
60 | public function pre_dispatch() |
||||||
61 | { |
||||||
62 | global $txt, $scripturl, $context, $settings, $modSettings, $options; |
||||||
63 | |||||||
64 | // Guests can't have unread things, we don't know anything about them. |
||||||
65 | is_not_guest(); |
||||||
66 | |||||||
67 | // Pre-fetching + lots of MySQL work = bad mojo. |
||||||
68 | stop_prefetching(); |
||||||
69 | |||||||
70 | require_once(SUBSDIR . '/Recent.subs.php'); |
||||||
71 | require_once(SUBSDIR . '/Boards.subs.php'); |
||||||
72 | |||||||
73 | // Determine the action, unreadreplies or unread |
||||||
74 | $this->_action = $this->_req->getQuery('action') === 'unreadreplies' ? 'unreadreplies' : 'unread'; |
||||||
75 | $this->_action_unread = $this->_action === 'unread'; |
||||||
76 | $this->_action_unreadreplies = $this->_action !== 'unread'; |
||||||
77 | |||||||
78 | // Some goodies for template use |
||||||
79 | $context['showCheckboxes'] = !empty($options['display_quick_mod']) && $settings['show_mark_read']; |
||||||
80 | $context['showing_all_topics'] = isset($this->_req->query->all); |
||||||
81 | $context['start'] = $this->_req->getQuery('start', 'intval', 0); |
||||||
82 | $context['topics_per_page'] = (int) (empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics']); |
||||||
83 | |||||||
84 | // Initialize the Unread class |
||||||
85 | $this->_grabber = new \ElkArte\Unread($this->user->id, $modSettings['postmod_active'], $modSettings['enable_unwatch'], $context['showing_all_topics']); |
||||||
86 | |||||||
87 | // Make sure we can continue |
||||||
88 | $this->_checkServerLoad(); |
||||||
89 | |||||||
90 | // Set the right page title for the action we are performing |
||||||
91 | if ($this->_action_unread) |
||||||
92 | { |
||||||
93 | $context['page_title'] = $context['showing_all_topics'] ? $txt['unread_topics_all'] : $txt['unread_topics_visit']; |
||||||
94 | } |
||||||
95 | else |
||||||
96 | { |
||||||
97 | $context['page_title'] = $txt['unread_replies']; |
||||||
98 | } |
||||||
99 | |||||||
100 | // Are we specifying any specific board? |
||||||
101 | $this->_wanted_boards(); |
||||||
102 | $this->_sorting_conditions(); |
||||||
103 | |||||||
104 | if (!empty($this->_req->query->c) && is_array($this->_req->query->c) && count($this->_req->query->c) === 1) |
||||||
105 | { |
||||||
106 | require_once(SUBSDIR . '/Categories.subs.php'); |
||||||
107 | $name = categoryName((int) $this->_req->query->c[0]); |
||||||
108 | |||||||
109 | $context['breadcrumbs'][] = [ |
||||||
110 | 'url' => getUrl('action', $modSettings['default_forum_action']) . '#c' . (int) $this->_req->query->c[0], |
||||||
111 | 'name' => $name |
||||||
112 | ]; |
||||||
113 | } |
||||||
114 | |||||||
115 | $context['breadcrumbs'][] = [ |
||||||
116 | 'url' => $scripturl . '?action=' . $this->_action . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], |
||||||
117 | 'name' => $this->_action_unread ? $txt['unread_topics_visit'] : $txt['unread_replies'] |
||||||
118 | ]; |
||||||
119 | |||||||
120 | // Prepare the template |
||||||
121 | theme()->getTemplates()->load('Recent'); |
||||||
122 | $context['sub_template'] = 'unread'; |
||||||
123 | $context['unread_header_title'] = $this->_action_unread ? ($context['showing_all_topics'] ? $txt['unread_topics_all'] : $txt['unread_topics_visit']) : $txt['unread_replies']; |
||||||
124 | $template_layers = theme()->getLayers(); |
||||||
125 | $template_layers->add($context['sub_template']); |
||||||
126 | |||||||
127 | $this->_is_topics = $this->_action_unread; |
||||||
128 | |||||||
129 | // If empty, no preview at all |
||||||
130 | if (!empty($modSettings['message_index_preview'])) |
||||||
131 | { |
||||||
132 | loadJavascriptFile('elk_toolTips.js', ['defer' => true]); |
||||||
133 | $context['message_index_preview'] = true; |
||||||
134 | |||||||
135 | // If 0 means everything |
||||||
136 | if (empty($modSettings['preview_characters'])) |
||||||
137 | { |
||||||
138 | $this->_grabber->bodyPreview(true); |
||||||
139 | } |
||||||
140 | // Default: a SUBSTRING |
||||||
141 | else |
||||||
142 | { |
||||||
143 | $this->_grabber->bodyPreview($modSettings['preview_characters']); |
||||||
144 | } |
||||||
145 | } |
||||||
146 | } |
||||||
147 | |||||||
148 | /** |
||||||
149 | * Validates the server can perform the required operation given its current loading |
||||||
150 | */ |
||||||
151 | private function _checkServerLoad() |
||||||
152 | { |
||||||
153 | global $context, $modSettings; |
||||||
154 | // Check for any server load issues |
||||||
155 | if ($context['showing_all_topics'] |
||||||
156 | && !empty($modSettings['loadavg_allunread']) |
||||||
157 | && $modSettings['current_load'] >= $modSettings['loadavg_allunread']) |
||||||
158 | { |
||||||
159 | throw new Exception('loadavg_allunread_disabled', false); |
||||||
160 | } |
||||||
161 | elseif ($this->_action_unreadreplies |
||||||
162 | && !empty($modSettings['loadavg_unreadreplies']) |
||||||
163 | && $modSettings['current_load'] >= $modSettings['loadavg_unreadreplies']) |
||||||
164 | { |
||||||
165 | throw new Exception('loadavg_unreadreplies_disabled', false); |
||||||
166 | } |
||||||
167 | elseif (!$context['showing_all_topics'] |
||||||
168 | && $this->_action_unread && !empty($modSettings['loadavg_unread']) |
||||||
169 | && $modSettings['current_load'] >= $modSettings['loadavg_unread']) |
||||||
170 | { |
||||||
171 | throw new Exception('loadavg_unread_disabled', false); |
||||||
172 | } |
||||||
173 | } |
||||||
174 | |||||||
175 | /** |
||||||
176 | * Finds out the boards the user want. |
||||||
177 | */ |
||||||
178 | private function _wanted_boards() |
||||||
179 | { |
||||||
180 | global $board, $context; |
||||||
181 | |||||||
182 | if (isset($this->_req->query->children) && (!empty($board) || !empty($this->_req->query->boards))) |
||||||
183 | { |
||||||
184 | $this->_boards = array(); |
||||||
185 | |||||||
186 | if (!empty($this->_req->query->boards)) |
||||||
187 | { |
||||||
188 | $this->_boards = array_map('intval', explode(',', $this->_req->query->boards)); |
||||||
189 | } |
||||||
190 | |||||||
191 | if (!empty($board)) |
||||||
192 | { |
||||||
193 | $this->_boards[] = (int) $board; |
||||||
194 | } |
||||||
195 | |||||||
196 | // The easiest thing is to just get all the boards they can see, |
||||||
197 | // but since we've specified the top of tree we ignore some of them |
||||||
198 | $this->_boards = addChildBoards($this->_boards); |
||||||
0 ignored issues
–
show
|
|||||||
199 | |||||||
200 | $context['querystring_board_limits'] = ';boards=' . implode(',', $this->_boards) . ';start=%d'; |
||||||
0 ignored issues
–
show
$this->_boards of type false is incompatible with the type array expected by parameter $pieces of implode() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
201 | } |
||||||
202 | elseif (!empty($board)) |
||||||
203 | { |
||||||
204 | $this->_boards = array($board); |
||||||
205 | $context['querystring_board_limits'] = ';board=' . $board . '.%1$d'; |
||||||
206 | } |
||||||
207 | elseif (!empty($this->_req->query->boards)) |
||||||
208 | { |
||||||
209 | $selected_boards = array_map('intval', explode(',', $this->_req->query->boards)); |
||||||
210 | |||||||
211 | $this->_boards = accessibleBoards($selected_boards); |
||||||
212 | |||||||
213 | $context['querystring_board_limits'] = ';boards=' . implode(',', $this->_boards) . ';start=%1$d'; |
||||||
214 | } |
||||||
215 | elseif (!empty($this->_req->query->c)) |
||||||
216 | { |
||||||
217 | $categories = array_map('intval', explode(',', $this->_req->query->c)); |
||||||
218 | |||||||
219 | $this->_boards = array_keys(boardsPosts(array(), $categories, $this->_action_unread)); |
||||||
220 | |||||||
221 | $context['querystring_board_limits'] = ';c=' . $this->_req->query->c . ';start=%1$d'; |
||||||
222 | |||||||
223 | $this->_req->query->c = explode(',', $this->_req->query->c); |
||||||
224 | } |
||||||
225 | else |
||||||
226 | { |
||||||
227 | $see_board = $this->_action_unreadreplies ? 'query_see_board' : 'query_wanna_see_board'; |
||||||
228 | |||||||
229 | // Don't bother to show deleted posts! |
||||||
230 | $this->_boards = wantedBoards($see_board); |
||||||
231 | |||||||
232 | $context['querystring_board_limits'] = ';start=%1$d'; |
||||||
233 | $context['no_board_limits'] = true; |
||||||
234 | } |
||||||
235 | |||||||
236 | if (empty($this->_boards)) |
||||||
237 | { |
||||||
238 | throw new Exception('error_no_boards_selected'); |
||||||
239 | } |
||||||
240 | |||||||
241 | $this->_grabber->setBoards($this->_boards); |
||||||
0 ignored issues
–
show
The method
setBoards() does not exist on ElkArte\Controller\Unread .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||
242 | } |
||||||
243 | |||||||
244 | /** |
||||||
245 | * Set up the array for the sorting dropdown. |
||||||
246 | */ |
||||||
247 | private function _sorting_conditions() |
||||||
248 | { |
||||||
249 | global $context, $txt, $scripturl; |
||||||
250 | |||||||
251 | $sort_methods = array( |
||||||
252 | 'subject' => 'ms.subject', |
||||||
253 | 'starter' => 'COALESCE(mems.real_name, ms.poster_name)', |
||||||
254 | 'replies' => 't.num_replies', |
||||||
255 | 'views' => 't.num_views', |
||||||
256 | 'first_post' => 't.id_topic', |
||||||
257 | 'last_post' => 't.id_last_msg' |
||||||
258 | ); |
||||||
259 | |||||||
260 | // The default is the most logical: newest first. |
||||||
261 | if (!isset($this->_req->query->sort) || !isset($sort_methods[$this->_req->query->sort])) |
||||||
262 | { |
||||||
263 | $context['sort_by'] = 'last_post'; |
||||||
264 | $ascending = isset($this->_req->query->asc); |
||||||
265 | |||||||
266 | $context['querystring_sort_limits'] = $ascending ? ';asc' : ''; |
||||||
267 | } |
||||||
268 | // But, for other methods the default sort is ascending. |
||||||
269 | else |
||||||
270 | { |
||||||
271 | $context['sort_by'] = $this->_req->query->sort; |
||||||
272 | $ascending = !isset($this->_req->query->desc); |
||||||
273 | |||||||
274 | $context['querystring_sort_limits'] = ';sort=' . $context['sort_by'] . ($ascending ? '' : ';desc'); |
||||||
275 | } |
||||||
276 | |||||||
277 | $this->_grabber->setSorting($sort_methods[$context['sort_by']], $ascending); |
||||||
0 ignored issues
–
show
The method
setSorting() does not exist on ElkArte\Controller\Unread .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||
278 | |||||||
279 | $context['sort_direction'] = $ascending ? 'up' : 'down'; |
||||||
280 | $context['sort_title'] = $ascending ? $txt['sort_desc'] : $txt['sort_asc']; |
||||||
281 | |||||||
282 | // Trick |
||||||
283 | $txt['starter'] = $txt['started_by']; |
||||||
284 | |||||||
285 | foreach (array_keys($sort_methods) as $key) |
||||||
286 | { |
||||||
287 | switch ($key) |
||||||
288 | { |
||||||
289 | case 'subject': |
||||||
290 | case 'starter': |
||||||
291 | $sorticon = 'alpha'; |
||||||
292 | break; |
||||||
293 | default: |
||||||
294 | $sorticon = 'numeric'; |
||||||
295 | } |
||||||
296 | |||||||
297 | $context['topics_headers'][$key] = array('url' => $scripturl . '?action=' . $this->_action . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $this->_req->query->start) . ';sort=' . $key . ($context['sort_by'] == $key && $context['sort_direction'] === 'up' ? ';desc' : ''), 'sort_dir_img' => $context['sort_by'] == $key ? '<i class="icon icon-small i-sort-' . $sorticon . '-' . $context['sort_direction'] . '" title="' . $context['sort_title'] . '"></i>' : '',); |
||||||
298 | } |
||||||
299 | } |
||||||
300 | |||||||
301 | /** |
||||||
302 | * Intended entry point for unread controller class. |
||||||
303 | * |
||||||
304 | * @see AbstractController::action_index |
||||||
305 | */ |
||||||
306 | public function action_index() |
||||||
307 | { |
||||||
308 | // Figure out what action to do .. Thinking, Thinking, OK unread |
||||||
309 | $this->action_unread(); |
||||||
310 | } |
||||||
311 | |||||||
312 | /** |
||||||
313 | * Find unread topics. |
||||||
314 | * |
||||||
315 | * Accessed by action=unread |
||||||
316 | */ |
||||||
317 | public function action_unread() |
||||||
318 | { |
||||||
319 | global $context, $settings; |
||||||
320 | |||||||
321 | $this->_grabber->setAction(\ElkArte\Unread::UNREAD); |
||||||
0 ignored issues
–
show
The method
setAction() does not exist on ElkArte\Controller\Unread .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||
322 | $this->_grabber->setEarliestMsg($context['showing_all_topics'] ? earliest_msg() : 0); |
||||||
0 ignored issues
–
show
The method
setEarliestMsg() does not exist on ElkArte\Controller\Unread .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||
323 | |||||||
324 | // @todo Add modified_time in for log_time check? |
||||||
325 | if ($this->_is_topics) |
||||||
326 | { |
||||||
327 | $this->_num_topics = $this->_grabber->numUnreads(empty($_SESSION['first_login']), $_SESSION['id_msg_last_visit']); |
||||||
0 ignored issues
–
show
The method
numUnreads() does not exist on ElkArte\Controller\Unread .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||
328 | $type = 'topics'; |
||||||
329 | } |
||||||
330 | // Does it make sense?... Dunno. |
||||||
331 | else |
||||||
332 | { |
||||||
333 | return $this->action_unreadreplies(); |
||||||
0 ignored issues
–
show
Are you sure the usage of
$this->action_unreadreplies() targeting ElkArte\Controller\Unread::action_unreadreplies() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||||
334 | } |
||||||
335 | |||||||
336 | if ($this->_num_topics == 0) |
||||||
337 | { |
||||||
338 | // Messages mark always, topics only if this is an all topics query |
||||||
339 | if ($type === 'message' || ($type === 'topics' && $context['showing_all_topics'])) |
||||||
340 | { |
||||||
341 | // Since there are no unread topics, mark the boards as read! |
||||||
342 | // @todo look at this... there are no more unread topics already. |
||||||
343 | // If clearing of log_topics is still needed, perhaps do it separately. |
||||||
344 | markBoardsRead($this->_boards, false, true); |
||||||
345 | } |
||||||
346 | |||||||
347 | $context['topics'] = array(); |
||||||
348 | |||||||
349 | if ($context['querystring_board_limits'] === ';start=%1$d') |
||||||
350 | { |
||||||
351 | $context['querystring_board_limits'] = ''; |
||||||
352 | } |
||||||
353 | else |
||||||
354 | { |
||||||
355 | $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $this->_req->query->start); |
||||||
356 | } |
||||||
357 | } |
||||||
358 | else |
||||||
359 | { |
||||||
360 | $context['topics'] = $this->_grabber->getUnreads($type, $this->_req->query->start, $context['topics_per_page'], $settings['avatars_on_indexes']); |
||||||
0 ignored issues
–
show
The method
getUnreads() does not exist on ElkArte\Controller\Unread .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||
361 | } |
||||||
362 | |||||||
363 | $this->_exiting_unread(); |
||||||
364 | |||||||
365 | return true; |
||||||
366 | } |
||||||
367 | |||||||
368 | /** |
||||||
369 | * Find unread replies. |
||||||
370 | * |
||||||
371 | * Accessed by action=unreadreplies |
||||||
372 | */ |
||||||
373 | public function action_unreadreplies() |
||||||
374 | { |
||||||
375 | global $scripturl, $context, $settings; |
||||||
376 | |||||||
377 | $this->_grabber->setAction(\ElkArte\Unread::UNREADREPLIES); |
||||||
378 | |||||||
379 | $this->_num_topics = $this->_grabber->numUnreads(); |
||||||
380 | |||||||
381 | if ($this->_num_topics == 0) |
||||||
382 | { |
||||||
383 | $context['topics'] = array(); |
||||||
384 | if ($context['querystring_board_limits'] === ';start=%1$d') |
||||||
385 | { |
||||||
386 | $context['querystring_board_limits'] = ''; |
||||||
387 | } |
||||||
388 | else |
||||||
389 | { |
||||||
390 | $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $this->_req->query->start); |
||||||
391 | } |
||||||
392 | } |
||||||
393 | else |
||||||
394 | { |
||||||
395 | $context['links'] += array( |
||||||
396 | 'first' => $this->_req->query->start >= $context['topics_per_page'] ? $scripturl . '?action=' . $this->_action . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', |
||||||
397 | 'last' => $this->_req->query->start + $context['topics_per_page'] < $this->_num_topics ? $scripturl . '?action=' . $this->_action . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($this->_num_topics - 1) / $context['topics_per_page']) * $context['topics_per_page']) . $context['querystring_sort_limits'] : '', |
||||||
398 | 'up' => $scripturl, |
||||||
399 | ); |
||||||
400 | $context['topics'] = $this->_grabber->getUnreads(null, $this->_req->query->start, $context['topics_per_page'], $settings['avatars_on_indexes']); |
||||||
401 | |||||||
402 | if ($context['topics'] === false) |
||||||
403 | { |
||||||
404 | $context['topics'] = array(); |
||||||
405 | |||||||
406 | if ($context['querystring_board_limits'] === ';start=%1$d') |
||||||
407 | { |
||||||
408 | $context['querystring_board_limits'] = ''; |
||||||
409 | } |
||||||
410 | else |
||||||
411 | { |
||||||
412 | $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $this->_req->query->start); |
||||||
413 | } |
||||||
414 | |||||||
415 | return; |
||||||
416 | } |
||||||
417 | } |
||||||
418 | |||||||
419 | $this->_exiting_unread(); |
||||||
420 | } |
||||||
421 | |||||||
422 | /** |
||||||
423 | * Some common things done at the end of each action. |
||||||
424 | */ |
||||||
425 | private function _exiting_unread() |
||||||
426 | { |
||||||
427 | global $scripturl, $context, $settings, $modSettings, $txt; |
||||||
428 | |||||||
429 | $topic_ids = array_keys($context['topics']); |
||||||
430 | |||||||
431 | if ($this->_is_topics && !empty($modSettings['enableParticipation']) && !empty($topic_ids)) |
||||||
432 | { |
||||||
433 | require_once(SUBSDIR . '/MessageIndex.subs.php'); |
||||||
434 | $topics_participated_in = topicsParticipation($this->user->id, $topic_ids); |
||||||
0 ignored issues
–
show
The property
id does not exist on ElkArte\Helper\ValuesContainer . Since you implemented __get , consider adding a @property annotation.
![]() |
|||||||
435 | |||||||
436 | foreach ($topics_participated_in as $topic) |
||||||
437 | { |
||||||
438 | if (empty($context['topics'][$topic['id_topic']]['is_posted_in'])) |
||||||
439 | { |
||||||
440 | $context['topics'][$topic['id_topic']]['is_posted_in'] = true; |
||||||
441 | $context['topics'][$topic['id_topic']]['class'] = 'my_' . $context['topics'][$topic['id_topic']]['class']; |
||||||
442 | } |
||||||
443 | } |
||||||
444 | } |
||||||
445 | |||||||
446 | $all = $context['showing_all_topics'] ? ';all' : ''; |
||||||
447 | |||||||
448 | // Make sure the starting place makes sense and construct the page index. |
||||||
449 | $context['page_index'] = constructPageIndex('{scripturl}?action=' . $this->_action . $all . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $this->_req->query->start, $this->_num_topics, $context['topics_per_page'], true); |
||||||
450 | $context['current_page'] = (int) $this->_req->query->start / $context['topics_per_page']; |
||||||
451 | |||||||
452 | if ($context['showing_all_topics']) |
||||||
453 | { |
||||||
454 | $context['breadcrumbs'][] = [ |
||||||
455 | 'url' => $scripturl . '?action=' . $this->_action . ';all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], |
||||||
456 | 'name' => $txt['unread_topics_all'] |
||||||
457 | ]; |
||||||
458 | |||||||
459 | $txt['unread_topics_visit_none'] = str_replace('{unread_all_url}', $scripturl . '?action=unread;all', $txt['unread_topics_visit_none']); |
||||||
460 | } |
||||||
461 | else |
||||||
462 | { |
||||||
463 | $txt['unread_topics_visit_none'] = str_replace('{unread_all_url}', $scripturl . '?action=unread;all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], $txt['unread_topics_visit_none']); |
||||||
464 | } |
||||||
465 | |||||||
466 | $context['links'] += array( |
||||||
467 | 'prev' => $this->_req->query->start >= $context['topics_per_page'] ? $scripturl . '?action=' . $this->_action . $all . sprintf($context['querystring_board_limits'], $this->_req->query->start - $context['topics_per_page']) . $context['querystring_sort_limits'] : '', |
||||||
468 | 'next' => $this->_req->query->start + $context['topics_per_page'] < $this->_num_topics ? $scripturl . '?action=' . $this->_action . $all . sprintf($context['querystring_board_limits'], $this->_req->query->start + $context['topics_per_page']) . $context['querystring_sort_limits'] : '', |
||||||
469 | ); |
||||||
470 | |||||||
471 | $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $this->_req->query->start); |
||||||
472 | $topics_to_mark = implode('-', $topic_ids); |
||||||
473 | |||||||
474 | if ($settings['show_mark_read']) |
||||||
475 | { |
||||||
476 | $context['recent_buttons'] = $this->_buttonsArray($topics_to_mark); |
||||||
477 | } |
||||||
478 | |||||||
479 | $context['querystring_board_limits'] = 'action=' . $this->_action . $all . $context['querystring_board_limits']; |
||||||
480 | |||||||
481 | // Allow help desks and bug trackers and what not to add their own unread |
||||||
482 | // data (just add a template_layer to show custom stuff in the template!) |
||||||
483 | call_integration_hook('integrate_unread_list'); |
||||||
484 | } |
||||||
485 | |||||||
486 | /** |
||||||
487 | * Build the recent button array. |
||||||
488 | * |
||||||
489 | * @param string $topics_to_mark - An array of topic ids properly formatted |
||||||
490 | * into a string to use in an URL |
||||||
491 | * |
||||||
492 | * @return array |
||||||
493 | */ |
||||||
494 | private function _buttonsArray($topics_to_mark) |
||||||
495 | { |
||||||
496 | global $context, $scripturl, $txt; |
||||||
497 | |||||||
498 | if ($this->_is_topics) |
||||||
499 | { |
||||||
500 | theme()->addJavascriptVar(array( |
||||||
501 | 'txt_mark_as_read_confirm' => $txt['mark_these_as_read_confirm'] |
||||||
502 | ), true); |
||||||
503 | |||||||
504 | $recent_buttons = array( |
||||||
505 | 'markread' => array( |
||||||
506 | 'text' => empty($context['no_board_limits']) ? 'mark_read_short' : 'mark_as_read', |
||||||
507 | 'lang' => true, |
||||||
508 | 'custom' => 'onclick="return markunreadButton(this);"', |
||||||
509 | 'url' => $scripturl . '?action=markasread;sa=' . (empty($context['no_board_limits']) ? 'board' . $context['querystring_board_limits'] : 'all') . ';' . $context['session_var'] . '=' . $context['session_id'], |
||||||
510 | ), |
||||||
511 | ); |
||||||
512 | |||||||
513 | if ($context['showCheckboxes']) |
||||||
514 | { |
||||||
515 | $recent_buttons['markselectread'] = array( |
||||||
516 | 'text' => 'quick_mod_markread', |
||||||
517 | 'lang' => true, |
||||||
518 | 'url' => 'javascript:document.quickModForm.submit();', |
||||||
519 | ); |
||||||
520 | } |
||||||
521 | |||||||
522 | if (!empty($context['topics']) && !$context['showing_all_topics']) |
||||||
523 | { |
||||||
524 | $recent_buttons['readall'] = array('text' => 'unread_topics_all', |
||||||
525 | 'lang' => true, |
||||||
526 | 'url' => $scripturl . '?action=unread;all' . $context['querystring_board_limits'], |
||||||
527 | 'active' => true); |
||||||
528 | } |
||||||
529 | } |
||||||
530 | elseif (!$this->_is_topics && isset($topics_to_mark)) |
||||||
531 | { |
||||||
532 | theme()->addJavascriptVar(array( |
||||||
533 | 'txt_mark_as_read_confirm' => $txt['mark_these_as_read_confirm'] |
||||||
534 | ), true); |
||||||
535 | |||||||
536 | $recent_buttons = array( |
||||||
537 | 'markread' => array( |
||||||
538 | 'text' => 'mark_these_as_read', |
||||||
539 | 'lang' => true, |
||||||
540 | 'url' => $scripturl . '?action=markasread;sa=unreadreplies;topics=' . $topics_to_mark . ';' . $context['session_var'] . '=' . $context['session_id'], |
||||||
541 | ), |
||||||
542 | ); |
||||||
543 | |||||||
544 | if ($context['showCheckboxes']) |
||||||
545 | { |
||||||
546 | $recent_buttons['markselectread'] = array( |
||||||
547 | 'text' => 'quick_mod_markread', |
||||||
548 | 'lang' => true, |
||||||
549 | 'url' => 'javascript:document.quickModForm.submit();', |
||||||
550 | ); |
||||||
551 | } |
||||||
552 | } |
||||||
553 | |||||||
554 | // Allow mods to add additional buttons here |
||||||
555 | call_integration_hook('integrate_recent_buttons', array(&$recent_buttons)); |
||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||
556 | |||||||
557 | return $recent_buttons; |
||||||
558 | } |
||||||
559 | } |
||||||
560 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..