[ Index ]

PHP Cross Reference of Eventum

title

Body

[close]

/include/ -> class.note.php (source)

   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  }


Generated: Wed Dec 19 21:21:33 2007 Cross-referenced by PHPXref 0.7