elkarte /
Elkarte
| 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(): void |
||
| 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, ['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', ['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(): void |
||
| 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, ['is_sticky' => (empty($is_sticky) ? 1 : 0)]); |
||
| 176 | |||
| 177 | // Log this sticky action - always a moderator thing. |
||
| 178 | logAction(empty($is_sticky) ? 'sticky' : 'unsticky', ['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(): void |
||
| 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
Loading history...
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'] = []; |
||
| 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'] = [ |
||
| 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 |