/**
  * Modifies an Issue's Reporter.
  *
  * @param   integer $issue_id The id of the issue.
  * @param   string $fullname The id of the user.
  * @param   boolean $add_history If this should be logged.
  * @return int
  */
 public static function update($issue_id, $email, $add_history = true)
 {
     $email = strtolower(Mail_Helper::getEmailAddress($email));
     $usr_id = User::getUserIDByEmail($email, true);
     // If no valid user found reset to system account
     if (!$usr_id) {
         $usr_id = APP_SYSTEM_USER_ID;
     }
     $sql = 'UPDATE
                 {{%issue}}
             SET
                 iss_usr_id = ?
             WHERE
                 iss_id = ?';
     try {
         DB_Helper::getInstance()->query($sql, array($usr_id, $issue_id));
     } catch (DbException $e) {
         return -1;
     }
     if ($add_history) {
         // TRANSLATORS: %1: email, %2: full name
         $current_usr_id = Auth::getUserID();
         History::add($issue_id, $current_usr_id, 'issue_updated', 'Reporter was changed to {email} by {user}', array('email' => $email, 'user' => User::getFullName($current_usr_id)));
     }
     // Add new user to notification list
     if ($usr_id > 0) {
         Notification::subscribeEmail($usr_id, $issue_id, $email, Notification::getDefaultActions());
     }
     return 1;
 }
示例#2
0
 /**
  * Method used to send a confirmation email to the user that is associated
  * to the email address.
  *
  * @param   string $usr_id The user ID
  * @return  void
  */
 public static function sendPasswordConfirmationEmail($usr_id)
 {
     $info = self::getDetails($usr_id);
     // send confirmation email to user
     $hash = md5($info['usr_full_name'] . $info['usr_email'] . Auth::privateKey());
     $tpl = new Template_Helper();
     $tpl->setTemplate('notifications/password_confirmation.tpl.text');
     $tpl->assign(array('app_title' => Misc::getToolCaption(), 'user' => $info, 'hash' => $hash));
     $text_message = $tpl->getTemplateContents();
     $setup = Setup::load();
     $mail = new Mail_Helper();
     // need to make this message MIME based
     $mail->setTextBody($text_message);
     $mail->send($setup['smtp']['from'], $info['usr_email'], APP_SHORT_NAME . ': New Password - Confirmation Required');
 }
示例#3
0
 public function addExtraRecipientsToNotificationList($prj_id, $email, $is_auto_created = false)
 {
     if (empty($email['to']) && !empty($email['sup_to'])) {
         $email['to'] = $email['sup_to'];
     }
     if (empty($email['cc']) && !empty($email['sup_cc'])) {
         $email['cc'] = $email['sup_cc'];
     }
     $project_details = Project::getDetails($prj_id);
     $addresses_not_too_add = explode(',', strtolower($project_details['prj_mail_aliases']));
     array_push($addresses_not_too_add, $project_details['prj_outgoing_sender_email']);
     $addresses = array();
     $to_addresses = Mail_Helper::getEmailAddresses(@$email['to']);
     if (count($to_addresses)) {
         $addresses = $to_addresses;
     }
     $cc_addresses = Mail_Helper::getEmailAddresses(@$email['cc']);
     if (count($cc_addresses)) {
         $addresses = array_merge($addresses, $cc_addresses);
     }
     $subscribers = Notification::getSubscribedEmails($email['issue_id']);
     foreach ($addresses as $address) {
         $address = strtolower($address);
         if (!in_array($address, $subscribers) && !in_array($address, $addresses_not_too_add)) {
             Notification::subscribeEmail(Auth::getUserID(), $email['issue_id'], $address, Notification::getDefaultActions($email['issue_id'], $address, 'add_extra_recipients'));
             if ($is_auto_created) {
                 Notification::notifyAutoCreatedIssue($prj_id, $email['issue_id'], $email['from'], $email['date'], $email['subject'], $address);
             }
         }
     }
 }
示例#4
0
 /**
  * Method used to get a list of emails that are associated with a given
  * project and issue.
  *
  * @param   integer $prj_id The project ID
  * @param   integer $issue_id The issue ID
  * @return  array List of emails
  */
 public static function getAddressBookEmails($prj_id, $issue_id)
 {
     $list = self::getAddressBook($prj_id, $issue_id);
     $emails = array();
     foreach ($list as $address => $name) {
         $emails[] = Mail_Helper::getEmailAddress($address);
     }
     return $emails;
 }
示例#5
0
    $tpl->assign('hide_email_buttons', 'yes');
} else {
    if (!empty($_GET['id'])) {
        $email = Support::getEmailDetails($_GET['ema_id'], $_GET['id']);
        $header = Misc::formatReplyPreamble($email['timestamp'], $email['sup_from']);
        $email['seb_body'] = $header . Misc::formatReply($email['seb_body']);
        $tpl->assign(array('email' => $email, 'parent_email_id' => $_GET['id']));
    }
}
// special handling when someone tries to 'reply' to an issue
if ($cat == 'reply') {
    $details = Issue::getReplyDetails($_GET['issue_id']);
    if ($details != '') {
        $header = Misc::formatReplyPreamble($details['created_date_ts'], $details['reporter']);
        $details['seb_body'] = $header . Misc::formatReply($details['description']);
        $details['sup_from'] = Mail_Helper::getFormattedName($details['reporter'], $details['reporter_email']);
        $tpl->assign(array('email' => $details, 'parent_email_id' => 0, 'extra_title' => 'Issue #' . $_GET['issue_id'] . ': Reply'));
    }
}
if (!empty($issue_id)) {
    // list the available statuses
    $tpl->assign('statuses', Status::getAssocStatusList($prj_id, false));
    $tpl->assign('current_issue_status', Issue::getStatusID($issue_id));
    // set if the current user is allowed to send emails on this issue or not
    $sender_details = User::getDetails($usr_id);
    $tpl->assign('can_send_email', Support::isAllowedToEmail($issue_id, $sender_details['usr_email']));
    $tpl->assign('subscribers', Notification::getSubscribers($issue_id, 'emails'));
}
if (!empty($_GET['ema_id']) || !empty($_POST['ema_id'])) {
    $ema_id = isset($_GET['ema_id']) ? (int) $_GET['ema_id'] : (isset($_POST['ema_id']) ? (int) $_POST['ema_id'] : null);
    $tpl->assign('ema_id', $ema_id);
 /**
  * Returns if the specified user is authorized to reply to this issue.
  *
  * @param   integer $issue_id The id of the issue.
  * @param   string  $email The email address to check.
  * @return  boolean If the specified user is allowed to reply to the issue.
  */
 public static function isAuthorizedReplier($issue_id, $email)
 {
     // XXX: Add caching
     $email = strtolower(Mail_Helper::getEmailAddress($email));
     // first check if this is an actual user or just an email address
     $usr_id = User::getUserIDByEmail($email, true);
     if (!empty($usr_id)) {
         // real user, get id
         $is_usr_authorized = self::isUserAuthorizedReplier($issue_id, $usr_id);
         if ($is_usr_authorized) {
             return true;
         }
         // if user is not authorized by user ID, continue to check by email in case the user account was added
         // after the email address was added to authorized repliers list.
     }
     // not a real user
     $stmt = 'SELECT
                 COUNT(*) AS total
              FROM
                 {{%issue_user_replier}}
              WHERE
                 iur_iss_id=? AND
                 iur_email=?';
     try {
         $res = DB_Helper::getInstance()->getOne($stmt, array($issue_id, $email));
     } catch (DbException $e) {
         return false;
     }
     if ($res > 0) {
         return true;
     } else {
         return false;
     }
 }
示例#7
0
 /**
  * Routes a draft to the correct issue.
  *
  * @param   string $full_message The complete draft.
  * @return  mixed   true or array(ERROR_CODE, ERROR_STRING) in case of failure
  */
 public static function route_drafts($full_message)
 {
     // save the full message for logging purposes
     Draft::saveRoutedMessage($full_message);
     if (preg_match('/^(boundary=).*/m', $full_message)) {
         $pattern = "/(Content-Type: multipart\\/)(.+); ?\r?\n(boundary=)(.*)\$/im";
         $replacement = '$1$2; $3$4';
         $full_message = preg_replace($pattern, $replacement, $full_message);
     }
     // need some validation here
     if (empty($full_message)) {
         return array(self::EX_NOINPUT, ev_gettext('Error: The email message was empty.') . "\n");
     }
     // remove the reply-to: header
     if (preg_match('/^(reply-to:).*/im', $full_message)) {
         $full_message = preg_replace("/^(reply-to:).*\n/im", '', $full_message, 1);
     }
     // check if the draft interface is even supposed to be enabled
     $setup = Setup::get();
     if ($setup['draft_routing']['status'] != 'enabled') {
         return array(self::EX_CONFIG, ev_gettext('Error: The email draft interface is disabled.') . "\n");
     }
     if (empty($setup['draft_routing']['address_prefix'])) {
         return array(self::EX_CONFIG, ev_gettext('Error: Please configure the email address prefix.') . "\n");
     }
     if (empty($setup['draft_routing']['address_host'])) {
         return array(self::EX_CONFIG, ev_gettext('Error: Please configure the email address domain.') . "\n");
     }
     $structure = Mime_Helper::decode($full_message, true, false);
     // find which issue ID this email refers to
     if (isset($structure->headers['to'])) {
         $issue_id = self::getMatchingIssueIDs($structure->headers['to'], 'draft');
     }
     // validation is always a good idea
     if (empty($issue_id) and isset($structure->headers['cc'])) {
         // we need to try the Cc header as well
         $issue_id = self::getMatchingIssueIDs($structure->headers['cc'], 'draft');
     }
     if (empty($issue_id)) {
         return array(self::EX_DATAERR, ev_gettext('Error: The routed email had no associated Eventum issue ID or had an invalid recipient address.') . "\n");
     }
     $prj_id = Issue::getProjectID($issue_id);
     // check if the sender is allowed in this issue' project and if it is an internal user
     $sender_email = strtolower(Mail_Helper::getEmailAddress($structure->headers['from']));
     $sender_usr_id = User::getUserIDByEmail($sender_email, true);
     if (!empty($sender_usr_id)) {
         $sender_role = User::getRoleByUser($sender_usr_id, $prj_id);
         if ($sender_role < User::ROLE_USER) {
             return array(self::EX_NOPERM, ev_gettext("Error: The sender of this email is not allowed in the project associated with issue #{$issue_id}.") . "\n");
         }
     }
     AuthCookie::setAuthCookie(User::getUserIDByEmail($sender_email));
     AuthCookie::setProjectCookie($prj_id);
     $body = $structure->body;
     Draft::saveEmail($issue_id, @$structure->headers['to'], @$structure->headers['cc'], @$structure->headers['subject'], $body, false, false, false);
     // XXX: need to handle attachments coming from drafts as well?
     $usr_id = Auth::getUserID();
     History::add($issue_id, $usr_id, 'draft_routed', 'Draft routed from {from}', array('from' => $structure->headers['from']));
     return true;
 }
 /**
  * Notifies site administrators of the error condition
  *
  * @param  string $notify_msg The formatted error message
  * @param  string $notify_from Sender of the email
  * @param  string $notify_list Email addresses to whom send the error report.
  */
 private static function _notify(&$notify_msg, $notify_from, $notify_list)
 {
     $backtrace = debug_backtrace();
     array_splice($backtrace, 0, 2);
     foreach ($backtrace as $frame) {
         // avoid recursion?
         if (isset($frame['class']) && $frame['class'] == __CLASS__) {
             return;
         }
     }
     $time = time();
     $date = date('Y-m-d H:i:s', $time);
     $msg = "Hello,\n\n";
     $msg .= $notify_msg;
     // this checks that we're not running from commandline (cron for example)
     if (isset($_SERVER['REMOTE_ADDR'])) {
         $proto = 'http';
         if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1)) {
             $proto .= 's';
         }
         $url = "{$proto}://{$_SERVER['HTTP_HOST']}{$_SERVER['SCRIPT_NAME']}";
         if (isset($_SERVER['QUERY_STRING'])) {
             $url .= "?{$_SERVER['QUERY_STRING']}";
         }
         $msg .= "URL: {$url}\n";
         $msg .= "IP: {$_SERVER['REMOTE_ADDR']}\n";
         $login = Auth::getUserLogin();
         if ($login) {
             $msg .= "User: {$login}\n";
         }
         if (!empty($_SERVER['HTTP_REFERER'])) {
             $msg .= "Referer: {$_SERVER['HTTP_REFERER']}\n";
         }
         if (!empty($_SERVER['HTTP_USER_AGENT'])) {
             $msg .= "User-Agent: {$_SERVER['HTTP_USER_AGENT']}\n";
         }
         $msg .= "\n";
     }
     $msg .= "-- \nSincerely yours,\nAutomated Error_Handler Class";
     $max_allowed_packet = DB_Helper::getMaxAllowedPacket();
     // skip error details of an email notification about a query that
     // was bigger than max_allowed_packet + 1024
     if (strlen($msg) > $max_allowed_packet + 1024) {
         return;
     }
     $notify_list = str_replace(';', ',', $notify_list);
     $notify_list = explode(',', $notify_list);
     $subject = APP_SITE_NAME . ' - Error found! - ' . $date;
     foreach ($notify_list as $notify_email) {
         $mail = new Mail_Helper();
         $mail->setTextBody($msg);
         $mail->send($notify_from, $notify_email, $subject, 0, false, 'error');
     }
 }
示例#9
0
<?php

/**
 * Decode note bodies again which have failed to decode unicode html entities
 */
// notes that need to be decoded
$res = $db->getAll('select not_id, not_iss_id, not_is_blocked, not_created_date, not_note, not_full_message from {{%note}} where not_note like ?', array('%&#x00%'));
$render_diff = function ($old, $new) {
    $diff = new Text_Diff(explode(PHP_EOL, $old), explode(PHP_EOL, $new));
    $renderer = new Text_Diff_Renderer_unified();
    return $renderer->render($diff);
};
$now = Date_Helper::getCurrentDateGMT();
foreach ($res as $i => $row) {
    $email = Mime_Helper::decode($row['not_full_message'], true);
    $note = trim($email->body);
    if ($row['not_is_blocked']) {
        $note = Mail_Helper::getCannedBlockedMsgExplanation() . $note;
    }
    $diff = $render_diff($row['not_note'], $note);
    echo "--- issue #{$row['not_iss_id']} {$row['not_created_date']} GMT\n";
    echo "+++ issue #{$row['not_iss_id']} {$now} GMT\n";
    echo $diff;
    $db->query('UPDATE {{%note}} ' . 'SET not_note=? ' . 'WHERE not_id=?', array($note, $row['not_id']));
}
echo count($res), " notes updated\n";
示例#10
0
 /**
  * Connects to the SMTP server and sends the queued message.
  *
  * @param   string $recipient The recipient of this message
  * @param   string $text_headers The full headers of this message
  * @param   string $body The full body of this message
  * @param   string $status The status of this message
  * @return  true, or a PEAR_Error object
  */
 private function _sendEmail($recipient, $text_headers, &$body, $status)
 {
     $header_names = Mime_Helper::getHeaderNames($text_headers);
     $_headers = self::_getHeaders($text_headers, $body);
     $headers = array();
     foreach ($_headers as $lowercase_name => $value) {
         // need to remove the quotes to avoid a parsing problem
         // on senders that have extended characters in the first
         // or last words in their sender name
         if ($lowercase_name == 'from') {
             $value = Mime_Helper::removeQuotes($value);
         }
         $value = Mime_Helper::encode($value);
         // add the quotes back
         if ($lowercase_name == 'from') {
             $value = Mime_Helper::quoteSender($value);
         }
         $headers[$header_names[$lowercase_name]] = $value;
     }
     // remove any Reply-To:/Return-Path: values from outgoing messages
     unset($headers['Reply-To']);
     unset($headers['Return-Path']);
     // mutt sucks, so let's remove the broken Mime-Version header and add the proper one
     if (in_array('Mime-Version', array_keys($headers))) {
         unset($headers['Mime-Version']);
         $headers['MIME-Version'] = '1.0';
     }
     $mail = Mail::factory('smtp', Mail_Helper::getSMTPSettings());
     $res = $mail->send($recipient, $headers, $body);
     if (Misc::isError($res)) {
         Logger::app()->error($res->getMessage(), array('debug' => $res->getDebugInfo()));
         return $res;
     }
     return true;
 }
示例#11
0
 /**
  * Splits the full email into headers and body
  *
  * @param   string $message The full email message
  * @param   boolean $unfold If headers should be unfolded
  * @return  array An array containing the headers and body
  */
 public static function splitHeaderBody($message, $unfold = true)
 {
     if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $message, $match)) {
         return array($unfold ? Mail_Helper::unfold($match[1]) : $match[1], $match[2]);
     }
     return array();
 }
 /**
  * Method used to send an alert to a set of email addresses when
  * a reminder action was triggered, but no action was really
  * taken because no recipients could be found.
  *
  * @param   integer $issue_id The issue ID
  * @param   string $type Which reminder are we trying to send, email or sms
  * @param   array $reminder The reminder details
  * @param   array $action The action details
  * @return  void
  */
 private function _recordNoRecipientError($issue_id, $type, $reminder, $action, $data, $conditions)
 {
     $to = Reminder::_getReminderAlertAddresses();
     if (count($to) > 0) {
         $tpl = new Template_Helper();
         $tpl->setTemplate('reminders/alert_no_recipients.tpl.text');
         $tpl->assign(array('type' => $type, 'data' => $data, 'reminder' => $reminder, 'action' => $action, 'conditions' => $conditions, 'has_customer_integration' => CRM::hasCustomerIntegration(Issue::getProjectID($issue_id))));
         $text_message = $tpl->getTemplateContents();
         foreach ($to as $address) {
             // send email (use PEAR's classes)
             $mail = new Mail_Helper();
             $mail->setTextBody($text_message);
             $setup = $mail->getSMTPSettings();
             // TRANSLATORS: %1 = issue_id, %2 - rma_title
             $subject = ev_gettext('[#%1$s] Reminder Not Triggered: [#%2$s]', $issue_id, $action['rma_title']);
             $mail->send($setup['from'], $address, $subject, 0, $issue_id);
         }
     }
 }
示例#13
0
 /**
  * Method used to break down the email address information and
  * return it for easy manipulation.
  *
  * @param   string $address The email address value
  * @param   boolean $multiple If multiple addresses should be returned
  * @return  array The address information
  */
 public static function getAddressInfo($address, $multiple = false)
 {
     $address = self::fixAddressQuoting($address);
     $addresslist = Mail_Helper::parseAddressList($address, null, null, false);
     if (Misc::isError($addresslist)) {
         return $addresslist;
     }
     if (!$multiple) {
         $addresslist = array($addresslist[0]);
     }
     $returns = array();
     foreach ($addresslist as $row) {
         $returns[] = array('sender_name' => $row->personal, 'email' => $row->mailbox . '@' . $row->host, 'username' => $row->mailbox, 'host' => $row->host);
     }
     if (!$multiple) {
         return $returns[0];
     }
     return $returns;
 }
示例#14
0
 /**
  * Method used to update the details of a given subscription.
  *
  * @param   $issue_id
  * @param   integer $sub_id The subscription ID
  * @param   $email
  * @return  integer 1 if the update worked, -1 otherwise
  */
 public static function update($issue_id, $sub_id, $email)
 {
     $usr_id = User::getUserIDByEmail(strtolower(Mail_Helper::getEmailAddress($email)), true);
     if (!empty($usr_id)) {
         $email = '';
     } else {
         $usr_id = 0;
     }
     $prj_id = Issue::getProjectID($issue_id);
     // call workflow to modify actions or cancel adding this user.
     $actions = array();
     $subscriber_usr_id = false;
     $workflow = Workflow::handleSubscription($prj_id, $issue_id, $subscriber_usr_id, $email, $actions);
     if ($workflow === false) {
         // cancel subscribing the user
         return -2;
     }
     // always set the type of notification to issue-level
     $stmt = "UPDATE\n                    {{%subscription}}\n                 SET\n                    sub_level='issue',\n                    sub_email=?,\n                    sub_usr_id=?\n                 WHERE\n                    sub_id=?";
     try {
         DB_Helper::getInstance()->query($stmt, array($email, $usr_id, $sub_id));
     } catch (DbException $e) {
         return -1;
     }
     $stmt = 'DELETE FROM
                 {{%subscription_type}}
              WHERE
                 sbt_sub_id=?';
     DB_Helper::getInstance()->query($stmt, array($sub_id));
     // now add them all again
     foreach ($_POST['actions'] as $sbt_type) {
         // FIXME: $sbt_type not validated for sane values
         self::addType($sub_id, $sbt_type);
     }
     // need to mark the issue as updated
     Issue::markAsUpdated($issue_id);
     $current_usr_id = Auth::getUserID();
     History::add($issue_id, $current_usr_id, 'notification_updated', "Notification list entry ('{subscriber}') updated by {user}", array('subscriber' => self::getSubscriber($sub_id), 'user' => User::getFullName($current_usr_id)));
     return 1;
 }
示例#15
0
 /**
  * Method used to add a new issue using the normal report form.
  *
  * @return  integer The new issue ID
  */
 public static function createFromPost()
 {
     $keys = array('add_primary_contact', 'attached_emails', 'category', 'contact', 'contact_email', 'contact_extra_emails', 'contact_person_fname', 'contact_person_lname', 'contact_phone', 'contact_timezone', 'contract', 'customer', 'custom_fields', 'description', 'estimated_dev_time', 'group', 'notify_customer', 'notify_senders', 'priority', 'private', 'release', 'severity', 'summary', 'users', 'product', 'product_version', 'expected_resolution_date', 'associated_issues');
     $data = array();
     foreach ($keys as $key) {
         if (isset($_POST[$key])) {
             $data[$key] = $_POST[$key];
         }
     }
     $prj_id = Auth::getCurrentProject();
     $current_usr_id = Auth::getUserID();
     $usr_id = $current_usr_id;
     // if we are creating an issue for a customer, put the
     // main customer contact as the reporter for it
     if (CRM::hasCustomerIntegration($prj_id)) {
         $crm = CRM::getInstance($prj_id);
         $contact_usr_id = User::getUserIDByContactID($data['contact']);
         if (empty($contact_usr_id)) {
             $contact_usr_id = $usr_id;
         }
         $data['reporter'] = $contact_usr_id;
     } else {
         $data['reporter'] = $usr_id;
     }
     $data['msg_id'] = Mail_Helper::generateMessageID();
     $issue_id = self::insertIssue($prj_id, $data);
     if ($issue_id == -1) {
         return -1;
     }
     $has_RR = false;
     $info = User::getNameEmail($usr_id);
     // log the creation of the issue
     History::add($issue_id, $current_usr_id, 'issue_opened', 'Issue opened by {user}', array('user' => User::getFullName($current_usr_id)));
     $clone_iss_id = isset($_POST['clone_iss_id']) ? (int) $_POST['clone_iss_id'] : null;
     if ($clone_iss_id && Access::canCloneIssue($clone_iss_id, $current_usr_id)) {
         History::add($issue_id, $current_usr_id, 'issue_cloned_from', 'Issue cloned from #{issue_id}', array('issue_id' => $clone_iss_id));
         History::add($clone_iss_id, $current_usr_id, 'issue_cloned_to', 'Issue cloned to #{issue_id}', array('issue_id' => $issue_id));
         self::addAssociation($issue_id, $clone_iss_id, $usr_id, true);
     }
     $emails = array();
     if (CRM::hasCustomerIntegration($prj_id)) {
         $customer = $crm->getCustomer($data['customer']);
         $contract = $crm->getContract($data['contract']);
         if (!empty($data['contact_extra_emails']) && count($data['contact_extra_emails']) > 0) {
             $emails = $data['contact_extra_emails'];
         }
         // add the primary contact to the notification list
         if (isset($data['add_primary_contact']) && $data['add_primary_contact'] == 'yes') {
             $contact_email = User::getEmailByContactID($data['contact']);
             if (!empty($contact_email)) {
                 $emails[] = $contact_email;
             }
         }
         // if there are any technical account managers associated with this customer, add these users to the notification list
         $managers = $customer->getEventumAccountManagers();
         foreach ($managers as $manager) {
             $emails[] = $manager['usr_email'];
         }
     }
     // add the reporter to the notification list
     $emails[] = $info['usr_email'];
     $emails = array_unique($emails);
     foreach ($emails as $address) {
         Notification::subscribeEmail($usr_id, $issue_id, $address, Notification::getDefaultActions($issue_id, $address, 'new_issue'));
     }
     // only assign the issue to an user if the associated customer has any technical account managers
     $users = array();
     $has_TAM = false;
     if (CRM::hasCustomerIntegration($prj_id) && count($managers) > 0) {
         foreach ($managers as $manager) {
             if ($manager['cam_type'] == 'intpart') {
                 continue;
             }
             $users[] = $manager['cam_usr_id'];
             self::addUserAssociation($usr_id, $issue_id, $manager['cam_usr_id'], false);
             History::add($issue_id, $usr_id, 'issue_auto_assigned', 'Issue auto-assigned to {assignee} (TAM)', array('assignee' => User::getFullName($manager['cam_usr_id'])));
         }
         $has_TAM = true;
     }
     // now add the user/issue association (aka assignments)
     if (!empty($data['users']) && count($data['users']) > 0) {
         foreach ($data['users'] as $user) {
             $actions = Notification::getDefaultActions($issue_id, User::getEmail($user), 'new_issue');
             Notification::subscribeUser($usr_id, $issue_id, $user, $actions);
             self::addUserAssociation($usr_id, $issue_id, $user);
             if ($user != $usr_id) {
                 $users[] = $user;
             }
         }
     } else {
         // only use the round-robin feature if this new issue was not
         // already assigned to a customer account manager
         if (@count($managers) < 1) {
             $assignee = Round_Robin::getNextAssignee($prj_id);
             // assign the issue to the round robin person
             if (!empty($assignee)) {
                 $users[] = $assignee;
                 self::addUserAssociation($usr_id, $issue_id, $assignee, false);
                 History::add($issue_id, APP_SYSTEM_USER_ID, 'rr_issue_assigned', 'Issue auto-assigned to {assignee} (RR)', array('assignee' => User::getFullName($assignee)));
                 $has_RR = true;
             }
         }
     }
     // set product and version
     if (isset($data['product']) && $data['product'] != '-1') {
         Product::addIssueProductVersion($issue_id, $data['product'], $data['product_version']);
     }
     // process any files being uploaded
     // from ajax upload, attachment file ids
     $iaf_ids = !empty($_POST['iaf_ids']) ? explode(',', $_POST['iaf_ids']) : null;
     // if no iaf_ids passed, perhaps it's old style upload
     // TODO: verify that the uploaded file(s) owner is same as attachment owner.
     if (!$iaf_ids && isset($_FILES['file'])) {
         $iaf_ids = Attachment::addFiles($_FILES['file']);
     }
     if ($iaf_ids) {
         Attachment::attachFiles($issue_id, $usr_id, $iaf_ids, false, 'Files uploaded at issue creation time');
     }
     // need to associate any emails ?
     if (!empty($data['attached_emails'])) {
         $items = explode(',', $data['attached_emails']);
         Support::associate($usr_id, $issue_id, $items);
     }
     // need to notify any emails being converted into issues ?
     if (@count($data['notify_senders']) > 0) {
         $recipients = Notification::notifyEmailConvertedIntoIssue($prj_id, $issue_id, $data['notify_senders'], @$data['customer']);
     } else {
         $recipients = array();
     }
     // need to process any custom fields ?
     if (@count($data['custom_fields']) > 0) {
         foreach ($data['custom_fields'] as $fld_id => $value) {
             Custom_Field::associateIssue($issue_id, $fld_id, $value);
         }
     }
     // also send a special confirmation email to the customer contact
     if (@$data['notify_customer'] == 'yes' && !empty($data['contact'])) {
         $contact = $contract->getContact($data['contact']);
         // also need to pass the list of sender emails already notified,
         // so we can avoid notifying the same person again
         $contact_email = User::getEmailByContactID($data['contact']);
         if (@(!in_array($contact_email, $recipients))) {
             $contact->notifyNewIssue($issue_id);
         }
         // now check for additional emails in contact_extra_emails
         if (@count($data['contact_extra_emails']) > 0) {
             $notification_emails = $data['contact_extra_emails'];
             foreach ($notification_emails as $notification_email) {
                 if (@(!in_array($notification_email, $recipients))) {
                     try {
                         $notification_contact = $crm->getContactByEmail($notification_email);
                         $notification_contact->notifyNewIssue($issue_id);
                     } catch (ContactNotFoundException $e) {
                     }
                 }
             }
         }
     }
     // handle associated issues
     if (isset($data['associated_issues'])) {
         $associated_issues = explode(',', $data['associated_issues']);
         if ($clone_iss_id) {
             $associated_issues[] = $clone_iss_id;
         }
         self::updateAssociatedIssuesRelations($issue_id, $associated_issues);
     }
     Workflow::handleNewIssue($prj_id, $issue_id, $has_TAM, $has_RR);
     // also notify any users that want to receive emails anytime a new issue is created
     Notification::notifyNewIssue($prj_id, $issue_id);
     return $issue_id;
 }
示例#16
0
 /**
  * Connects to the SMTP server and sends the queued message.
  *
  * @param   string $recipient The recipient of this message
  * @param   string $text_headers The full headers of this message
  * @param   string $body The full body of this message
  * @param   string $status The status of this message
  * @return  true, or a PEAR_Error object
  */
 private function _sendEmail($recipient, $text_headers, &$body, $status)
 {
     $header_names = Mime_Helper::getHeaderNames($text_headers);
     $_headers = self::_getHeaders($text_headers, $body);
     $headers = array();
     foreach ($_headers as $lowercase_name => $value) {
         // need to remove the quotes to avoid a parsing problem
         // on senders that have extended characters in the first
         // or last words in their sender name
         if ($lowercase_name == 'from') {
             $value = Mime_Helper::removeQuotes($value);
         }
         $value = Mime_Helper::encode($value);
         // add the quotes back
         if ($lowercase_name == 'from') {
             $value = Mime_Helper::quoteSender($value);
         }
         $headers[$header_names[$lowercase_name]] = $value;
     }
     // remove any Reply-To:/Return-Path: values from outgoing messages
     unset($headers['Reply-To']);
     unset($headers['Return-Path']);
     // mutt sucks, so let's remove the broken Mime-Version header and add the proper one
     if (in_array('Mime-Version', array_keys($headers))) {
         unset($headers['Mime-Version']);
         $headers['MIME-Version'] = '1.0';
     }
     $mail = Mail::factory('smtp', Mail_Helper::getSMTPSettings());
     $res = $mail->send($recipient, $headers, $body);
     if (Misc::isError($res)) {
         // special handling of errors when the mail server is down
         $msg = $res->getMessage();
         $cant_notify = $status == 'error' || strstr($msg, 'unable to connect to smtp server') || stristr($msg, 'Failed to connect to') !== false;
         Error_Handler::logError(array($msg, $res->getDebugInfo()), __FILE__, __LINE__, !$cant_notify);
         return $res;
     }
     return true;
 }
示例#17
0
文件: new.php 项目: korusdipl/eventum
            $crm = CRM::getInstance($prj_id);
            // also need to guess the contact_id from any attached emails
            try {
                $info = $crm->getCustomerInfoFromEmails($prj_id, $item);
                $tpl->assign(array('customer_id' => $info['customer_id'], 'customer_name' => $info['customer_name'], 'contact_id' => $info['contact_id'], 'contact_name' => $info['contact_name'], 'contacts' => $info['contacts']));
            } catch (CRMException $e) {
            }
        }
        // if we are dealing with just one message, use the subject line as the
        // summary for the issue, and the body as the description
        if (count($item) == 1) {
            $email_details = Support::getEmailDetails(Email_Account::getAccountByEmail($item[0]), $item[0]);
            $tpl->assign(array('issue_summary' => $email_details['sup_subject'], 'issue_description' => $email_details['seb_body']));
            // also auto pre-fill the customer contact text fields
            if (CRM::hasCustomerIntegration($prj_id)) {
                $sender_email = Mail_Helper::getEmailAddress($email_details['sup_from']);
                try {
                    $contact = $crm->getContactByEmail($sender_email);
                    $tpl->assign('contact_details', $contact->getDetails());
                } catch (CRMException $e) {
                }
            }
        }
    }
}
$tpl->assign(array('cats' => Category::getAssocList($prj_id), 'priorities' => Priority::getAssocList($prj_id), 'severities' => Severity::getList($prj_id), 'users' => Project::getUserAssocList($prj_id, 'active', User::getRoleID('Customer')), 'releases' => Release::getAssocList($prj_id), 'custom_fields' => Custom_Field::getListByProject($prj_id, 'report_form'), 'max_attachment_size' => Attachment::getMaxAttachmentSize(), 'max_attachment_bytes' => Attachment::getMaxAttachmentSize(true), 'field_display_settings' => Project::getFieldDisplaySettings($prj_id), 'groups' => Group::getAssocList($prj_id), 'products' => Product::getList(false)));
$prefs = Prefs::get($usr_id);
$tpl->assign('user_prefs', $prefs);
$tpl->assign('zones', Date_Helper::getTimezoneList());
if (Auth::getCurrentRole() == User::getRoleID('Customer')) {
    $crm = CRM::getInstance(Auth::getCurrentProject());
示例#18
0
            }
        }
        $tpl->assign('associate_result', $res);
    }
    @$tpl->assign('total_emails', count($_POST['item']));
} else {
    @$tpl->assign('emails', $_GET['item']);
    @$tpl->assign('total_emails', count($_GET['item']));
    $prj_id = Issue::getProjectID($_GET['issue_id']);
    if (CRM::hasCustomerIntegration($prj_id)) {
        // check if the selected emails all have sender email addresses that are associated with the issue' customer
        $crm = CRM::getInstance($prj_id);
        $senders = Support::getSender($_GET['item']);
        $sender_emails = array();
        foreach ($senders as $sender) {
            $email = Mail_Helper::getEmailAddress($sender);
            $sender_emails[$email] = $sender;
        }
        $contract_id = Issue::getContractID($_GET['issue_id']);
        if (!empty($contract_id)) {
            try {
                $contract = $crm->getContract($contract_id);
                // TODOCRM: Active contacts only
                $contact_emails = array_keys($contract->getContactEmailAssocList());
            } catch (CRMException $e) {
                $contact_emails = array();
            }
            $unknown_contacts = array();
            foreach ($sender_emails as $email => $address) {
                if (!@in_array($email, $contact_emails)) {
                    $usr_id = User::getUserIDByEmail($email);
示例#19
0
 /**
  * Converts a note to a draft or an email
  *
  * @param int $note_id The id of the note
  * @param string $target What the note should be converted too (email, etc)
  * @param bool $authorize_sender If $authorize_sender If the sender should be added to authorized senders list.
  * @return int
  */
 public static function convertNote($note_id, $target, $authorize_sender = false)
 {
     $issue_id = self::getIssueID($note_id);
     $email_account_id = Email_Account::getEmailAccount();
     $blocked_message = self::getBlockedMessage($note_id);
     $unknown_user = self::getUnknownUser($note_id);
     $structure = Mime_Helper::decode($blocked_message, true, true);
     $body = $structure->body;
     $sender_email = strtolower(Mail_Helper::getEmailAddress($structure->headers['from']));
     $current_usr_id = Auth::getUserID();
     if ($target == 'email') {
         if (Mime_Helper::hasAttachments($structure)) {
             $has_attachments = 1;
         } else {
             $has_attachments = 0;
         }
         list($blocked_message, $headers) = Mail_Helper::rewriteThreadingHeaders($issue_id, $blocked_message, @$structure->headers);
         $t = array('issue_id' => $issue_id, 'ema_id' => $email_account_id, 'message_id' => @$structure->headers['message-id'], 'date' => Date_Helper::getCurrentDateGMT(), 'from' => @$structure->headers['from'], 'to' => @$structure->headers['to'], 'cc' => @$structure->headers['cc'], 'subject' => @$structure->headers['subject'], 'body' => @$body, 'full_email' => @$blocked_message, 'has_attachment' => $has_attachments, 'headers' => $headers);
         // need to check for a possible customer association
         if (!empty($structure->headers['from'])) {
             $details = Email_Account::getDetails($email_account_id);
             // check from the associated project if we need to lookup any customers by this email address
             if (CRM::hasCustomerIntegration($details['ema_prj_id'])) {
                 $crm = CRM::getInstance($details['ema_prj_id']);
                 // check for any customer contact association
                 try {
                     $contact = $crm->getContactByEmail($sender_email);
                     $issue_contract = $crm->getContract(Issue::getContractID($issue_id));
                     if ($contact->canAccessContract($issue_contract)) {
                         $t['customer_id'] = $issue_contract->getCustomerID();
                     }
                 } catch (CRMException $e) {
                 }
             }
         }
         if (empty($t['customer_id'])) {
             $update_type = 'staff response';
             $t['customer_id'] = null;
         } else {
             $update_type = 'customer action';
         }
         $res = Support::insertEmail($t, $structure, $sup_id);
         if ($res != -1) {
             Support::extractAttachments($issue_id, $structure);
             // notifications about new emails are always external
             $internal_only = false;
             // special case when emails are bounced back, so we don't want to notify the customer about those
             if (Notification::isBounceMessage($sender_email)) {
                 $internal_only = true;
             }
             Notification::notifyNewEmail($current_usr_id, $issue_id, $t, $internal_only, false, '', $sup_id);
             Issue::markAsUpdated($issue_id, $update_type);
             self::remove($note_id, false);
             History::add($issue_id, $current_usr_id, 'note_converted_email', 'Note converted to e-mail (from: {from}) by {user}', array('from' => @$structure->headers['from'], 'user' => User::getFullName($current_usr_id)));
             // now add sender as an authorized replier
             if ($authorize_sender) {
                 Authorized_Replier::manualInsert($issue_id, @$structure->headers['from']);
             }
         }
         return $res;
     }
     // save message as a draft
     $res = Draft::saveEmail($issue_id, $structure->headers['to'], $structure->headers['cc'], $structure->headers['subject'], $body, false, $unknown_user);
     // remove the note, if the draft was created successfully
     if ($res) {
         self::remove($note_id, false);
         $usr_id = $current_usr_id;
         History::add($issue_id, $usr_id, 'note_converted_draft', 'Note converted to draft (from: {from}) by {user}', array('from' => @$structure->headers['from'], 'user' => User::getFullName($current_usr_id)));
     }
     return $res;
 }
示例#20
0
        Misc::setMessage(ev_gettext('Thank you, the internal note was posted successfully.'), Misc::MSG_INFO);
    }
    $tpl->assign('post_result', $res);
    // enter the time tracking entry about this phone support entry
    if (!empty($_POST['time_spent'])) {
        if (isset($_POST['time_summary']) && !empty($_POST['time_summary'])) {
            $summary = (string) $_POST['time_summary'];
        } else {
            $summary = 'Time entry inserted when sending an internal note.';
        }
        $date = (array) $_POST['date'];
        $ttc_id = (int) $_POST['time_category'];
        $time_spent = (int) $_POST['time_spent'];
        Time_Tracking::addTimeEntry($issue_id, $ttc_id, $time_spent, $date, $summary);
    }
    Auth::redirect("post_note.php?cat=post_result&issue_id={$issue_id}&post_result={$res}");
} elseif ($cat == 'reply') {
    if (!empty($_GET['id'])) {
        $note = Note::getDetails($_GET['id']);
        $header = Misc::formatReplyPreamble($note['timestamp'], $note['not_from']);
        $note['not_body'] = $header . Misc::formatReply($note['not_note']);
        $tpl->assign(array('note' => $note, 'parent_note_id' => $_GET['id']));
        $reply_subject = Mail_Helper::removeExcessRe($note['not_title']);
    }
}
if (empty($reply_subject)) {
    // TRANSLATORS: %1 = issue summary
    $reply_subject = ev_gettext('Re: %1$s', $details['iss_summary']);
}
$tpl->assign(array('from' => User::getFromHeader($usr_id), 'users' => Project::getUserAssocList($prj_id, 'active', User::getRoleID('Customer')), 'current_user_prefs' => Prefs::get($usr_id), 'subscribers' => Notification::getSubscribers($issue_id, false, User::getRoleID('Standard User')), 'statuses' => Status::getAssocStatusList($prj_id, false), 'current_issue_status' => Issue::getStatusID($issue_id), 'time_categories' => Time_Tracking::getAssocCategories($prj_id), 'note_category_id' => Time_Tracking::getCategoryId($prj_id, 'Note Discussion'), 'reply_subject' => $reply_subject, 'issue_fields' => Issue_Field::getDisplayData($issue_id, 'post_note')));
$tpl->displayTemplate();