Issues (1686)

sources/ElkArte/Controller/Topic.php (2 issues)

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 id does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
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.
Loading history...
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