1 | <?php |
||
2 | |||
3 | /** |
||
4 | * This file takes care of actions on topics including |
||
5 | * - lock/unlock a topic, |
||
6 | * - sticky (pin) /unsticky (unpin) it |
||
7 | * - printing |
||
8 | * |
||
9 | * @package ElkArte Forum |
||
10 | * @copyright ElkArte Forum contributors |
||
11 | * @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
||
12 | * |
||
13 | * This file contains code covered by: |
||
14 | * copyright: 2011 Simple Machines (http://www.simplemachines.org) |
||
15 | * |
||
16 | * @version 2.0 dev |
||
17 | * |
||
18 | */ |
||
19 | |||
20 | namespace ElkArte\Controller; |
||
21 | |||
22 | use ElkArte\AbstractController; |
||
23 | use ElkArte\Exceptions\Exception; |
||
24 | use ElkArte\Languages\Txt; |
||
25 | |||
26 | /** |
||
27 | * Handles various topic actions, lock/unlock, sticky (pin) /unsticky (unpin), printing |
||
28 | */ |
||
29 | class Topic extends AbstractController |
||
30 | { |
||
31 | /** |
||
32 | * Entry point for this class (by default). |
||
33 | * |
||
34 | * @see AbstractController::action_index |
||
35 | */ |
||
36 | public function action_index() |
||
37 | { |
||
38 | global $topic; |
||
39 | |||
40 | // Call the right method, if it is not done yet. |
||
41 | // |
||
42 | // This is done by the dispatcher, so lets leave it alone... |
||
43 | // We don't want to assume what it means if the user doesn't |
||
44 | // send us a ?sa=, do we? (lock topics out of nowhere?) |
||
45 | // Unless... we can printpage() |
||
46 | |||
47 | // Without anything it throws an error, so redirect somewhere |
||
48 | if (!empty($topic)) |
||
49 | { |
||
50 | redirectexit('topic=' . $topic . '.0'); |
||
51 | } |
||
52 | else |
||
53 | { |
||
54 | redirectexit(); |
||
55 | } |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * Locks a topic... either by way of a moderator or the topic starter. |
||
60 | * |
||
61 | * What this does: |
||
62 | * - Locks a topic, toggles between locked/unlocked/admin locked. |
||
63 | * - Only admins can unlock topics locked by other admins. |
||
64 | * - Requires the lock_own or lock_any permission. |
||
65 | * - Logs the action to the moderator log. |
||
66 | * - Returns to the topic after it is done. |
||
67 | * - It is accessed via ?action=topic;sa=lock. |
||
68 | */ |
||
69 | public function action_lock() |
||
70 | { |
||
71 | global $topic, $board; |
||
72 | |||
73 | // Just quit if there's no topic to lock. |
||
74 | if (empty($topic)) |
||
75 | { |
||
76 | throw new Exception('not_a_topic', false); |
||
77 | } |
||
78 | |||
79 | checkSession('get'); |
||
80 | |||
81 | // Load up the helpers |
||
82 | require_once(SUBSDIR . '/Notification.subs.php'); |
||
83 | require_once(SUBSDIR . '/Topic.subs.php'); |
||
84 | |||
85 | // Find out who started the topic and its current lock status |
||
86 | [$starter, $locked] = topicStatus($topic); |
||
87 | |||
88 | // Can you lock topics here, mister? |
||
89 | $user_lock = !allowedTo('lock_any'); |
||
90 | |||
91 | if ($user_lock && $starter == $this->user->id) |
||
92 | { |
||
93 | isAllowedTo('lock_own'); |
||
94 | } |
||
95 | else |
||
96 | { |
||
97 | isAllowedTo('lock_any'); |
||
98 | } |
||
99 | |||
100 | // Locking with high privileges. |
||
101 | if ($locked == '0' && !$user_lock) |
||
102 | { |
||
103 | $locked = '1'; |
||
104 | } |
||
105 | // Locking with low privileges. |
||
106 | elseif ($locked == '0') |
||
107 | { |
||
108 | $locked = '2'; |
||
109 | } |
||
110 | // Unlocking - make sure you don't unlock what you can't. |
||
111 | elseif ($locked == '2' || ($locked == '1' && !$user_lock)) |
||
112 | { |
||
113 | $locked = '0'; |
||
114 | } |
||
115 | // You cannot unlock this! |
||
116 | else |
||
117 | { |
||
118 | throw new Exception('locked_by_admin', 'user'); |
||
119 | } |
||
120 | |||
121 | // Lock the topic! |
||
122 | setTopicAttribute($topic, array('locked' => $locked)); |
||
123 | |||
124 | // If they are allowed a "moderator" permission, log it in the moderator log. |
||
125 | if (!$user_lock) |
||
126 | { |
||
127 | logAction($locked !== '' ? 'lock' : 'unlock', array('topic' => $topic, 'board' => $board)); |
||
128 | } |
||
129 | |||
130 | // Notify people that this topic has been locked? |
||
131 | sendNotifications($topic, empty($locked) ? 'unlock' : 'lock'); |
||
132 | |||
133 | // Back to the topic! |
||
134 | redirectexit('topic=' . $topic . '.' . $this->_req->post->start); |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * Sticky a topic. |
||
139 | * |
||
140 | * Can't be done by topic starters - that would be annoying! |
||
141 | * |
||
142 | * What this does: |
||
143 | * - Stickies a topic - toggles between sticky and normal. |
||
144 | * - Requires the make_sticky permission. |
||
145 | * - Adds an entry to the moderator log. |
||
146 | * - When done, sends the user back to the topic. |
||
147 | * - Accessed via ?action=topic;sa=sticky. |
||
148 | */ |
||
149 | public function action_sticky() |
||
150 | { |
||
151 | global $topic, $board; |
||
152 | |||
153 | // Make sure the user can sticky it, and they are stickying *something*. |
||
154 | isAllowedTo('make_sticky'); |
||
155 | |||
156 | // You can't sticky a board or something! |
||
157 | if (empty($topic)) |
||
158 | { |
||
159 | throw new Exception('not_a_topic', false); |
||
160 | } |
||
161 | |||
162 | checkSession('get'); |
||
163 | |||
164 | // We need this for the sendNotifications() function. |
||
165 | require_once(SUBSDIR . '/Notification.subs.php'); |
||
166 | |||
167 | // And Topic subs for topic attributes. |
||
168 | require_once(SUBSDIR . '/Topic.subs.php'); |
||
169 | |||
170 | // Is this topic already stickied, or no? |
||
171 | $sticky = topicAttribute($topic, 'is_sticky'); |
||
172 | $is_sticky = $sticky['is_sticky']; |
||
173 | |||
174 | // Toggle the sticky value. |
||
175 | setTopicAttribute($topic, array('is_sticky' => (empty($is_sticky) ? 1 : 0))); |
||
176 | |||
177 | // Log this sticky action - always a moderator thing. |
||
178 | logAction(empty($is_sticky) ? 'sticky' : 'unsticky', array('topic' => $topic, 'board' => $board)); |
||
179 | |||
180 | // Notify people that this topic has been stickied? |
||
181 | if (empty($is_sticky)) |
||
182 | { |
||
183 | sendNotifications($topic, 'sticky'); |
||
184 | } |
||
185 | |||
186 | // Take them back to the now stickied topic. |
||
187 | redirectexit('topic=' . $topic . '.' . $this->_req->post->start); |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * Format a topic to be printer friendly. |
||
192 | * |
||
193 | * What id does: |
||
194 | * - Must be called with a topic specified. |
||
195 | * - Accessed via ?action=topic;sa=printpage. |
||
196 | * |
||
197 | * @uses template_print_page() in Printpage.template, |
||
198 | * @uses template_print_above() later without the main layer. |
||
199 | * @uses template_print_below() without the main layer |
||
200 | */ |
||
201 | public function action_printpage() |
||
202 | { |
||
203 | global $topic, $context, $board_info, $modSettings; |
||
204 | |||
205 | // Redirect to the boardindex if no valid topic id is provided. |
||
206 | if (empty($topic)) |
||
207 | { |
||
208 | redirectexit(); |
||
209 | } |
||
210 | |||
211 | // Its not enabled, give them the boot |
||
212 | if (!empty($modSettings['disable_print_topic'])) |
||
213 | { |
||
214 | unset($this->_req->query->action); |
||
215 | $context['theme_loaded'] = false; |
||
216 | throw new Exception('feature_disabled', false); |
||
217 | } |
||
218 | |||
219 | // Clean out the template layers |
||
220 | $template_layers = theme()->getLayers(); |
||
221 | $template_layers->removeAll(); |
||
222 | |||
223 | // Get the topic starter information. |
||
224 | require_once(SUBSDIR . '/Topic.subs.php'); |
||
225 | $topicinfo = getTopicInfo($topic, 'starter'); |
||
226 | |||
227 | // Redirect to the boardindex if no valid topic id is provided. |
||
228 | if (empty($topicinfo)) |
||
229 | { |
||
230 | redirectexit(); |
||
231 | } |
||
232 | |||
233 | $context['user']['started'] = $this->user->id == $topicinfo['id_member'] && $this->user->is_guest === false; |
||
0 ignored issues
–
show
Bug
Best Practice
introduced
by
![]() The property
is_guest does not exist on ElkArte\Helper\ValuesContainer . Since you implemented __get , consider adding a @property annotation.
![]() |
|||
234 | |||
235 | // Whatever happens don't index this. |
||
236 | $context['robot_no_index'] = true; |
||
237 | |||
238 | // @todo this code is almost the same as the one in Display.controller.php |
||
239 | if ($topicinfo['id_poll'] > 0 && !empty($modSettings['pollMode']) && allowedTo('poll_view')) |
||
240 | { |
||
241 | Txt::load('Post'); |
||
242 | require_once(SUBSDIR . '/Poll.subs.php'); |
||
243 | |||
244 | loadPollContext($topicinfo['id_poll']); |
||
245 | $template_layers->addAfter('print_poll', 'print'); |
||
246 | } |
||
247 | |||
248 | // Lets "output" all that info. |
||
249 | theme()->getTemplates()->load('Printpage'); |
||
250 | $template_layers->add('print'); |
||
251 | $context['sub_template'] = 'print_page'; |
||
252 | $context['board_name'] = $board_info['name']; |
||
253 | $context['category_name'] = $board_info['cat']['name']; |
||
254 | $context['poster_name'] = $topicinfo['poster_name']; |
||
255 | $context['post_time'] = standardTime($topicinfo['poster_time'], false); |
||
256 | $context['parent_boards'] = array(); |
||
257 | |||
258 | foreach ($board_info['parent_boards'] as $parent) |
||
259 | { |
||
260 | $context['parent_boards'][] = $parent['name']; |
||
261 | } |
||
262 | |||
263 | // Split the topics up so we can print them. |
||
264 | $context['posts'] = topicMessages($topic); |
||
265 | $posts_id = array_keys($context['posts']); |
||
266 | |||
267 | if (!isset($context['topic_subject'])) |
||
268 | { |
||
269 | $context['topic_subject'] = $context['posts'][min($posts_id)]['subject']; |
||
270 | } |
||
271 | |||
272 | // Fetch attachments so we can print them if asked, enabled and allowed |
||
273 | if (isset($this->_req->query->images) && !empty($modSettings['attachmentEnable']) && allowedTo('view_attachments')) |
||
274 | { |
||
275 | require_once(SUBSDIR . '/Topic.subs.php'); |
||
276 | $context['printattach'] = messagesAttachments(array_keys($context['posts'])); |
||
277 | $context['viewing_attach'] = true; |
||
278 | } |
||
279 | |||
280 | // Set a canonical URL for this page. |
||
281 | $context['canonical_url'] = getUrl('action', ['topic' => $topic . '.0']); |
||
282 | $context['view_attach_mode'] = array( |
||
283 | 'text' => getUrl('action', ['action' => 'topic', 'sa' => 'printpage', 'topic' => $topic . '.0']), |
||
284 | 'images' => getUrl('action', ['action' => 'topic', 'sa' => 'printpage', 'topic' => $topic . '.0', 'images']), |
||
285 | ); |
||
286 | } |
||
287 | } |
||
288 |