Yoshi2889 /
SMF2.1
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * This file contains all the functions that allow for the saving, |
||
| 5 | * retrieving, deleting and settings for the drafts function. |
||
| 6 | * |
||
| 7 | * Simple Machines Forum (SMF) |
||
| 8 | * |
||
| 9 | * @package SMF |
||
| 10 | * @author Simple Machines http://www.simplemachines.org |
||
| 11 | * @copyright 2017 Simple Machines and individual contributors |
||
| 12 | * @license http://www.simplemachines.org/about/smf/license.php BSD |
||
| 13 | * |
||
| 14 | * @version 2.1 Beta 4 |
||
| 15 | */ |
||
| 16 | |||
| 17 | if (!defined('SMF')) |
||
| 18 | die('No direct access...'); |
||
| 19 | |||
| 20 | loadLanguage('Drafts'); |
||
| 21 | |||
| 22 | /** |
||
| 23 | * Saves a post draft in the user_drafts table |
||
| 24 | * The core draft feature must be enabled, as well as the post draft option |
||
| 25 | * Determines if this is a new or an existing draft |
||
| 26 | * Returns errors in $post_errors for display in the template |
||
| 27 | * |
||
| 28 | * @param string[] $post_errors Any errors encountered trying to save this draft |
||
| 29 | * @return boolean Always returns true |
||
| 30 | */ |
||
| 31 | function SaveDraft(&$post_errors) |
||
|
0 ignored issues
–
show
|
|||
| 32 | { |
||
| 33 | global $context, $user_info, $smcFunc, $modSettings, $board; |
||
| 34 | |||
| 35 | // can you be, should you be ... here? |
||
| 36 | if (empty($modSettings['drafts_post_enabled']) || !allowedTo('post_draft') || !isset($_POST['save_draft']) || !isset($_POST['id_draft'])) |
||
| 37 | return false; |
||
| 38 | |||
| 39 | // read in what they sent us, if anything |
||
| 40 | $id_draft = (int) $_POST['id_draft']; |
||
| 41 | $draft_info = ReadDraft($id_draft); |
||
| 42 | |||
| 43 | // A draft has been saved less than 5 seconds ago, let's not do the autosave again |
||
| 44 | View Code Duplication | if (isset($_REQUEST['xml']) && !empty($draft_info['poster_time']) && time() < $draft_info['poster_time'] + 5) |
|
| 45 | { |
||
| 46 | $context['draft_saved_on'] = $draft_info['poster_time']; |
||
| 47 | |||
| 48 | // since we were called from the autosave function, send something back |
||
| 49 | if (!empty($id_draft)) |
||
| 50 | XmlDraft($id_draft); |
||
| 51 | |||
| 52 | return true; |
||
| 53 | } |
||
| 54 | |||
| 55 | if (!isset($_POST['message'])) |
||
| 56 | $_POST['message'] = isset($_POST['quickReply']) ? $_POST['quickReply'] : ''; |
||
| 57 | |||
| 58 | // prepare any data from the form |
||
| 59 | $topic_id = empty($_REQUEST['topic']) ? 0 : (int) $_REQUEST['topic']; |
||
| 60 | $draft['icon'] = empty($_POST['icon']) ? 'xx' : preg_replace('~[\./\\\\*:"\'<>]~', '', $_POST['icon']); |
||
| 61 | $draft['smileys_enabled'] = isset($_POST['ns']) ? (int) $_POST['ns'] : 0; |
||
| 62 | $draft['locked'] = isset($_POST['lock']) ? (int) $_POST['lock'] : 0; |
||
| 63 | $draft['sticky'] = isset($_POST['sticky']) ? (int) $_POST['sticky'] : 0; |
||
| 64 | $draft['subject'] = strtr($smcFunc['htmlspecialchars']($_POST['subject']), array("\r" => '', "\n" => '', "\t" => '')); |
||
| 65 | $draft['body'] = $smcFunc['htmlspecialchars']($_POST['message'], ENT_QUOTES); |
||
| 66 | |||
| 67 | // message and subject still need a bit more work |
||
| 68 | preparsecode($draft['body']); |
||
| 69 | View Code Duplication | if ($smcFunc['strlen']($draft['subject']) > 100) |
|
| 70 | $draft['subject'] = $smcFunc['substr']($draft['subject'], 0, 100); |
||
| 71 | |||
| 72 | // Modifying an existing draft, like hitting the save draft button or autosave enabled? |
||
| 73 | if (!empty($id_draft) && !empty($draft_info)) |
||
| 74 | { |
||
| 75 | $smcFunc['db_query']('', ' |
||
| 76 | UPDATE {db_prefix}user_drafts |
||
| 77 | SET |
||
| 78 | id_topic = {int:id_topic}, |
||
| 79 | id_board = {int:id_board}, |
||
| 80 | poster_time = {int:poster_time}, |
||
| 81 | subject = {string:subject}, |
||
| 82 | smileys_enabled = {int:smileys_enabled}, |
||
| 83 | body = {string:body}, |
||
| 84 | icon = {string:icon}, |
||
| 85 | locked = {int:locked}, |
||
| 86 | is_sticky = {int:is_sticky} |
||
| 87 | WHERE id_draft = {int:id_draft}', |
||
| 88 | array( |
||
| 89 | 'id_topic' => $topic_id, |
||
| 90 | 'id_board' => $board, |
||
| 91 | 'poster_time' => time(), |
||
| 92 | 'subject' => $draft['subject'], |
||
| 93 | 'smileys_enabled' => (int) $draft['smileys_enabled'], |
||
| 94 | 'body' => $draft['body'], |
||
| 95 | 'icon' => $draft['icon'], |
||
| 96 | 'locked' => $draft['locked'], |
||
| 97 | 'is_sticky' => $draft['sticky'], |
||
| 98 | 'id_draft' => $id_draft, |
||
| 99 | ) |
||
| 100 | ); |
||
| 101 | |||
| 102 | // some items to return to the form |
||
| 103 | $context['draft_saved'] = true; |
||
| 104 | $context['id_draft'] = $id_draft; |
||
| 105 | |||
| 106 | // cleanup |
||
| 107 | unset($_POST['save_draft']); |
||
| 108 | } |
||
| 109 | // otherwise creating a new draft |
||
| 110 | else |
||
| 111 | { |
||
| 112 | $id_draft = $smcFunc['db_insert']('', |
||
| 113 | '{db_prefix}user_drafts', |
||
| 114 | array( |
||
| 115 | 'id_topic' => 'int', |
||
| 116 | 'id_board' => 'int', |
||
| 117 | 'type' => 'int', |
||
| 118 | 'poster_time' => 'int', |
||
| 119 | 'id_member' => 'int', |
||
| 120 | 'subject' => 'string-255', |
||
| 121 | 'smileys_enabled' => 'int', |
||
| 122 | 'body' => (!empty($modSettings['max_messageLength']) && $modSettings['max_messageLength'] > 65534 ? 'string-' . $modSettings['max_messageLength'] : 'string-65534'), |
||
| 123 | 'icon' => 'string-16', |
||
| 124 | 'locked' => 'int', |
||
| 125 | 'is_sticky' => 'int' |
||
| 126 | ), |
||
| 127 | array( |
||
| 128 | $topic_id, |
||
| 129 | $board, |
||
| 130 | 0, |
||
| 131 | time(), |
||
| 132 | $user_info['id'], |
||
| 133 | $draft['subject'], |
||
| 134 | $draft['smileys_enabled'], |
||
| 135 | $draft['body'], |
||
| 136 | $draft['icon'], |
||
| 137 | $draft['locked'], |
||
| 138 | $draft['sticky'] |
||
| 139 | ), |
||
| 140 | array( |
||
| 141 | 'id_draft' |
||
| 142 | ), |
||
| 143 | 1 |
||
| 144 | ); |
||
| 145 | |||
| 146 | // everything go as expected? |
||
| 147 | View Code Duplication | if (!empty($id_draft)) |
|
| 148 | { |
||
| 149 | $context['draft_saved'] = true; |
||
| 150 | $context['id_draft'] = $id_draft; |
||
| 151 | } |
||
| 152 | else |
||
| 153 | $post_errors[] = 'draft_not_saved'; |
||
| 154 | |||
| 155 | // cleanup |
||
| 156 | unset($_POST['save_draft']); |
||
| 157 | } |
||
| 158 | |||
| 159 | // if we were called from the autosave function, send something back |
||
| 160 | View Code Duplication | if (!empty($id_draft) && isset($_REQUEST['xml']) && (!in_array('session_timeout', $post_errors))) |
|
| 161 | { |
||
| 162 | $context['draft_saved_on'] = time(); |
||
| 163 | XmlDraft($id_draft); |
||
| 164 | } |
||
| 165 | |||
| 166 | return true; |
||
| 167 | } |
||
| 168 | |||
| 169 | /** |
||
| 170 | * Saves a PM draft in the user_drafts table |
||
| 171 | * The core draft feature must be enabled, as well as the pm draft option |
||
| 172 | * Determines if this is a new or and update to an existing pm draft |
||
| 173 | * |
||
| 174 | * @param string $post_errors A string of info about errors encountered trying to save this draft |
||
| 175 | * @param array $recipientList An array of data about who this PM is being sent to |
||
| 176 | * @return boolean false if you can't save the draft, true if we're doing this via XML more than 5 seconds after the last save, nothing otherwise |
||
|
0 ignored issues
–
show
|
|||
| 177 | */ |
||
| 178 | function SavePMDraft(&$post_errors, $recipientList) |
||
|
0 ignored issues
–
show
As per coding-style, this function should be in camelCase.
Loading history...
|
|||
| 179 | { |
||
| 180 | global $context, $user_info, $smcFunc, $modSettings; |
||
| 181 | |||
| 182 | // PM survey says ... can you stay or must you go |
||
| 183 | if (empty($modSettings['drafts_pm_enabled']) || !allowedTo('pm_draft') || !isset($_POST['save_draft'])) |
||
| 184 | return false; |
||
| 185 | |||
| 186 | // read in what you sent us |
||
| 187 | $id_pm_draft = (int) $_POST['id_pm_draft']; |
||
| 188 | $draft_info = ReadDraft($id_pm_draft, 1); |
||
| 189 | |||
| 190 | // 5 seconds is the same limit we have for posting |
||
| 191 | View Code Duplication | if (isset($_REQUEST['xml']) && !empty($draft_info['poster_time']) && time() < $draft_info['poster_time'] + 5) |
|
| 192 | { |
||
| 193 | $context['draft_saved_on'] = $draft_info['poster_time']; |
||
| 194 | |||
| 195 | // Send something back to the javascript caller |
||
| 196 | if (!empty($id_draft)) |
||
| 197 | XmlDraft($id_draft); |
||
| 198 | |||
| 199 | return true; |
||
| 200 | } |
||
| 201 | |||
| 202 | // determine who this is being sent to |
||
| 203 | if (isset($_REQUEST['xml'])) |
||
| 204 | { |
||
| 205 | $recipientList['to'] = isset($_POST['recipient_to']) ? explode(',', $_POST['recipient_to']) : array(); |
||
| 206 | $recipientList['bcc'] = isset($_POST['recipient_bcc']) ? explode(',', $_POST['recipient_bcc']) : array(); |
||
| 207 | } |
||
| 208 | elseif (!empty($draft_info['to_list']) && empty($recipientList)) |
||
| 209 | $recipientList = $smcFunc['json_decode']($draft_info['to_list'], true); |
||
| 210 | |||
| 211 | // prepare the data we got from the form |
||
| 212 | $reply_id = empty($_POST['replied_to']) ? 0 : (int) $_POST['replied_to']; |
||
| 213 | $draft['body'] = $smcFunc['htmlspecialchars']($_POST['message'], ENT_QUOTES); |
||
| 214 | $draft['subject'] = strtr($smcFunc['htmlspecialchars']($_POST['subject']), array("\r" => '', "\n" => '', "\t" => '')); |
||
| 215 | |||
| 216 | // message and subject always need a bit more work |
||
| 217 | preparsecode($draft['body']); |
||
| 218 | View Code Duplication | if ($smcFunc['strlen']($draft['subject']) > 100) |
|
| 219 | $draft['subject'] = $smcFunc['substr']($draft['subject'], 0, 100); |
||
| 220 | |||
| 221 | // Modifying an existing PM draft? |
||
| 222 | if (!empty($id_pm_draft) && !empty($draft_info)) |
||
| 223 | { |
||
| 224 | $smcFunc['db_query']('', ' |
||
| 225 | UPDATE {db_prefix}user_drafts |
||
| 226 | SET id_reply = {int:id_reply}, |
||
| 227 | type = {int:type}, |
||
| 228 | poster_time = {int:poster_time}, |
||
| 229 | subject = {string:subject}, |
||
| 230 | body = {string:body}, |
||
| 231 | to_list = {string:to_list} |
||
| 232 | WHERE id_draft = {int:id_pm_draft} |
||
| 233 | LIMIT 1', |
||
| 234 | array( |
||
| 235 | 'id_reply' => $reply_id, |
||
| 236 | 'type' => 1, |
||
| 237 | 'poster_time' => time(), |
||
| 238 | 'subject' => $draft['subject'], |
||
| 239 | 'body' => $draft['body'], |
||
| 240 | 'id_pm_draft' => $id_pm_draft, |
||
| 241 | 'to_list' => $smcFunc['json_encode']($recipientList), |
||
| 242 | ) |
||
| 243 | ); |
||
| 244 | |||
| 245 | // some items to return to the form |
||
| 246 | $context['draft_saved'] = true; |
||
| 247 | $context['id_pm_draft'] = $id_pm_draft; |
||
| 248 | } |
||
| 249 | // otherwise creating a new PM draft. |
||
| 250 | else |
||
| 251 | { |
||
| 252 | $id_pm_draft = $smcFunc['db_insert']('', |
||
| 253 | '{db_prefix}user_drafts', |
||
| 254 | array( |
||
| 255 | 'id_reply' => 'int', |
||
| 256 | 'type' => 'int', |
||
| 257 | 'poster_time' => 'int', |
||
| 258 | 'id_member' => 'int', |
||
| 259 | 'subject' => 'string-255', |
||
| 260 | 'body' => 'string-65534', |
||
| 261 | 'to_list' => 'string-255', |
||
| 262 | ), |
||
| 263 | array( |
||
| 264 | $reply_id, |
||
| 265 | 1, |
||
| 266 | time(), |
||
| 267 | $user_info['id'], |
||
| 268 | $draft['subject'], |
||
| 269 | $draft['body'], |
||
| 270 | $smcFunc['json_encode']($recipientList), |
||
| 271 | ), |
||
| 272 | array( |
||
| 273 | 'id_draft' |
||
| 274 | ), |
||
| 275 | 1 |
||
| 276 | ); |
||
| 277 | |||
| 278 | // everything go as expected, if not toss back an error |
||
| 279 | View Code Duplication | if (!empty($id_pm_draft)) |
|
| 280 | { |
||
| 281 | $context['draft_saved'] = true; |
||
| 282 | $context['id_pm_draft'] = $id_pm_draft; |
||
| 283 | } |
||
| 284 | else |
||
| 285 | $post_errors[] = 'draft_not_saved'; |
||
| 286 | } |
||
| 287 | |||
| 288 | // if we were called from the autosave function, send something back |
||
| 289 | View Code Duplication | if (!empty($id_pm_draft) && isset($_REQUEST['xml']) && !in_array('session_timeout', $post_errors)) |
|
| 290 | { |
||
| 291 | $context['draft_saved_on'] = time(); |
||
| 292 | XmlDraft($id_pm_draft); |
||
| 293 | } |
||
| 294 | |||
| 295 | return; |
||
| 296 | } |
||
| 297 | |||
| 298 | /** |
||
| 299 | * Reads a draft in from the user_drafts table |
||
| 300 | * Validates that the draft is the user''s draft |
||
| 301 | * Optionally loads the draft in to context or superglobal for loading in to the form |
||
| 302 | * |
||
| 303 | * @param int $id_draft ID of the draft to load |
||
| 304 | * @param int $type Type of draft - 0 for post or 1 for PM |
||
| 305 | * @param boolean $check Validate that this draft belongs to the current user |
||
| 306 | * @param boolean $load Whether or not to load the data into variables for use on a form |
||
| 307 | * @return boolean|array False if the data couldn't be loaded, true if it's a PM draft or an array of info about the draft if it's a post draft |
||
| 308 | */ |
||
| 309 | function ReadDraft($id_draft, $type = 0, $check = true, $load = false) |
||
|
0 ignored issues
–
show
As per coding-style, this function should be in camelCase.
Loading history...
|
|||
| 310 | { |
||
| 311 | global $context, $user_info, $smcFunc, $modSettings; |
||
| 312 | |||
| 313 | // like purell always clean to be sure |
||
| 314 | $id_draft = (int) $id_draft; |
||
| 315 | $type = (int) $type; |
||
| 316 | |||
| 317 | // nothing to read, nothing to do |
||
| 318 | if (empty($id_draft)) |
||
| 319 | return false; |
||
| 320 | |||
| 321 | // load in this draft from the DB |
||
| 322 | $request = $smcFunc['db_query']('', ' |
||
| 323 | SELECT is_sticky, locked, smileys_enabled, icon, body , subject, |
||
| 324 | id_board, id_draft, id_reply, to_list |
||
| 325 | FROM {db_prefix}user_drafts |
||
| 326 | WHERE id_draft = {int:id_draft}' . ($check ? ' |
||
| 327 | AND id_member = {int:id_member}' : '') . ' |
||
| 328 | AND type = {int:type}' . (!empty($modSettings['drafts_keep_days']) ? ' |
||
| 329 | AND poster_time > {int:time}' : '') . ' |
||
| 330 | LIMIT 1', |
||
| 331 | array( |
||
| 332 | 'id_member' => $user_info['id'], |
||
| 333 | 'id_draft' => $id_draft, |
||
| 334 | 'type' => $type, |
||
| 335 | 'time' => (!empty($modSettings['drafts_keep_days']) ? (time() - ($modSettings['drafts_keep_days'] * 86400)) : 0), |
||
| 336 | ) |
||
| 337 | ); |
||
| 338 | |||
| 339 | // no results? |
||
| 340 | if (!$smcFunc['db_num_rows']($request)) |
||
| 341 | return false; |
||
| 342 | |||
| 343 | // load up the data |
||
| 344 | $draft_info = $smcFunc['db_fetch_assoc']($request); |
||
| 345 | $smcFunc['db_free_result']($request); |
||
| 346 | |||
| 347 | // Load it up for the templates as well |
||
| 348 | if (!empty($load)) |
||
| 349 | { |
||
| 350 | if ($type === 0) |
||
| 351 | { |
||
| 352 | // a standard post draft? |
||
| 353 | $context['sticky'] = !empty($draft_info['is_sticky']) ? $draft_info['is_sticky'] : ''; |
||
| 354 | $context['locked'] = !empty($draft_info['locked']) ? $draft_info['locked'] : ''; |
||
| 355 | $context['use_smileys'] = !empty($draft_info['smileys_enabled']) ? true : false; |
||
| 356 | $context['icon'] = !empty($draft_info['icon']) ? $draft_info['icon'] : 'xx'; |
||
| 357 | $context['message'] = !empty($draft_info['body']) ? str_replace('<br>', "\n", un_htmlspecialchars(stripslashes($draft_info['body']))) : ''; |
||
| 358 | $context['subject'] = !empty($draft_info['subject']) ? stripslashes($draft_info['subject']) : ''; |
||
| 359 | $context['board'] = !empty($draft_info['id_board']) ? $draft_info['id_board'] : ''; |
||
| 360 | $context['id_draft'] = !empty($draft_info['id_draft']) ? $draft_info['id_draft'] : 0; |
||
| 361 | } |
||
| 362 | elseif ($type === 1) |
||
| 363 | { |
||
| 364 | // one of those pm drafts? then set it up like we have an error |
||
| 365 | $_REQUEST['subject'] = !empty($draft_info['subject']) ? stripslashes($draft_info['subject']) : ''; |
||
| 366 | $_REQUEST['message'] = !empty($draft_info['body']) ? str_replace('<br>', "\n", un_htmlspecialchars(stripslashes($draft_info['body']))) : ''; |
||
| 367 | $_REQUEST['replied_to'] = !empty($draft_info['id_reply']) ? $draft_info['id_reply'] : 0; |
||
| 368 | $context['id_pm_draft'] = !empty($draft_info['id_draft']) ? $draft_info['id_draft'] : 0; |
||
| 369 | $recipients = $smcFunc['json_decode']($draft_info['to_list'], true); |
||
| 370 | |||
| 371 | // make sure we only have integers in this array |
||
| 372 | $recipients['to'] = array_map('intval', $recipients['to']); |
||
| 373 | $recipients['bcc'] = array_map('intval', $recipients['bcc']); |
||
| 374 | |||
| 375 | // pretend we messed up to populate the pm message form |
||
| 376 | messagePostError(array(), array(), $recipients); |
||
| 377 | return true; |
||
| 378 | } |
||
| 379 | } |
||
| 380 | |||
| 381 | return $draft_info; |
||
| 382 | } |
||
| 383 | |||
| 384 | /** |
||
| 385 | * Deletes one or many drafts from the DB |
||
| 386 | * Validates the drafts are from the user |
||
| 387 | * is supplied an array of drafts will attempt to remove all of them |
||
| 388 | * |
||
| 389 | * @param int $id_draft The ID of the draft to delete |
||
| 390 | * @param boolean $check Whether or not to check that the draft belongs to the current user |
||
| 391 | * @return boolean False if it couldn't be deleted (doesn't return anything otherwise) |
||
|
0 ignored issues
–
show
|
|||
| 392 | */ |
||
| 393 | function DeleteDraft($id_draft, $check = true) |
||
|
0 ignored issues
–
show
As per coding-style, this function should be in camelCase.
Loading history...
|
|||
| 394 | { |
||
| 395 | global $user_info, $smcFunc; |
||
| 396 | |||
| 397 | // Only a single draft. |
||
| 398 | if (is_numeric($id_draft)) |
||
| 399 | $id_draft = array($id_draft); |
||
| 400 | |||
| 401 | // can't delete nothing |
||
| 402 | if (empty($id_draft) || ($check && empty($user_info['id']))) |
||
| 403 | return false; |
||
| 404 | |||
| 405 | $smcFunc['db_query']('', ' |
||
| 406 | DELETE FROM {db_prefix}user_drafts |
||
| 407 | WHERE id_draft IN ({array_int:id_draft})' . ($check ? ' |
||
| 408 | AND id_member = {int:id_member}' : ''), |
||
| 409 | array( |
||
| 410 | 'id_draft' => $id_draft, |
||
| 411 | 'id_member' => empty($user_info['id']) ? -1 : $user_info['id'], |
||
| 412 | ) |
||
| 413 | ); |
||
| 414 | } |
||
| 415 | |||
| 416 | /** |
||
| 417 | * Loads in a group of drafts for the user of a given type (0/posts, 1/pm's) |
||
| 418 | * loads a specific draft for forum use if selected. |
||
| 419 | * Used in the posting screens to allow draft selection |
||
| 420 | * Will load a draft if selected is supplied via post |
||
| 421 | * |
||
| 422 | * @param int $member_id ID of the member to show drafts for |
||
| 423 | * @param boolean|integer If $type is 1, this can be set to only load drafts for posts in the specific topic |
||
| 424 | * @param int $draft_type The type of drafts to show - 0 for post drafts, 1 for PM drafts |
||
| 425 | * @return boolean False if the drafts couldn't be loaded, nothing otherwise |
||
|
0 ignored issues
–
show
|
|||
| 426 | */ |
||
| 427 | function ShowDrafts($member_id, $topic = false, $draft_type = 0) |
||
|
0 ignored issues
–
show
As per coding-style, this function should be in camelCase.
Loading history...
|
|||
| 428 | { |
||
| 429 | global $smcFunc, $scripturl, $context, $txt, $modSettings; |
||
| 430 | |||
| 431 | // Permissions |
||
| 432 | if (($draft_type === 0 && empty($context['drafts_save'])) || ($draft_type === 1 && empty($context['drafts_pm_save'])) || empty($member_id)) |
||
| 433 | return false; |
||
| 434 | |||
| 435 | $context['drafts'] = array(); |
||
| 436 | |||
| 437 | // has a specific draft has been selected? Load it up if there is not a message already in the editor |
||
| 438 | if (isset($_REQUEST['id_draft']) && empty($_POST['subject']) && empty($_POST['message'])) |
||
| 439 | ReadDraft((int) $_REQUEST['id_draft'], $draft_type, true, true); |
||
| 440 | |||
| 441 | // load the drafts this user has available |
||
| 442 | $request = $smcFunc['db_query']('', ' |
||
| 443 | SELECT subject, poster_time, id_board, id_topic, id_draft |
||
| 444 | FROM {db_prefix}user_drafts |
||
| 445 | WHERE id_member = {int:id_member}' . ((!empty($topic) && empty($draft_type)) ? ' |
||
| 446 | AND id_topic = {int:id_topic}' : (!empty($topic) ? ' |
||
| 447 | AND id_reply = {int:id_topic}' : '')) . ' |
||
| 448 | AND type = {int:draft_type}' . (!empty($modSettings['drafts_keep_days']) ? ' |
||
| 449 | AND poster_time > {int:time}' : '') . ' |
||
| 450 | ORDER BY poster_time DESC', |
||
| 451 | array( |
||
| 452 | 'id_member' => $member_id, |
||
| 453 | 'id_topic' => (int) $topic, |
||
| 454 | 'draft_type' => $draft_type, |
||
| 455 | 'time' => (!empty($modSettings['drafts_keep_days']) ? (time() - ($modSettings['drafts_keep_days'] * 86400)) : 0), |
||
| 456 | ) |
||
| 457 | ); |
||
| 458 | |||
| 459 | // add them to the draft array for display |
||
| 460 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 461 | { |
||
| 462 | if (empty($row['subject'])) |
||
| 463 | $row['subject'] = $txt['no_subject']; |
||
| 464 | |||
| 465 | // Post drafts |
||
| 466 | if ($draft_type === 0) |
||
| 467 | { |
||
| 468 | $tmp_subject = shorten_subject(stripslashes($row['subject']), 24); |
||
| 469 | $context['drafts'][] = array( |
||
| 470 | 'subject' => censorText($tmp_subject), |
||
| 471 | 'poster_time' => timeformat($row['poster_time']), |
||
| 472 | 'link' => '<a href="' . $scripturl . '?action=post;board=' . $row['id_board'] . ';' . (!empty($row['id_topic']) ? 'topic=' . $row['id_topic'] . '.0;' : '') . 'id_draft=' . $row['id_draft'] . '">' . $row['subject'] . '</a>', |
||
| 473 | ); |
||
| 474 | } |
||
| 475 | // PM drafts |
||
| 476 | elseif ($draft_type === 1) |
||
| 477 | { |
||
| 478 | $tmp_subject = shorten_subject(stripslashes($row['subject']), 24); |
||
| 479 | $context['drafts'][] = array( |
||
| 480 | 'subject' => censorText($tmp_subject), |
||
| 481 | 'poster_time' => timeformat($row['poster_time']), |
||
| 482 | 'link' => '<a href="' . $scripturl . '?action=pm;sa=send;id_draft=' . $row['id_draft'] . '">' . (!empty($row['subject']) ? $row['subject'] : $txt['drafts_none']) . '</a>', |
||
| 483 | ); |
||
| 484 | } |
||
| 485 | } |
||
| 486 | $smcFunc['db_free_result']($request); |
||
| 487 | } |
||
| 488 | |||
| 489 | /** |
||
| 490 | * Returns an xml response to an autosave ajax request |
||
| 491 | * provides the id of the draft saved and the time it was saved |
||
| 492 | * |
||
| 493 | * @param int $id_draft |
||
| 494 | */ |
||
| 495 | function XmlDraft($id_draft) |
||
|
0 ignored issues
–
show
As per coding-style, this function should be in camelCase.
Loading history...
|
|||
| 496 | { |
||
| 497 | global $txt, $context; |
||
| 498 | |||
| 499 | header('Content-Type: text/xml; charset=' . (empty($context['character_set']) ? 'ISO-8859-1' : $context['character_set'])); |
||
| 500 | |||
| 501 | echo '<?xml version="1.0" encoding="', $context['character_set'], '"?> |
||
| 502 | <drafts> |
||
| 503 | <draft id="', $id_draft, '"><![CDATA[', $txt['draft_saved_on'], ': ', timeformat($context['draft_saved_on']), ']]></draft> |
||
| 504 | </drafts>'; |
||
| 505 | |||
| 506 | obExit(false); |
||
| 507 | } |
||
| 508 | |||
| 509 | /** |
||
| 510 | * Show all drafts of a given type by the current user |
||
| 511 | * Uses the showdraft template |
||
| 512 | * Allows for the deleting and loading/editing of drafts |
||
| 513 | * |
||
| 514 | * @param int $memID |
||
| 515 | * @param int $draft_type |
||
| 516 | */ |
||
| 517 | function showProfileDrafts($memID, $draft_type = 0) |
||
| 518 | { |
||
| 519 | global $txt, $scripturl, $modSettings, $context, $smcFunc, $options; |
||
| 520 | |||
| 521 | // Some initial context. |
||
| 522 | $context['start'] = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0; |
||
| 523 | $context['current_member'] = $memID; |
||
| 524 | |||
| 525 | // If just deleting a draft, do it and then redirect back. |
||
| 526 | if (!empty($_REQUEST['delete'])) |
||
| 527 | { |
||
| 528 | checkSession('get'); |
||
| 529 | $id_delete = (int) $_REQUEST['delete']; |
||
| 530 | |||
| 531 | $smcFunc['db_query']('', ' |
||
| 532 | DELETE FROM {db_prefix}user_drafts |
||
| 533 | WHERE id_draft = {int:id_draft} |
||
| 534 | AND id_member = {int:id_member} |
||
| 535 | AND type = {int:draft_type} |
||
| 536 | LIMIT 1', |
||
| 537 | array( |
||
| 538 | 'id_draft' => $id_delete, |
||
| 539 | 'id_member' => $memID, |
||
| 540 | 'draft_type' => $draft_type, |
||
| 541 | ) |
||
| 542 | ); |
||
| 543 | |||
| 544 | redirectexit('action=profile;u=' . $memID . ';area=showdrafts;start=' . $context['start']); |
||
| 545 | } |
||
| 546 | |||
| 547 | // Default to 10. |
||
| 548 | View Code Duplication | if (empty($_REQUEST['viewscount']) || !is_numeric($_REQUEST['viewscount'])) |
|
| 549 | $_REQUEST['viewscount'] = 10; |
||
| 550 | |||
| 551 | // Get the count of applicable drafts on the boards they can (still) see ... |
||
| 552 | // @todo .. should we just let them see their drafts even if they have lost board access ? |
||
|
0 ignored issues
–
show
|
|||
| 553 | $request = $smcFunc['db_query']('', ' |
||
| 554 | SELECT COUNT(id_draft) |
||
| 555 | FROM {db_prefix}user_drafts AS ud |
||
| 556 | INNER JOIN {db_prefix}boards AS b ON (b.id_board = ud.id_board AND {query_see_board}) |
||
| 557 | WHERE id_member = {int:id_member} |
||
| 558 | AND type={int:draft_type}' . (!empty($modSettings['drafts_keep_days']) ? ' |
||
| 559 | AND poster_time > {int:time}' : ''), |
||
| 560 | array( |
||
| 561 | 'id_member' => $memID, |
||
| 562 | 'draft_type' => $draft_type, |
||
| 563 | 'time' => (!empty($modSettings['drafts_keep_days']) ? (time() - ($modSettings['drafts_keep_days'] * 86400)) : 0), |
||
| 564 | ) |
||
| 565 | ); |
||
| 566 | list ($msgCount) = $smcFunc['db_fetch_row']($request); |
||
| 567 | $smcFunc['db_free_result']($request); |
||
| 568 | |||
| 569 | $maxPerPage = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages']; |
||
| 570 | $maxIndex = $maxPerPage; |
||
| 571 | |||
| 572 | // Make sure the starting place makes sense and construct our friend the page index. |
||
| 573 | $context['page_index'] = constructPageIndex($scripturl . '?action=profile;u=' . $memID . ';area=showdrafts', $context['start'], $msgCount, $maxIndex); |
||
| 574 | $context['current_page'] = $context['start'] / $maxIndex; |
||
| 575 | |||
| 576 | // Reverse the query if we're past 50% of the pages for better performance. |
||
| 577 | $start = $context['start']; |
||
| 578 | $reverse = $_REQUEST['start'] > $msgCount / 2; |
||
| 579 | View Code Duplication | if ($reverse) |
|
| 580 | { |
||
| 581 | $maxIndex = $msgCount < $context['start'] + $maxPerPage + 1 && $msgCount > $context['start'] ? $msgCount - $context['start'] : $maxPerPage; |
||
| 582 | $start = $msgCount < $context['start'] + $maxPerPage + 1 || $msgCount < $context['start'] + $maxPerPage ? 0 : $msgCount - $context['start'] - $maxPerPage; |
||
| 583 | } |
||
| 584 | |||
| 585 | // Find this user's drafts for the boards they can access |
||
| 586 | // @todo ... do we want to do this? If they were able to create a draft, do we remove thier access to said draft if they loose |
||
|
0 ignored issues
–
show
|
|||
| 587 | // access to the board or if the topic moves to a board they can not see? |
||
| 588 | $request = $smcFunc['db_query']('', ' |
||
| 589 | SELECT |
||
| 590 | b.id_board, b.name AS bname, |
||
| 591 | ud.id_member, ud.id_draft, ud.body, ud.smileys_enabled, ud.subject, ud.poster_time, ud.icon, ud.id_topic, ud.locked, ud.is_sticky |
||
| 592 | FROM {db_prefix}user_drafts AS ud |
||
| 593 | INNER JOIN {db_prefix}boards AS b ON (b.id_board = ud.id_board AND {query_see_board}) |
||
| 594 | WHERE ud.id_member = {int:current_member} |
||
| 595 | AND type = {int:draft_type}' . (!empty($modSettings['drafts_keep_days']) ? ' |
||
| 596 | AND poster_time > {int:time}' : '') . ' |
||
| 597 | ORDER BY ud.id_draft ' . ($reverse ? 'ASC' : 'DESC') . ' |
||
| 598 | LIMIT {int:start}, {int:max}', |
||
| 599 | array( |
||
| 600 | 'current_member' => $memID, |
||
| 601 | 'draft_type' => $draft_type, |
||
| 602 | 'time' => (!empty($modSettings['drafts_keep_days']) ? (time() - ($modSettings['drafts_keep_days'] * 86400)) : 0), |
||
| 603 | 'start' => $start, |
||
| 604 | 'max' => $maxIndex, |
||
| 605 | ) |
||
| 606 | ); |
||
| 607 | |||
| 608 | // Start counting at the number of the first message displayed. |
||
| 609 | $counter = $reverse ? $context['start'] + $maxIndex + 1 : $context['start']; |
||
| 610 | $context['posts'] = array(); |
||
| 611 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 612 | { |
||
| 613 | // Censor.... |
||
| 614 | if (empty($row['body'])) |
||
| 615 | $row['body'] = ''; |
||
| 616 | |||
| 617 | $row['subject'] = $smcFunc['htmltrim']($row['subject']); |
||
| 618 | if (empty($row['subject'])) |
||
| 619 | $row['subject'] = $txt['no_subject']; |
||
| 620 | |||
| 621 | censorText($row['body']); |
||
| 622 | censorText($row['subject']); |
||
| 623 | |||
| 624 | // BBC-ilize the message. |
||
| 625 | $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], 'draft' . $row['id_draft']); |
||
| 626 | |||
| 627 | // And the array... |
||
| 628 | $context['drafts'][$counter += $reverse ? -1 : 1] = array( |
||
| 629 | 'body' => $row['body'], |
||
| 630 | 'counter' => $counter, |
||
| 631 | 'board' => array( |
||
| 632 | 'name' => $row['bname'], |
||
| 633 | 'id' => $row['id_board'] |
||
| 634 | ), |
||
| 635 | 'topic' => array( |
||
| 636 | 'id' => $row['id_topic'], |
||
| 637 | 'link' => empty($row['id']) ? $row['subject'] : '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['subject'] . '</a>', |
||
| 638 | ), |
||
| 639 | 'subject' => $row['subject'], |
||
| 640 | 'time' => timeformat($row['poster_time']), |
||
| 641 | 'timestamp' => forum_time(true, $row['poster_time']), |
||
| 642 | 'icon' => $row['icon'], |
||
| 643 | 'id_draft' => $row['id_draft'], |
||
| 644 | 'locked' => $row['locked'], |
||
| 645 | 'sticky' => $row['is_sticky'], |
||
| 646 | ); |
||
| 647 | } |
||
| 648 | $smcFunc['db_free_result']($request); |
||
| 649 | |||
| 650 | // If the drafts were retrieved in reverse order, get them right again. |
||
| 651 | if ($reverse) |
||
| 652 | $context['drafts'] = array_reverse($context['drafts'], true); |
||
| 653 | |||
| 654 | // Menu tab |
||
| 655 | $context[$context['profile_menu_name']]['tab_data'] = array( |
||
| 656 | 'title' => $txt['drafts_show'], |
||
| 657 | 'description' => $txt['drafts_show_desc'], |
||
| 658 | 'icon_class' => 'pm_icons inbox' |
||
| 659 | ); |
||
| 660 | $context['sub_template'] = 'showDrafts'; |
||
| 661 | } |
||
| 662 | |||
| 663 | /** |
||
| 664 | * Show all PM drafts of the current user |
||
| 665 | * Uses the showpmdraft template |
||
| 666 | * Allows for the deleting and loading/editing of drafts |
||
| 667 | * |
||
| 668 | * @param int $memID |
||
| 669 | */ |
||
| 670 | function showPMDrafts($memID = -1) |
||
| 671 | { |
||
| 672 | global $txt, $user_info, $scripturl, $modSettings, $context, $smcFunc, $options; |
||
| 673 | |||
| 674 | // init |
||
| 675 | $draft_type = 1; |
||
| 676 | |||
| 677 | // If just deleting a draft, do it and then redirect back. |
||
| 678 | if (!empty($_REQUEST['delete'])) |
||
| 679 | { |
||
| 680 | checkSession('get'); |
||
| 681 | $id_delete = (int) $_REQUEST['delete']; |
||
| 682 | $start = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0; |
||
| 683 | |||
| 684 | $smcFunc['db_query']('', ' |
||
| 685 | DELETE FROM {db_prefix}user_drafts |
||
| 686 | WHERE id_draft = {int:id_draft} |
||
| 687 | AND id_member = {int:id_member} |
||
| 688 | AND type = {int:draft_type} |
||
| 689 | LIMIT 1', |
||
| 690 | array( |
||
| 691 | 'id_draft' => $id_delete, |
||
| 692 | 'id_member' => $memID, |
||
| 693 | 'draft_type' => $draft_type, |
||
| 694 | ) |
||
| 695 | ); |
||
| 696 | |||
| 697 | // now redirect back to the list |
||
| 698 | redirectexit('action=pm;sa=showpmdrafts;start=' . $start); |
||
| 699 | } |
||
| 700 | |||
| 701 | // perhaps a draft was selected for editing? if so pass this off |
||
| 702 | if (!empty($_REQUEST['id_draft']) && !empty($context['drafts_pm_save']) && $memID == $user_info['id']) |
||
| 703 | { |
||
| 704 | checkSession('get'); |
||
| 705 | $id_draft = (int) $_REQUEST['id_draft']; |
||
| 706 | redirectexit('action=pm;sa=send;id_draft=' . $id_draft); |
||
| 707 | } |
||
| 708 | |||
| 709 | // Default to 10. |
||
| 710 | View Code Duplication | if (empty($_REQUEST['viewscount']) || !is_numeric($_REQUEST['viewscount'])) |
|
| 711 | $_REQUEST['viewscount'] = 10; |
||
| 712 | |||
| 713 | // Get the count of applicable drafts |
||
| 714 | $request = $smcFunc['db_query']('', ' |
||
| 715 | SELECT COUNT(id_draft) |
||
| 716 | FROM {db_prefix}user_drafts |
||
| 717 | WHERE id_member = {int:id_member} |
||
| 718 | AND type={int:draft_type}' . (!empty($modSettings['drafts_keep_days']) ? ' |
||
| 719 | AND poster_time > {int:time}' : ''), |
||
| 720 | array( |
||
| 721 | 'id_member' => $memID, |
||
| 722 | 'draft_type' => $draft_type, |
||
| 723 | 'time' => (!empty($modSettings['drafts_keep_days']) ? (time() - ($modSettings['drafts_keep_days'] * 86400)) : 0), |
||
| 724 | ) |
||
| 725 | ); |
||
| 726 | list ($msgCount) = $smcFunc['db_fetch_row']($request); |
||
| 727 | $smcFunc['db_free_result']($request); |
||
| 728 | |||
| 729 | $maxPerPage = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages']; |
||
| 730 | $maxIndex = $maxPerPage; |
||
| 731 | |||
| 732 | // Make sure the starting place makes sense and construct our friend the page index. |
||
| 733 | $context['page_index'] = constructPageIndex($scripturl . '?action=pm;sa=showpmdrafts', $context['start'], $msgCount, $maxIndex); |
||
| 734 | $context['current_page'] = $context['start'] / $maxIndex; |
||
| 735 | |||
| 736 | // Reverse the query if we're past 50% of the total for better performance. |
||
| 737 | $start = $context['start']; |
||
| 738 | $reverse = $_REQUEST['start'] > $msgCount / 2; |
||
| 739 | View Code Duplication | if ($reverse) |
|
| 740 | { |
||
| 741 | $maxIndex = $msgCount < $context['start'] + $maxPerPage + 1 && $msgCount > $context['start'] ? $msgCount - $context['start'] : $maxPerPage; |
||
| 742 | $start = $msgCount < $context['start'] + $maxPerPage + 1 || $msgCount < $context['start'] + $maxPerPage ? 0 : $msgCount - $context['start'] - $maxPerPage; |
||
| 743 | } |
||
| 744 | |||
| 745 | // Load in this user's PM drafts |
||
| 746 | $request = $smcFunc['db_query']('', ' |
||
| 747 | SELECT |
||
| 748 | ud.id_member, ud.id_draft, ud.body, ud.subject, ud.poster_time, ud.id_reply, ud.to_list |
||
| 749 | FROM {db_prefix}user_drafts AS ud |
||
| 750 | WHERE ud.id_member = {int:current_member} |
||
| 751 | AND type = {int:draft_type}' . (!empty($modSettings['drafts_keep_days']) ? ' |
||
| 752 | AND poster_time > {int:time}' : '') . ' |
||
| 753 | ORDER BY ud.id_draft ' . ($reverse ? 'ASC' : 'DESC') . ' |
||
| 754 | LIMIT {int:start}, {int:max}', |
||
| 755 | array( |
||
| 756 | 'current_member' => $memID, |
||
| 757 | 'draft_type' => $draft_type, |
||
| 758 | 'time' => (!empty($modSettings['drafts_keep_days']) ? (time() - ($modSettings['drafts_keep_days'] * 86400)) : 0), |
||
| 759 | 'start' => $start, |
||
| 760 | 'max' => $maxIndex, |
||
| 761 | ) |
||
| 762 | ); |
||
| 763 | |||
| 764 | // Start counting at the number of the first message displayed. |
||
| 765 | $counter = $reverse ? $context['start'] + $maxIndex + 1 : $context['start']; |
||
| 766 | $context['posts'] = array(); |
||
| 767 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 768 | { |
||
| 769 | // Censor.... |
||
| 770 | if (empty($row['body'])) |
||
| 771 | $row['body'] = ''; |
||
| 772 | |||
| 773 | $row['subject'] = $smcFunc['htmltrim']($row['subject']); |
||
| 774 | if (empty($row['subject'])) |
||
| 775 | $row['subject'] = $txt['no_subject']; |
||
| 776 | |||
| 777 | censorText($row['body']); |
||
| 778 | censorText($row['subject']); |
||
| 779 | |||
| 780 | // BBC-ilize the message. |
||
| 781 | $row['body'] = parse_bbc($row['body'], true, 'draft' . $row['id_draft']); |
||
| 782 | |||
| 783 | // Have they provide who this will go to? |
||
| 784 | $recipients = array( |
||
| 785 | 'to' => array(), |
||
| 786 | 'bcc' => array(), |
||
| 787 | ); |
||
| 788 | $recipient_ids = (!empty($row['to_list'])) ? $smcFunc['json_decode']($row['to_list'], true) : array(); |
||
| 789 | |||
| 790 | // @todo ... this is a bit ugly since it runs an extra query for every message, do we want this? |
||
|
0 ignored issues
–
show
|
|||
| 791 | // at least its only for draft PM's and only the user can see them ... so not heavily used .. still |
||
| 792 | if (!empty($recipient_ids['to']) || !empty($recipient_ids['bcc'])) |
||
| 793 | { |
||
| 794 | $recipient_ids['to'] = array_map('intval', $recipient_ids['to']); |
||
| 795 | $recipient_ids['bcc'] = array_map('intval', $recipient_ids['bcc']); |
||
| 796 | $allRecipients = array_merge($recipient_ids['to'], $recipient_ids['bcc']); |
||
| 797 | |||
| 798 | $request_2 = $smcFunc['db_query']('', ' |
||
| 799 | SELECT id_member, real_name |
||
| 800 | FROM {db_prefix}members |
||
| 801 | WHERE id_member IN ({array_int:member_list})', |
||
| 802 | array( |
||
| 803 | 'member_list' => $allRecipients, |
||
| 804 | ) |
||
| 805 | ); |
||
| 806 | while ($result = $smcFunc['db_fetch_assoc']($request_2)) |
||
| 807 | { |
||
| 808 | $recipientType = in_array($result['id_member'], $recipient_ids['bcc']) ? 'bcc' : 'to'; |
||
| 809 | $recipients[$recipientType][] = $result['real_name']; |
||
| 810 | } |
||
| 811 | $smcFunc['db_free_result']($request_2); |
||
| 812 | } |
||
| 813 | |||
| 814 | // Add the items to the array for template use |
||
| 815 | $context['drafts'][$counter += $reverse ? -1 : 1] = array( |
||
| 816 | 'body' => $row['body'], |
||
| 817 | 'counter' => $counter, |
||
| 818 | 'subject' => $row['subject'], |
||
| 819 | 'time' => timeformat($row['poster_time']), |
||
| 820 | 'timestamp' => forum_time(true, $row['poster_time']), |
||
| 821 | 'id_draft' => $row['id_draft'], |
||
| 822 | 'recipients' => $recipients, |
||
| 823 | 'age' => floor((time() - $row['poster_time']) / 86400), |
||
| 824 | 'remaining' => (!empty($modSettings['drafts_keep_days']) ? floor($modSettings['drafts_keep_days'] - ((time() - $row['poster_time']) / 86400)) : 0), |
||
| 825 | ); |
||
| 826 | } |
||
| 827 | $smcFunc['db_free_result']($request); |
||
| 828 | |||
| 829 | // if the drafts were retrieved in reverse order, then put them in the right order again. |
||
| 830 | if ($reverse) |
||
| 831 | $context['drafts'] = array_reverse($context['drafts'], true); |
||
| 832 | |||
| 833 | // off to the template we go |
||
| 834 | $context['page_title'] = $txt['drafts']; |
||
| 835 | $context['sub_template'] = 'showPMDrafts'; |
||
| 836 | $context['linktree'][] = array( |
||
| 837 | 'url' => $scripturl . '?action=pm;sa=showpmdrafts', |
||
| 838 | 'name' => $txt['drafts'], |
||
| 839 | ); |
||
| 840 | } |
||
| 841 | |||
| 842 | ?> |
Learn more about camelCase.