[ Index ] |
PHP Cross Reference of Eventum |
[Summary view] [Print] [Text view]
1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4 encoding=utf-8: */ 3 // +----------------------------------------------------------------------+ 4 // | Eventum - Issue Tracking System | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 2003, 2004, 2005, 2006, 2007 MySQL AB | 7 // | | 8 // | This program is free software; you can redistribute it and/or modify | 9 // | it under the terms of the GNU General Public License as published by | 10 // | the Free Software Foundation; either version 2 of the License, or | 11 // | (at your option) any later version. | 12 // | | 13 // | This program is distributed in the hope that it will be useful, | 14 // | but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 // | GNU General Public License for more details. | 17 // | | 18 // | You should have received a copy of the GNU General Public License | 19 // | along with this program; if not, write to: | 20 // | | 21 // | Free Software Foundation, Inc. | 22 // | 59 Temple Place - Suite 330 | 23 // | Boston, MA 02111-1307, USA. | 24 // +----------------------------------------------------------------------+ 25 // | Authors: João Prado Maia <jpm@mysql.com> | 26 // +----------------------------------------------------------------------+ 27 // 28 29 require_once (APP_INC_PATH . "class.error_handler.php"); 30 require_once (APP_INC_PATH . "class.validation.php"); 31 require_once (APP_INC_PATH . "class.auth.php"); 32 require_once (APP_INC_PATH . "class.history.php"); 33 require_once (APP_INC_PATH . "class.user.php"); 34 require_once (APP_INC_PATH . "class.misc.php"); 35 require_once (APP_INC_PATH . "class.issue.php"); 36 require_once (APP_INC_PATH . "class.date.php"); 37 require_once (APP_INC_PATH . "class.draft.php"); 38 require_once (APP_INC_PATH . "class.authorized_replier.php"); 39 40 /** 41 * Class to handle the business logic related to adding, updating or 42 * deleting notes from the application. 43 * 44 * @version 1.0 45 * @author João Prado Maia <jpm@mysql.com> 46 */ 47 48 class Note 49 { 50 /** 51 * Returns the next and previous notes associated with the given issue ID 52 * and the currently selected note. 53 * 54 * @access public 55 * @param integer $issue_id The issue ID 56 * @param integer $not_id The currently selected note ID 57 * @return array The next and previous note ID 58 */ 59 function getSideLinks($issue_id, $not_id) 60 { 61 $issue_id = Misc::escapeInteger($issue_id); 62 $not_id = Misc::escapeInteger($not_id); 63 $stmt = "SELECT 64 not_id 65 FROM 66 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 67 WHERE 68 not_iss_id=$issue_id AND 69 not_removed = 0 70 ORDER BY 71 not_created_date ASC"; 72 $res = $GLOBALS["db_api"]->dbh->getCol($stmt); 73 if (PEAR::isError($res)) { 74 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 75 return ""; 76 } else { 77 // COMPAT: the next line requires PHP >= 4.0.5 78 $index = array_search($not_id, $res); 79 if (!empty($res[$index+1])) { 80 $next = $res[$index+1]; 81 } 82 if (!empty($res[$index-1])) { 83 $previous = $res[$index-1]; 84 } 85 return array( 86 "next" => @$next, 87 "previous" => @$previous 88 ); 89 } 90 } 91 92 93 /** 94 * Retrieves the details about a given note. 95 * 96 * @access public 97 * @param integer $note_id The note ID 98 * @return array The note details 99 */ 100 function getDetails($note_id) 101 { 102 $note_id = Misc::escapeInteger($note_id); 103 $stmt = "SELECT 104 " . APP_TABLE_PREFIX . "note.*, 105 not_created_date, 106 not_blocked_message, 107 usr_full_name 108 FROM 109 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note, 110 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "user 111 WHERE 112 not_usr_id=usr_id AND 113 not_id='$note_id'"; 114 $res = $GLOBALS["db_api"]->dbh->getRow($stmt, DB_FETCHMODE_ASSOC); 115 if (PEAR::isError($res)) { 116 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 117 return ''; 118 } else { 119 if (count($res) > 0) { 120 $res['timestamp'] = Date_API::getUnixTimestamp($res['not_created_date'], 'GMT'); 121 $res['not_created_date'] = Date_API::getFormattedDate($res['not_created_date']); 122 if (!empty($res['not_blocked_message'])) { 123 $res['has_blocked_message'] = true; 124 $res["attachments"] = Mime_Helper::getAttachmentCIDs($res['not_blocked_message']); 125 } else { 126 $res['has_blocked_message'] = false; 127 } 128 if (!empty($res["not_unknown_user"])) { 129 $res["not_from"] = $res["not_unknown_user"]; 130 } else { 131 $res["not_from"] = User::getFullName($res['not_usr_id']); 132 } 133 return $res; 134 } else { 135 return ''; 136 } 137 } 138 } 139 140 141 /** 142 * Returns the sequensial note identification number for the given issue. 143 * This is only for display purposes, but has become relied upon by users 144 * as a valid reference number. It is simply a sequence, starting with the 145 * first note created as #1, and each increasing by 1 there after. 146 */ 147 function getNoteSequenceNumber($issue_id, $note_id) 148 { 149 static $issue_note_numbers; 150 151 if (isset($issue_note_numbers[$issue_id][$note_id])) { 152 return $issue_note_numbers[$issue_id][$note_id]; 153 } 154 155 $stmt = "SELECT 156 not_id, 157 not_iss_id 158 FROM 159 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 160 WHERE 161 not_iss_id = " . Misc::escapeInteger($issue_id) . " 162 ORDER BY 163 not_created_date ASC"; 164 $res = $GLOBALS["db_api"]->dbh->getAll($stmt, DB_FETCHMODE_ASSOC); 165 if (PEAR::isError($res)) { 166 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 167 return ""; 168 } 169 170 $sequence_number = 1; 171 foreach ($res as $note_issue_ids) { 172 $issue_note_numbers[$note_issue_ids['not_iss_id']][$note_issue_ids['not_id']] = $sequence_number; 173 $sequence_number++; 174 } 175 176 if (isset($issue_note_numbers[$issue_id][$note_id])) { 177 return $issue_note_numbers[$issue_id][$note_id]; 178 } 179 180 return '#'; 181 } 182 183 184 /** 185 * Returns the blocked email message body associated with the given note ID. 186 * 187 * @access public 188 * @param integer $note_id The note ID 189 * @return string The blocked email message body 190 */ 191 function getBlockedMessage($note_id) 192 { 193 $note_id = Misc::escapeInteger($note_id); 194 $stmt = "SELECT 195 not_blocked_message 196 FROM 197 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 198 WHERE 199 not_id=$note_id"; 200 $res = $GLOBALS["db_api"]->dbh->getOne($stmt); 201 if (PEAR::isError($res)) { 202 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 203 return ''; 204 } else { 205 return $res; 206 } 207 } 208 209 210 /** 211 * Returns the issue ID associated with the given note ID. 212 * 213 * @access public 214 * @param integer $note_id The note ID 215 * @return integer The issue ID 216 */ 217 function getIssueID($note_id) 218 { 219 $note_id = Misc::escapeInteger($note_id); 220 $stmt = "SELECT 221 not_iss_id 222 FROM 223 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 224 WHERE 225 not_id=$note_id"; 226 $res = $GLOBALS["db_api"]->dbh->getOne($stmt); 227 if (PEAR::isError($res)) { 228 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 229 return ''; 230 } else { 231 return $res; 232 } 233 } 234 235 236 /** 237 * Returns the nth note for the specific issue. Sequence starts at 1. 238 * 239 * @access public 240 * @param integer $issue_id The id of the issue. 241 * @param integer $sequence The sequential number of the note. 242 * @return array An array of data containing details about the note. 243 */ 244 function getNoteBySequence($issue_id, $sequence) 245 { 246 $issue_id = Misc::escapeInteger($issue_id); 247 $sequence = Misc::escapeInteger($sequence); 248 $stmt = "SELECT 249 not_id 250 FROM 251 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 252 WHERE 253 not_iss_id = $issue_id AND 254 not_removed = 0 255 ORDER BY 256 not_created_date ASC 257 LIMIT " . ($sequence - 1) . ", 1"; 258 $res = $GLOBALS["db_api"]->dbh->getOne($stmt); 259 if (PEAR::isError($res)) { 260 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 261 return array(); 262 } else { 263 return Note::getDetails($res); 264 } 265 } 266 267 268 /** 269 * Method used to get the unknown_user from the note table for the specified note id. 270 * 271 * @access public 272 * @param integer $note_id The note ID 273 */ 274 function getUnknownUser($note_id) 275 { 276 $note_id = Misc::escapeInteger($note_id); 277 $sql = "SELECT 278 not_unknown_user 279 FROM 280 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 281 WHERE 282 not_id=$note_id"; 283 $res = $GLOBALS["db_api"]->dbh->getOne($sql); 284 if (PEAR::isError($res)) { 285 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 286 return ''; 287 } else { 288 return $res; 289 } 290 } 291 292 293 /** 294 * Method used to save the routed note into a backup directory. 295 * 296 * @access public 297 * @param string $message The full body of the note 298 */ 299 function saveRoutedNote($message) 300 { 301 list($usec,) = explode(" ", microtime()); 302 $filename = date('Y-m-d_H-i-s_') . $usec . '.note.txt'; 303 $file = APP_ROUTED_MAILS_SAVEDIR . 'routed_notes/' . $filename; 304 $fp = @fopen($file, 'w'); 305 @fwrite($fp, $message); 306 @fclose($fp); 307 @chmod($file, 0644); 308 } 309 310 311 /** 312 * Method used to add a note using the user interface form 313 * available in the application. 314 * 315 * @param integer $usr_id The user ID 316 * @param integer $issue_id The issue ID 317 * @param string $unknown_user The email address of a user that sent the blocked email that was turned into this note. Default is false. 318 * @param boolean $log If adding this note should be logged. Default true. 319 * @param boolean $closing If The issue is being closed. Default false 320 * @param boolean $send_notification Whether to send a notification about this note or not 321 * @access public 322 * @return integer the new note id if the insert worked, -1 or -2 otherwise 323 */ 324 function insert($usr_id, $issue_id, $unknown_user = FALSE, $log = true, $closing = false, $send_notification = true) 325 { 326 $issue_id = Misc::escapeInteger($issue_id); 327 328 if (@$_POST['add_extra_recipients'] != 'yes') { 329 $note_cc = array(); 330 } else { 331 $note_cc = $_POST['note_cc']; 332 } 333 // add the poster to the list of people to be subscribed to the notification list 334 // only if there is no 'unknown user' and the note is not blocked 335 $note_cc[] = $usr_id; 336 if (($unknown_user == false) && (@empty($_POST['blocked_msg']))) { 337 for ($i = 0; $i < count($note_cc); $i++) { 338 Notification::subscribeUser($usr_id, $issue_id, $note_cc[$i], Notification::getDefaultActions()); 339 } 340 } 341 if (Validation::isWhitespace($_POST["note"])) { 342 return -2; 343 } 344 if (empty($_POST['message_id'])) { 345 $_POST['message_id'] = Mail_API::generateMessageID(); 346 } 347 $stmt = "INSERT INTO 348 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 349 ( 350 not_iss_id, 351 not_usr_id, 352 not_created_date, 353 not_note, 354 not_title"; 355 if (!@empty($_POST['blocked_msg'])) { 356 $stmt .= ", not_blocked_message"; 357 } 358 $stmt .= ", not_message_id"; 359 if (!@empty($_POST['parent_id'])) { 360 $stmt .= ", not_parent_id"; 361 } 362 if ($unknown_user != false) { 363 $stmt .= ", not_unknown_user"; 364 } 365 $stmt .= " 366 ) VALUES ( 367 $issue_id, 368 $usr_id, 369 '" . Date_API::getCurrentDateGMT() . "', 370 '" . Misc::escapeString($_POST["note"]) . "', 371 '" . Misc::escapeString($_POST["title"]) . "'"; 372 if (!@empty($_POST['blocked_msg'])) { 373 $stmt .= ", '" . Misc::escapeString($_POST['blocked_msg']) . "'"; 374 } 375 $stmt .= ", '" . Misc::escapeString($_POST['message_id']) . "'"; 376 if (!@empty($_POST['parent_id'])) { 377 $stmt .= ", " . Misc::escapeInteger($_POST['parent_id']) . ""; 378 } 379 if ($unknown_user != false) { 380 $stmt .= ", '" . Misc::escapeString($unknown_user) . "'"; 381 } 382 $stmt .= " 383 )"; 384 $res = $GLOBALS["db_api"]->dbh->query($stmt); 385 if (PEAR::isError($res)) { 386 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 387 return -1; 388 } else { 389 $new_note_id = $GLOBALS["db_api"]->get_last_insert_id(); 390 Issue::markAsUpdated($issue_id, 'note'); 391 if ($log) { 392 // need to save a history entry for this 393 History::add($issue_id, $usr_id, History::getTypeID('note_added'), 'Note added by ' . User::getFullName($usr_id)); 394 } 395 // send notifications for the issue being updated 396 if ($send_notification) { 397 $internal_only = true; 398 if ((@$_POST['add_extra_recipients'] != 'yes') && (@count($_POST['note_cc']) > 0)) { 399 Notification::notify($issue_id, 'notes', $new_note_id, $internal_only, $_POST['note_cc']); 400 } else { 401 Notification::notify($issue_id, 'notes', $new_note_id, $internal_only); 402 } 403 Workflow::handleNewNote(Issue::getProjectID($issue_id), $issue_id, $usr_id, $closing, $new_note_id); 404 } 405 // need to return the new note id here so it can 406 // be re-used to associate internal-only attachments 407 return $new_note_id; 408 } 409 } 410 411 412 /** 413 * Method used to remove all notes associated with a specific set 414 * of issues. 415 * 416 * @access public 417 * @param array $ids The list of issues 418 * @return boolean 419 */ 420 function removeByIssues($ids) 421 { 422 $items = implode(", ", $ids); 423 $stmt = "DELETE FROM 424 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 425 WHERE 426 not_iss_id IN ($items)"; 427 $res = $GLOBALS["db_api"]->dbh->query($stmt); 428 if (PEAR::isError($res)) { 429 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 430 return false; 431 } else { 432 return true; 433 } 434 } 435 436 437 /** 438 * Method used to remove a specific note from the application. 439 * 440 * @access public 441 * @param integer $note_id The note ID 442 * @param boolean $log If this event should be logged or not. Default true 443 * @return integer 1 if the removal worked, -1 or -2 otherwise 444 */ 445 function remove($note_id, $log = true) 446 { 447 $note_id = Misc::escapeInteger($note_id); 448 $stmt = "SELECT 449 not_iss_id, 450 not_usr_id, 451 IF(LENGTH(not_blocked_message) > 0, 1, 0) AS has_blocked_message 452 FROM 453 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 454 WHERE 455 not_id=$note_id"; 456 $details = $GLOBALS["db_api"]->dbh->getRow($stmt, DB_FETCHMODE_ASSOC); 457 if (($details['not_usr_id'] != Auth::getUserID()) && ($details['has_blocked_message'] != 1)) { 458 return -2; 459 } 460 461 $stmt = "UPDATE 462 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 463 SET 464 not_removed = 1 465 WHERE 466 not_id=$note_id"; 467 $res = $GLOBALS["db_api"]->dbh->query($stmt); 468 if (PEAR::isError($res)) { 469 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 470 return -1; 471 } else { 472 // also remove any internal-only files associated with this note 473 $stmt = "DELETE FROM 474 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_attachment 475 WHERE 476 iat_not_id=$note_id AND 477 iat_status='internal'"; 478 $res = $GLOBALS["db_api"]->dbh->query($stmt); 479 if (PEAR::isError($res)) { 480 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 481 } 482 483 Issue::markAsUpdated($details['not_iss_id']); 484 if ($log) { 485 // need to save a history entry for this 486 History::add($details['not_iss_id'], Auth::getUserID(), History::getTypeID('note_removed'), 'Note removed by ' . User::getFullName(Auth::getUserID())); 487 } 488 return 1; 489 } 490 } 491 492 493 /** 494 * Method used to get the full listing of notes associated with 495 * a specific issue. 496 * 497 * @access public 498 * @param integer $issue_id The issue ID 499 * @return array The list of notes 500 */ 501 function getListing($issue_id) 502 { 503 $issue_id = Misc::escapeInteger($issue_id); 504 $stmt = "SELECT 505 not_id, 506 not_created_date, 507 not_title, 508 not_usr_id, 509 not_unknown_user, 510 not_has_attachment, 511 IF(LENGTH(not_blocked_message) > 0, 1, 0) AS has_blocked_message, 512 usr_full_name 513 FROM 514 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note, 515 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "user 516 WHERE 517 not_usr_id=usr_id AND 518 not_iss_id=$issue_id AND 519 not_removed = 0 520 ORDER BY 521 not_created_date ASC"; 522 $res = $GLOBALS["db_api"]->dbh->getAll($stmt, DB_FETCHMODE_ASSOC); 523 if (PEAR::isError($res)) { 524 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 525 return ""; 526 } else { 527 // only show the internal notes for users with the appropriate permission level 528 $role_id = Auth::getCurrentRole(); 529 $t = array(); 530 for ($i = 0; $i < count($res); $i++) { 531 if ($role_id < User::getRoleID('standard user')) { 532 continue; 533 } 534 535 // Display not_unknown_user instead of usr_full_name if not null. 536 // This is so the original sender of a blocked email is displayed on the note. 537 if (!empty($res[$i]["not_unknown_user"])) { 538 $res[$i]["usr_full_name"] = $res[$i]["not_unknown_user"]; 539 } 540 541 $res[$i]["not_created_date"] = Date_API::getFormattedDate($res[$i]["not_created_date"]); 542 $t[] = $res[$i]; 543 } 544 return $t; 545 } 546 } 547 548 549 /** 550 * Converts a note to a draft or an email 551 * 552 * @access public 553 * @param $note_id The id of the note 554 * @param $target What the not should be converted too 555 * @param $authorize_sender If the sender should be added to authorized senders list. 556 */ 557 function convertNote($note_id, $target, $authorize_sender = false) 558 { 559 $note_id = Misc::escapeInteger($note_id); 560 $issue_id = Note::getIssueID($note_id); 561 $email_account_id = Email_Account::getEmailAccount(); 562 $blocked_message = Note::getBlockedMessage($note_id); 563 $unknown_user = Note::getUnknownUser($note_id); 564 $structure = Mime_Helper::decode($blocked_message, true, true); 565 $body = Mime_Helper::getMessageBody($structure); 566 $sender_email = strtolower(Mail_API::getEmailAddress($structure->headers['from'])); 567 if ($target == 'email') { 568 if (Mime_Helper::hasAttachments($structure)) { 569 $has_attachments = 1; 570 } else { 571 $has_attachments = 0; 572 } 573 list($blocked_message, $headers) = Mail_API::rewriteThreadingHeaders($issue_id, $blocked_message, @$structure->headers); 574 $t = array( 575 'issue_id' => $issue_id, 576 'ema_id' => $email_account_id, 577 'message_id' => @$structure->headers['message-id'], 578 'date' => Date_API::getCurrentDateGMT(), 579 'from' => @$structure->headers['from'], 580 'to' => @$structure->headers['to'], 581 'cc' => @$structure->headers['cc'], 582 'subject' => @$structure->headers['subject'], 583 'body' => @$body, 584 'full_email' => @$blocked_message, 585 'has_attachment' => $has_attachments, 586 'headers' => $headers 587 ); 588 // need to check for a possible customer association 589 if (!empty($structure->headers['from'])) { 590 $details = Email_Account::getDetails($email_account_id); 591 // check from the associated project if we need to lookup any customers by this email address 592 if (Customer::hasCustomerIntegration($details['ema_prj_id'])) { 593 // check for any customer contact association 594 list($customer_id,) = Customer::getCustomerIDByEmails($details['ema_prj_id'], array($sender_email)); 595 if (!empty($customer_id)) { 596 $t['customer_id'] = $customer_id; 597 } 598 } 599 } 600 if (empty($t['customer_id'])) { 601 $update_type = 'staff response'; 602 $t['customer_id'] = "NULL"; 603 } else { 604 $update_type = 'customer action'; 605 } 606 $res = Support::insertEmail($t, $structure, $sup_id); 607 if ($res != -1) { 608 Support::extractAttachments($issue_id, $structure); 609 // notifications about new emails are always external 610 $internal_only = false; 611 // special case when emails are bounced back, so we don't want to notify the customer about those 612 if (Notification::isBounceMessage($sender_email)) { 613 $internal_only = true; 614 } 615 Notification::notifyNewEmail(Auth::getUserID(), $issue_id, $t, $internal_only, false, '', $sup_id); 616 Issue::markAsUpdated($issue_id, $update_type); 617 Note::remove($note_id, false); 618 History::add($issue_id, Auth::getUserID(), History::getTypeID('note_converted_email'), 619 "Note converted to e-mail (from: " . @$structure->headers['from'] . ") by " . User::getFullName(Auth::getUserID())); 620 // now add sender as an authorized replier 621 if ($authorize_sender) { 622 Authorized_Replier::manualInsert($issue_id, @$structure->headers['from']); 623 } 624 } 625 return $res; 626 } else { 627 // save message as a draft 628 $res = Draft::saveEmail($issue_id, 629 $structure->headers['to'], 630 $structure->headers['cc'], 631 $structure->headers['subject'], 632 $body, 633 false, $unknown_user); 634 // remove the note, if the draft was created successfully 635 if ($res) { 636 Note::remove($note_id, false); 637 History::add($issue_id, Auth::getUserID(), History::getTypeID('note_converted_draft'), 638 "Note converted to draft (from: " . @$structure->headers['from'] . ") by " . User::getFullName(Auth::getUserID())); 639 } 640 return $res; 641 } 642 } 643 644 645 /** 646 * Returns the number of notes by a user in a time range. 647 * 648 * @access public 649 * @param string $usr_id The ID of the user 650 * @param integer $start The timestamp of the start date 651 * @param integer $end The timestanp of the end date 652 * @return integer The number of notes by the user 653 */ 654 function getCountByUser($usr_id, $start, $end) 655 { 656 $stmt = "SELECT 657 COUNT(not_id) 658 FROM 659 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note, 660 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue 661 WHERE 662 not_iss_id = iss_id AND 663 iss_prj_id = " . Auth::getCurrentProject() . " AND 664 not_created_date BETWEEN '$start' AND '$end' AND 665 not_usr_id = $usr_id AND 666 not_removed = 0"; 667 $res = $GLOBALS["db_api"]->dbh->getOne($stmt); 668 if (PEAR::isError($res)) { 669 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 670 return ""; 671 } else { 672 return $res; 673 } 674 } 675 676 677 /** 678 * Method used to mark a note as having attachments associated with it. 679 * 680 * @access public 681 * @param integer $note_id The note ID 682 * @return boolean 683 */ 684 function setAttachmentFlag($note_id) 685 { 686 $stmt = "UPDATE 687 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 688 SET 689 not_has_attachment=1 690 WHERE 691 not_id=$note_id"; 692 $res = $GLOBALS["db_api"]->dbh->query($stmt); 693 if (PEAR::isError($res)) { 694 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 695 return false; 696 } else { 697 return true; 698 } 699 } 700 701 702 /** 703 * Returns the total number of notes associated to the given issue ID. 704 * 705 * @access public 706 * @param string $issue_id The issue ID 707 * @return integer The number of notes 708 */ 709 function getTotalNotesByIssue($issue_id) 710 { 711 $stmt = "SELECT 712 COUNT(*) 713 FROM 714 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 715 WHERE 716 not_iss_id=$issue_id AND 717 not_removed = 0"; 718 $res = $GLOBALS["db_api"]->dbh->getOne($stmt); 719 if (PEAR::isError($res)) { 720 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 721 return 0; 722 } else { 723 return $res; 724 } 725 } 726 727 728 /** 729 * Method used to get the issue ID associated with a given note 730 * message-id. 731 * 732 * @access public 733 * @param string $message_id The message ID 734 * @return integer The issue ID 735 */ 736 function getIssueByMessageID($message_id) 737 { 738 $stmt = "SELECT 739 not_iss_id 740 FROM 741 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 742 WHERE 743 not_message_id='" . Misc::escapeString($message_id) . "'"; 744 $res = $GLOBALS["db_api"]->dbh->getOne($stmt); 745 if (PEAR::isError($res)) { 746 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 747 return ""; 748 } else { 749 return $res; 750 } 751 } 752 753 754 /** 755 * Returns the message-id of the parent note. 756 * 757 * @access public 758 * @param string $msg_id The message ID 759 * @return string The message id of the parent note or false 760 */ 761 function getParentMessageIDbyMessageID($msg_id) 762 { 763 $sql = "SELECT 764 parent.not_message_id 765 FROM 766 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note child, 767 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note parent 768 WHERE 769 parent.not_id = child.not_parent_id AND 770 child.not_message_id = '" . Misc::escapeString($msg_id) . "'"; 771 $res = $GLOBALS["db_api"]->dbh->getOne($sql); 772 if (PEAR::isError($res)) { 773 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 774 return false; 775 } else { 776 if (empty($res)) { 777 return false; 778 } 779 return $res; 780 } 781 782 } 783 784 785 /** 786 * Method used to get the note ID associated with a given note 787 * message-id. 788 * 789 * @access public 790 * @param string $message_id The message ID 791 * @return integer The note ID 792 */ 793 function getIDByMessageID($message_id) 794 { 795 $stmt = "SELECT 796 not_id 797 FROM 798 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 799 WHERE 800 not_message_id='" . Misc::escapeString($message_id) . "'"; 801 $res = $GLOBALS["db_api"]->dbh->getOne($stmt); 802 if (PEAR::isError($res)) { 803 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 804 return false; 805 } else { 806 if (empty($res)) { 807 return false; 808 } else { 809 return $res; 810 } 811 } 812 } 813 814 815 /** 816 * Method used to get the message-ID associated with a given note 817 * id. 818 * 819 * @access public 820 * @param integer $id The ID 821 * @return string The Message-ID 822 */ 823 function getMessageIDbyID($id) 824 { 825 $stmt = "SELECT 826 not_message_id 827 FROM 828 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 829 WHERE 830 not_id=" . Misc::escapeInteger($id); 831 $res = $GLOBALS["db_api"]->dbh->getOne($stmt); 832 if (PEAR::isError($res)) { 833 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 834 return false; 835 } else { 836 if (empty($res)) { 837 return false; 838 } else { 839 return $res; 840 } 841 } 842 } 843 844 845 /** 846 * Checks if a message already is downloaded.. 847 * 848 * @access public 849 * @param string $message_id The Message-ID header 850 * @return boolean 851 */ 852 function exists($message_id) 853 { 854 $sql = "SELECT 855 count(*) 856 FROM 857 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note 858 WHERE 859 not_message_id ='" . Misc::escapeString($message_id) . "'"; 860 $res = $GLOBALS['db_api']->dbh->getOne($sql); 861 if (PEAR::isError($res)) { 862 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); 863 return false; 864 } 865 if ($res > 0) { 866 return true; 867 } else { 868 return false; 869 } 870 } 871 } 872 873 // benchmarking the included file (aka setup time) 874 if (APP_BENCHMARK) { 875 $GLOBALS['bench']->setMarker('Included Note Class'); 876 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Dec 19 21:21:33 2007 | Cross-referenced by PHPXref 0.7 |