Example #1
0
 /**
  * Returns data for the custom fields weekly report, based on the field and options passed in.
  *
  * @param   integer $fld_id The id of the custom field.
  * @param   array $cfo_ids An array of option ids.
  * @param   string $start_date
  * @param   string $end_date
  * @param   boolean $per_user Show time spent per user
  * @return  array An array of data.
  */
 public static function getCustomFieldWeeklyReport($fld_id, $cfo_ids, $start_date, $end_date, $per_user = false)
 {
     $fld_id = (int) $fld_id;
     $cfo_ids = (array) $cfo_ids;
     // get field values
     $options = Custom_Field::getOptions($fld_id, $cfo_ids);
     $params = array();
     $sql = 'SELECT
                 iss_id,
                 SUM(ttr_time_spent) ttr_time_spent_sum,
                 iss_summary,
                 iss_customer_id,
                 iss_private
            ';
     if ($per_user) {
         $sql .= ', usr_full_name ';
     }
     $sql .= '
              FROM
                 {{%time_tracking}},';
     if ($per_user) {
         $sql .= '{{%user}}, ';
     }
     $sql .= '
                     {{%issue}}
                 WHERE
                     iss_prj_id=? AND
                     ttr_created_date BETWEEN ? AND ? AND
                     ttr_iss_id = iss_id AND
                     ';
     $params[] = Auth::getCurrentProject();
     $params[] = "{$start_date} 00:00:00";
     $params[] = "{$end_date} 23:59:59";
     if ($per_user) {
         $sql .= ' usr_id = ttr_usr_id AND ';
     }
     $sql .= '
                     ttr_iss_id = iss_id
                     ';
     if (count($options) > 0) {
         $ids = array_keys($options);
         $list = DB_Helper::buildList($ids);
         $sql .= " AND (\n                SELECT\n                    count(*)\n                FROM\n                    {{%issue_custom_field}} a\n                WHERE\n                    a.icf_fld_id = ? AND\n                    a.icf_value IN({$list}) AND\n                    a.icf_iss_id = ttr_iss_id\n                ) > 0";
         $params[] = $fld_id;
         $params = array_merge($params, $ids);
     }
     if ($per_user) {
         $sql .= '
                 GROUP BY
                 iss_id, ttr_usr_id';
     } else {
         $sql .= '
                 GROUP BY
                 iss_id';
     }
     try {
         $res = DB_Helper::getInstance()->getAll($sql, $params);
     } catch (DbException $e) {
         return array();
     }
     foreach ($res as &$row) {
         $row['field_value'] = Custom_Field::getDisplayValue($row['iss_id'], $fld_id);
         $row['ttr_time_spent_sum_formatted'] = Misc::getFormattedTime($row['ttr_time_spent_sum'], false);
     }
     return $res;
 }
Example #2
0
 /**
  * Method used to get the details for a specific issue.
  *
  * @param   integer $issue_id The issue ID
  * @param   boolean $force_refresh If the cache should not be used.
  * @return  array The details for the specified issue
  */
 public static function getDetails($issue_id, $force_refresh = false)
 {
     static $returns;
     if (empty($issue_id)) {
         return '';
     }
     if (!empty($returns[$issue_id]) && $force_refresh != true) {
         return $returns[$issue_id];
     }
     $stmt = 'SELECT
                 {{%issue}}.*,
                 prj_title,
                 prc_title,
                 pre_title,
                 pri_title,
                 sev_title,
                 sta_title,
                 sta_abbreviation,
                 sta_color status_color,
                 sta_is_closed
              FROM
                 (
                 {{%issue}},
                 {{%project}}
                 )
              LEFT JOIN
                 {{%project_priority}}
              ON
                 iss_pri_id=pri_id
              LEFT JOIN
                 {{%project_severity}}
              ON
                 iss_sev_id=sev_id
              LEFT JOIN
                 {{%status}}
              ON
                 iss_sta_id=sta_id
              LEFT JOIN
                 {{%project_category}}
              ON
                 iss_prc_id=prc_id
              LEFT JOIN
                 {{%project_release}}
              ON
                 iss_pre_id=pre_id
              WHERE
                 iss_id=? AND
                 iss_prj_id=prj_id';
     try {
         $res = DB_Helper::getInstance()->getRow($stmt, array($issue_id));
     } catch (DbException $e) {
         return '';
     }
     if (empty($res)) {
         return '';
     }
     $created_date_ts = Date_Helper::getUnixTimestamp($res['iss_created_date'], Date_Helper::getDefaultTimezone());
     // get customer information, if any
     if (!empty($res['iss_customer_id']) && CRM::hasCustomerIntegration($res['iss_prj_id'])) {
         $crm = CRM::getInstance($res['iss_prj_id']);
         try {
             $customer = $crm->getCustomer($res['iss_customer_id']);
             $contract = $crm->getContract($res['iss_customer_contract_id']);
             $res['contact_local_time'] = Date_Helper::getFormattedDate(Date_Helper::getCurrentDateGMT(), $res['iss_contact_timezone']);
             $res['customer'] = $customer;
             $res['contract'] = $contract;
             $res['contact'] = $crm->getContact($res['iss_customer_contact_id']);
             // TODOCRM: Deal with incidents
             //                    $res['redeemed_incidents'] = Customer::getRedeemedIncidentDetails($res['iss_prj_id'], $res['iss_id']);
             $max_first_response_time = $contract->getMaximumFirstResponseTime($issue_id);
             $res['max_first_response_time'] = Misc::getFormattedTime($max_first_response_time / 60);
             if (empty($res['iss_first_response_date'])) {
                 $first_response_deadline = $created_date_ts + $max_first_response_time;
                 if (time() <= $first_response_deadline) {
                     $res['max_first_response_time_left'] = Date_Helper::getFormattedDateDiff($first_response_deadline, time());
                 } else {
                     $res['overdue_first_response_time'] = Date_Helper::getFormattedDateDiff(time(), $first_response_deadline);
                 }
             }
         } catch (CRMException $e) {
             // TODOCRM: Log exception?
         }
     }
     $res['iss_original_description'] = $res['iss_description'];
     $res['iss_original_percent_complete'] = $res['iss_percent_complete'];
     $res['iss_description'] = nl2br(htmlspecialchars($res['iss_description']));
     $res['iss_resolution'] = Resolution::getTitle($res['iss_res_id']);
     $res['iss_impact_analysis'] = nl2br(htmlspecialchars($res['iss_impact_analysis']));
     $res['iss_created_date_ts'] = $created_date_ts;
     $res['assignments'] = @implode(', ', array_values(self::getAssignedUsers($res['iss_id'])));
     list($res['authorized_names'], $res['authorized_repliers']) = Authorized_Replier::getAuthorizedRepliers($res['iss_id']);
     $temp = self::getAssignedUsersStatus($res['iss_id']);
     $res['has_inactive_users'] = 0;
     $res['assigned_users'] = array();
     $res['assigned_inactive_users'] = array();
     foreach ($temp as $usr_id => $usr_status) {
         if (!User::isActiveStatus($usr_status)) {
             $res['assigned_inactive_users'][] = $usr_id;
             $res['has_inactive_users'] = 1;
         } else {
             $res['assigned_users'][] = $usr_id;
         }
     }
     if (@in_array(Auth::getUserID(), $res['assigned_users'])) {
         $res['is_current_user_assigned'] = 1;
     } else {
         $res['is_current_user_assigned'] = 0;
     }
     $res['associated_issues_details'] = self::getAssociatedIssuesDetails($res['iss_id']);
     $res['associated_issues'] = self::getAssociatedIssues($res['iss_id']);
     $res['reporter'] = User::getFullName($res['iss_usr_id']);
     if (empty($res['iss_updated_date'])) {
         $res['iss_updated_date'] = $res['iss_created_date'];
     }
     $res['estimated_formatted_time'] = Misc::getFormattedTime($res['iss_dev_time']);
     if (Release::isAssignable($res['iss_pre_id'])) {
         $release = Release::getDetails($res['iss_pre_id']);
         $res['pre_title'] = $release['pre_title'];
         $res['pre_status'] = $release['pre_status'];
     }
     // need to return the list of issues that are duplicates of this one
     $res['duplicates'] = self::getDuplicateList($res['iss_id']);
     $res['duplicates_details'] = self::getDuplicateDetailsList($res['iss_id']);
     // also get the issue title of the duplicated issue
     if (!empty($res['iss_duplicated_iss_id'])) {
         $res['duplicated_issue'] = self::getDuplicatedDetails($res['iss_duplicated_iss_id']);
     }
     // get group information
     if (!empty($res['iss_grp_id'])) {
         $res['group'] = Group::getDetails($res['iss_grp_id']);
     }
     // get quarantine issue
     $res['quarantine'] = self::getQuarantineInfo($res['iss_id']);
     $res['products'] = Product::getProductsByIssue($res['iss_id']);
     $returns[$issue_id] = $res;
     return $res;
 }
Example #3
0
 private function timeActivity()
 {
     $sql = "SELECT\n                    {{%time_tracking}}.*,\n                    ttc_title,\n                    iss_summary,\n                    usr_full_name,\n                    sta_color\n                FROM\n                    {{%time_tracking}},\n                    {{%time_tracking_category}},\n                    {{%issue}},\n                    {{%user}},\n                    {{%status}}\n                WHERE\n                    iss_sta_id = sta_id AND\n                    ttr_iss_id = iss_id AND\n                    ttr_ttc_id = ttc_id AND\n                    ttr_usr_id = usr_id AND\n                    iss_prj_id = ? AND\n";
     $params = array($this->prj_id);
     $this->createWhereClause($sql, $params, 'ttr_created_date', 'ttr_usr_id');
     $res = DB_Helper::getInstance()->getAll($sql, $params);
     $this->processResult($res, 'ttr_created_date', 'ttr_iss_id');
     foreach ($res as &$time) {
         $time['time_spent'] = Misc::getFormattedTime($time['ttr_time_spent'], true);
     }
     return $res;
 }
 /**
  * Method used to add time spent on issue to a list of user issues.
  *
  * @param   array $res User issues
  * @param   string $usr_id The ID of the user this report is for.
  * @param   integer $start The timestamp of the beginning of the report.
  * @param   integer $end The timestamp of the end of this report.
  * @return  void
  */
 public static function fillTimeSpentByIssueAndTime(&$res, $usr_id, $start, $end)
 {
     $issue_ids = array();
     foreach ($res as $row) {
         $issue_ids[] = $row['iss_id'];
     }
     $stmt = 'SELECT
                 ttr_iss_id, sum(ttr_time_spent)
              FROM
                 {{%time_tracking}}
              WHERE
                 ttr_usr_id = ? AND
                 ttr_created_date BETWEEN ? AND ? AND
                 ttr_iss_id in (' . DB_Helper::buildList($issue_ids) . ')
              GROUP BY ttr_iss_id';
     $params = array($usr_id, $start, $end);
     $params = array_merge($params, $issue_ids);
     try {
         $result = DB_Helper::getInstance()->getPair($stmt, $params);
     } catch (DbException $e) {
         return;
     }
     foreach ($res as $key => $item) {
         @($res[$key]['it_spent'] = $result[$item['iss_id']]);
         @($res[$key]['time_spent'] = Misc::getFormattedTime($result[$item['iss_id']], false));
     }
 }
Example #5
0
 /**
  * Method used to get the list of issues to be displayed in the grid layout.
  *
  * @param   integer $prj_id The current project ID
  * @param   array $options The search parameters
  * @param   integer $current_row The current page number
  * @param   integer $max The maximum number of rows per page. 'ALL' for unlimited.
  * @return  array The list of issues to be displayed
  */
 public static function getListing($prj_id, $options, $current_row = 0, $max = 5)
 {
     if (strtoupper($max) == 'ALL') {
         $max = 9999999;
     }
     $start = $current_row * $max;
     // get the current user's role
     $usr_id = Auth::getUserID();
     $role_id = User::getRoleByUser($usr_id, $prj_id);
     $usr_details = User::getDetails($usr_id);
     // get any custom fields that should be displayed
     $custom_fields = Custom_Field::getFieldsToBeListed($prj_id);
     $stmt = 'SELECT
                 iss_id,
                 iss_grp_id,
                 iss_prj_id,
                 iss_sta_id,
                 iss_customer_id,
                 iss_customer_contract_id,
                 iss_created_date,
                 iss_updated_date,
                 iss_last_response_date,
                 iss_closed_date,
                 iss_last_customer_action_date,
                 iss_usr_id,
                 iss_summary,
                 pri_title,
                 prc_title,
                 sta_title,
                 sta_color status_color,
                 sta_id,
                 iqu_status,
                 grp_name,
                 pre_title,
                 iss_last_public_action_date,
                 iss_last_public_action_type,
                 iss_last_internal_action_date,
                 iss_last_internal_action_type,
                 ' . Issue::getLastActionFields() . ",\n                    CASE WHEN iss_last_internal_action_date > iss_last_public_action_date THEN 'internal' ELSE 'public' END AS action_type,\n                    iss_private,\n                    usr_full_name,\n                    iss_percent_complete,\n                    iss_dev_time,\n                    iss_expected_resolution_date,\n                    sev_title\n                 FROM\n                    (\n                    {{%issue}},\n                    {{%user}}";
     // join custom fields if we are searching by custom fields
     if (is_array($options['custom_field']) && count($options['custom_field']) > 0) {
         foreach ($options['custom_field'] as $fld_id => $search_value) {
             if (empty($search_value)) {
                 continue;
             }
             $field = Custom_Field::getDetails($fld_id);
             if ($field['fld_type'] == 'date' && (empty($search_value['Year']) || empty($search_value['Month']) || empty($search_value['Day']))) {
                 continue;
             }
             if ($field['fld_type'] == 'integer' && empty($search_value['value'])) {
                 continue;
             }
             if ($field['fld_type'] == 'multiple') {
                 $search_value = Misc::escapeString($search_value);
                 foreach ($search_value as $cfo_id) {
                     $stmt .= ",\n{{%issue_custom_field}} as cf" . $fld_id . '_' . $cfo_id . "\n";
                 }
             } else {
                 $stmt .= ",\n{{%issue_custom_field}} as cf" . $fld_id . "\n";
             }
         }
     }
     $stmt .= ')';
     // check for the custom fields we want to sort by
     if (strstr($options['sort_by'], 'custom_field') !== false) {
         $fld_id = str_replace('custom_field_', '', $options['sort_by']);
         $stmt .= "\n LEFT JOIN \n\n                    {{%issue_custom_field}} as cf_sort\n                ON\n                    (cf_sort.icf_iss_id = iss_id AND cf_sort.icf_fld_id = {$fld_id}) \n";
     }
     if (!empty($options['users']) || $options['sort_by'] === 'isu_usr_id') {
         $stmt .= '
              LEFT JOIN
                 {{%issue_user}}
              ON
                 isu_iss_id=iss_id';
     }
     if (!empty($usr_details['usr_par_code'])) {
         // restrict partners
         $stmt .= '
              LEFT JOIN
                 {{%issue_partner}}
              ON
                 ipa_iss_id=iss_id';
     }
     if (!empty($options['show_authorized_issues']) || $role_id == User::getRoleID('Reporter') && Project::getSegregateReporters($prj_id)) {
         $stmt .= '
              LEFT JOIN
                 {{%issue_user_replier}}
              ON
                 iur_iss_id=iss_id';
     }
     if (!empty($options['show_notification_list_issues'])) {
         $stmt .= '
              LEFT JOIN
                 {{%subscription}}
              ON
                 sub_iss_id=iss_id';
     }
     if (!empty($options['product'])) {
         $stmt .= '
              LEFT JOIN
                 {{%issue_product_version}}
              ON
                 ipv_iss_id=iss_id';
     }
     $stmt .= "\n                 LEFT JOIN\n                    {{%group}}\n                 ON\n                    iss_grp_id=grp_id\n                 LEFT JOIN\n                    {{%project_category}}\n                 ON\n                    iss_prc_id=prc_id\n                 LEFT JOIN\n                    {{%project_release}}\n                 ON\n                    iss_pre_id = pre_id\n                 LEFT JOIN\n                    {{%status}}\n                 ON\n                    iss_sta_id=sta_id\n                 LEFT JOIN\n                    {{%project_priority}}\n                 ON\n                    iss_pri_id=pri_id\n                 LEFT JOIN\n                    {{%project_severity}}\n                 ON\n                    iss_sev_id=sev_id\n                 LEFT JOIN\n                    {{%issue_quarantine}}\n                 ON\n                    iss_id=iqu_iss_id AND\n                    (iqu_expiration > '" . Date_Helper::getCurrentDateGMT() . "' OR iqu_expiration IS NULL)\n                 WHERE\n                    iss_prj_id= " . Misc::escapeInteger($prj_id);
     $stmt .= self::buildWhereClause($options);
     if (strstr($options['sort_by'], 'custom_field') !== false) {
         $fld_details = Custom_Field::getDetails($fld_id);
         $sort_by = 'cf_sort.' . Custom_Field::getDBValueFieldNameByType($fld_details['fld_type']);
     } else {
         $sort_by = Misc::escapeString($options['sort_by']);
     }
     $stmt .= '
              GROUP BY
                 iss_id
              ORDER BY
                 ' . $sort_by . ' ' . Misc::escapeString($options['sort_order']) . ',
                 iss_id DESC';
     $total_rows = Pager::getTotalRows($stmt);
     $stmt .= '
              LIMIT
                 ' . Misc::escapeInteger($max) . ' OFFSET ' . Misc::escapeInteger($start);
     try {
         $res = DB_Helper::getInstance()->getAll($stmt);
     } catch (DbException $e) {
         return array('list' => null, 'info' => null, 'csv' => null);
     }
     if (count($res) > 0) {
         Issue::getAssignedUsersByIssues($res);
         Time_Tracking::fillTimeSpentByIssues($res);
         // need to get the customer titles for all of these issues...
         if (CRM::hasCustomerIntegration($prj_id)) {
             $crm = CRM::getInstance($prj_id);
             $crm->processListIssuesResult($res);
         }
         Issue::formatLastActionDates($res);
         Issue::getLastStatusChangeDates($prj_id, $res);
     } elseif ($current_row > 0) {
         // if there are no results, and the page is not the first page reset page to one and reload results
         Auth::redirect("list.php?pagerRow=0&rows={$max}");
     }
     $groups = Group::getAssocList($prj_id);
     $categories = Category::getAssocList($prj_id);
     $column_headings = array();
     $columns_to_display = Display_Column::getColumnsToDisplay($prj_id, 'list_issues');
     foreach ($columns_to_display as $col_key => $column) {
         if ($col_key == 'custom_fields' && count($custom_fields) > 0) {
             foreach ($custom_fields as $fld_id => $fld_title) {
                 $column_headings['cstm_' . $fld_id] = $fld_title;
             }
         } else {
             $column_headings[$col_key] = $column['title'];
         }
     }
     $csv[] = @implode("\t", $column_headings);
     if (@$options['hide_excerpts'] != 1 && self::doesBackendSupportExcerpts() == true) {
         $excerpts = self::getFullTextExcerpts();
     }
     foreach ($res as &$row) {
         $issue_id = $row['iss_id'];
         $row['time_spent'] = Misc::getFormattedTime($row['time_spent']);
         $row['iss_created_date'] = Date_Helper::getFormattedDate($row['iss_created_date']);
         $row['iss_expected_resolution_date'] = Date_Helper::getSimpleDate($row['iss_expected_resolution_date'], false);
         $row['excerpts'] = isset($excerpts[$issue_id]) ? $excerpts[$issue_id] : '';
         $fields = array();
         foreach (array_keys($columns_to_display) as $col_key) {
             switch ($col_key) {
                 case 'pri_rank':
                     $col_key = 'pri_title';
                     break;
                 case 'assigned':
                     $col_key = 'assigned_users';
                     break;
                 case 'sta_rank':
                     $col_key = 'sta_title';
                     break;
                 case 'sta_change_date':
                     $col_key = 'status_change_date';
                     break;
                 case 'sev_rank':
                     $col_key = 'sev_title';
                     break;
             }
             if ($col_key == 'custom_fields' && count($custom_fields) > 0) {
                 $custom_field_values = Custom_Field::getListByIssue($prj_id, $row['iss_id']);
                 foreach ($custom_field_values as $this_field) {
                     if (!empty($custom_fields[$this_field['fld_id']])) {
                         $row['custom_field'][$this_field['fld_id']] = $this_field['value'];
                         $fields[] = $this_field['value'];
                     }
                 }
             } else {
                 $fields[] = isset($row[$col_key]) ? $row[$col_key] : '';
             }
         }
         if (CRM::hasCustomerIntegration($prj_id)) {
             // check if current user is a customer and has a per incident contract.
             // if so, check if issue is redeemed.
             if (User::getRoleByUser($usr_id, $prj_id) == User::getRoleID('Customer')) {
                 // TODOCRM: Fix per incident usage
                 //                    if ((Customer::hasPerIncidentContract($prj_id, Issue::getCustomerID($res[$i]['iss_id'])) &&
                 //                            (Customer::isRedeemedIncident($prj_id, $res[$i]['iss_id'])))) {
                 //                        $res[$i]['redeemed'] = true;
                 //                    }
             }
         }
         $csv[] = @implode("\t", $fields);
     }
     $total_pages = ceil($total_rows / $max);
     $last_page = $total_pages - 1;
     return array('list' => $res, 'info' => array('current_page' => $current_row, 'start_offset' => $start, 'end_offset' => $start + count($res), 'total_rows' => $total_rows, 'total_pages' => $total_pages, 'previous_page' => $current_row == 0 ? '-1' : $current_row - 1, 'next_page' => $current_row == $last_page ? '-1' : $current_row + 1, 'last_page' => $last_page, 'custom_fields' => $custom_fields), 'csv' => @implode("\n", $csv));
 }
                 $data['draft'][$i]['to'] = "Notification List";
             }
         }
     }
 }
 if (in_array('time', $_REQUEST['activity_types'])) {
     $sql = "SELECT\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "time_tracking.*,\n                    ttc_title,\n                    iss_summary,\n                    usr_full_name,\n                    sta_color\n                FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "time_tracking,\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "time_tracking_category,\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue,\n                    " . ETEL_USER_TABLE . ",\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "status\n                WHERE\n                    iss_sta_id = sta_id AND\n                    ttr_iss_id = iss_id AND\n                    ttr_ttc_id = ttc_id AND\n                    ttr_usr_id = usr_id AND\n                    iss_prj_id = {$prj_id} AND\n";
     $sql .= createWhereClause('ttr_created_date', 'ttr_usr_id');
     $res = $GLOBALS["db_api"]->dbh->getAll($sql, DB_FETCHMODE_ASSOC);
     if (PEAR::isError($res)) {
         print_r($res);
         Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
     } else {
         $data['time'] = processResult($res, 'ttr_created_date', 'ttr_iss_id');
         for ($i = 0; $i < count($data['time']); $i++) {
             $data['time'][$i]['time_spent'] = Misc::getFormattedTime($data['time'][$i]['ttr_time_spent'], true);
         }
     }
 }
 if (empty($_REQUEST['developer']) && in_array('reminder', $_REQUEST['activity_types'])) {
     $sql = "SELECT\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "reminder_history.*,\n                    iss_summary,\n                    sta_color,\n                    rma_title\n                FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "reminder_history,\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "reminder_action,\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue,\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "status\n                WHERE\n                    iss_sta_id = sta_id AND\n                    rmh_iss_id = iss_id AND\n                    rmh_rma_id = rma_id AND\n                    iss_prj_id = {$prj_id} AND\n";
     $sql .= createWhereClause('rmh_created_date');
     $res = $GLOBALS["db_api"]->dbh->getAll($sql, DB_FETCHMODE_ASSOC);
     if (PEAR::isError($res)) {
         print_r($res);
         Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
     } else {
         $data['reminder'] = processResult($res, 'rmh_created_date', 'rmh_iss_id');
     }
 }
 $tpl->assign(array("unit" => $_REQUEST['unit'], "amount" => $_REQUEST['amount'], "developer" => $_REQUEST['developer'], "start_date" => @$start_date, "end_date" => @$end_date, "data" => $data));
Example #7
0
 /**
  * Method used to get the overall statistics of issues in the system for a
  * given customer.
  *
  * @access  public
  * @param   integer $customer_id The customer ID
  * @return  array The customer related issue statistics
  */
 function getOverallStats($customer_id)
 {
     // don't count customer notes, emails, phone calls
     $stmt = "SELECT\n                    iss_id,\n                    sta_is_closed\n                 FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue\n                 LEFT JOIN\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "status\n                 ON\n                    iss_sta_id=sta_id\n                 WHERE\n                    iss_customer_id={$customer_id}";
     $res = $GLOBALS["db_api"]->dbh->getAssoc($stmt);
     if (PEAR::isError($res) || empty($res) || count($res) == 0) {
         return array('total_issues' => 0, 'total_open' => 0, 'total_closed' => 0, 'total_persons' => 0, 'total_emails' => 0, 'total_calls' => 0, 'average_first_response' => 0, 'average_close' => 0);
     } else {
         $issues = array();
         $open = 0;
         $closed = 0;
         foreach ($res as $issue_id => $status) {
             $issues[] = $issue_id;
             if (empty($status)) {
                 $open++;
             } else {
                 $closed++;
             }
         }
     }
     // get the list of distinct persons from the notification
     // list, phone support and notes tables
     $stmt = "SELECT\n                    iss_id,\n                    sub_usr_id,\n                    not_usr_id,\n                    phs_usr_id\n                 FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue\n                 LEFT JOIN\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note\n                 ON\n                    not_iss_id=iss_id\n                 LEFT JOIN\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "phone_support\n                 ON\n                    phs_iss_id=iss_id\n                 LEFT JOIN\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "subscription\n                 ON\n                    sub_iss_id=iss_id AND\n                    sub_usr_id <> 0 AND\n                    sub_usr_id IS NOT NULL\n                 LEFT JOIN\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "subscription_type\n                 ON\n                    sbt_sub_id=sub_id AND\n                    sbt_type='emails'\n                 WHERE\n                    iss_customer_id={$customer_id}";
     $res = $GLOBALS["db_api"]->dbh->getAll($stmt, DB_FETCHMODE_ASSOC);
     $persons = array();
     for ($i = 0; $i < count($res); $i++) {
         if (!empty($res[$i]['sub_usr_id']) && !in_array($res[$i]['sub_usr_id'], $persons)) {
             $persons[] = $res[$i]['sub_usr_id'];
         }
         if (!empty($res[$i]['not_usr_id']) && !in_array($res[$i]['not_usr_id'], $persons)) {
             $persons[] = $res[$i]['not_usr_id'];
         }
         if (!empty($res[$i]['phs_usr_id']) && !in_array($res[$i]['phs_usr_id'], $persons)) {
             $persons[] = $res[$i]['phs_usr_id'];
         }
     }
     // get list of staff emails
     $stmt = "SELECT\n                    usr_email\n                 FROM\n                    " . ETEL_USER_TABLE . ",\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "project_user,\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue\n                 WHERE\n                    pru_usr_id=usr_id AND\n                    pru_prj_id=iss_prj_id AND\n                    iss_id={$issue_id} AND\n                    pru_role <> " . User::getRoleID('Customer');
     $staff_emails = $GLOBALS["db_api"]->dbh->getCol($stmt);
     $stmt = "SELECT\n                    sup_from\n                 FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "support_email\n                 WHERE\n                    sup_iss_id IN (" . implode(", ", $issues) . ")";
     $emails = $GLOBALS["db_api"]->dbh->getCol($stmt);
     $total_emails = 0;
     foreach ($emails as $address) {
         $email = strtolower(Mail_API::getEmailAddress($address));
         $staff_emails = array_map('strtolower', $staff_emails);
         if (@in_array($email, $staff_emails)) {
             $total_emails++;
         }
     }
     $stmt = "SELECT\n                    COUNT(*)\n                 FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "phone_support\n                 WHERE\n                    phs_iss_id IN (" . implode(", ", $issues) . ")";
     $calls = $GLOBALS["db_api"]->dbh->getOne($stmt);
     $stmt = "SELECT\n                    AVG(UNIX_TIMESTAMP(iss_first_response_date) - UNIX_TIMESTAMP(iss_created_date)) AS first_response_time\n                 FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue\n                 WHERE\n                    iss_id IN (" . implode(", ", $issues) . ")";
     $avg_first_response = $GLOBALS["db_api"]->dbh->getOne($stmt);
     if (!empty($avg_first_response)) {
         // format the average into a number of minutes
         $avg_first_response = $avg_first_response / 60;
     }
     $stmt = "SELECT\n                    AVG(UNIX_TIMESTAMP(iss_closed_date) - UNIX_TIMESTAMP(iss_created_date)) AS closed_time\n                 FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue\n                 WHERE\n                    iss_id IN (" . implode(", ", $issues) . ")";
     $avg_close = $GLOBALS["db_api"]->dbh->getOne($stmt);
     if (!empty($avg_close)) {
         // format the average into a number of minutes
         $avg_close = $avg_close / 60;
     }
     return array('total_issues' => count($issues), 'total_open' => $open, 'total_closed' => $closed, 'total_persons' => count($persons), 'total_emails' => $total_emails, 'total_calls' => (int) $calls, 'average_first_response' => Misc::getFormattedTime($avg_first_response), 'average_close' => Misc::getFormattedTime($avg_close));
 }
 /**
  * Method used to get the full list of requirements and impact analysis for
  * a specific issue.
  *
  * @param   integer $issue_id The issue ID
  * @return  array The full list of requirements
  */
 public static function getListing($issue_id)
 {
     $stmt = 'SELECT
                 isr_id,
                 isr_requirement,
                 isr_dev_time,
                 isr_impact_analysis,
                 A.usr_full_name AS submitter_name,
                 B.usr_full_name AS handler_name
              FROM
                 (
                 {{%issue_requirement}},
                 {{%user}} A
                 )
              LEFT JOIN
                 {{%user}} B
              ON
                 isr_updated_usr_id=B.usr_id
              WHERE
                 isr_iss_id=? AND
                 isr_usr_id=A.usr_id';
     try {
         $res = DB_Helper::getInstance()->getAll($stmt, array($issue_id));
     } catch (DbException $e) {
         return '';
     }
     if (count($res) == 0) {
         return '';
     }
     $prj_id = Issue::getProjectID($issue_id);
     foreach ($res as &$row) {
         $row['isr_requirement'] = Link_Filter::processText($prj_id, nl2br(htmlspecialchars($row['isr_requirement'])));
         $row['isr_impact_analysis'] = Link_Filter::processText($prj_id, nl2br(htmlspecialchars($row['isr_impact_analysis'])));
         $row['formatted_dev_time'] = Misc::getFormattedTime($row['isr_dev_time']);
     }
     return $res;
 }
Example #9
0
 /**
  * Returns the data used by the weekly report.
  *
  * @access  public
  * @param   string $usr_id The ID of the user this report is for.
  * @param   string The start date of this report.
  * @param   string The end date of this report.
  * @param   boolean If closed issues should be separated from other issues.
  * @return  array An array of data containing all the elements of the weekly report.
  */
 function getWeeklyReport($usr_id, $start, $end, $separate_closed = false)
 {
     $usr_id = Misc::escapeInteger($usr_id);
     // figure out timezone
     $user_prefs = Prefs::get($usr_id);
     $tz = @$user_prefs["timezone"];
     $start_dt = new Date();
     $end_dt = new Date();
     // set timezone to that of user.
     $start_dt->setTZById($tz);
     $end_dt->setTZById($tz);
     // set the dates in the users time zone
     $start_dt->setDate($start . " 00:00:00");
     $end_dt->setDate($end . " 23:59:59");
     // convert time to GMT
     $start_dt->toUTC();
     $end_dt->toUTC();
     $start_ts = $start_dt->getDate();
     $end_ts = $end_dt->getDate();
     $time_tracking = Time_Tracking::getSummaryByUser($usr_id, $start_ts, $end_ts);
     // replace spaces in index with _ and calculate total time
     $total_time = 0;
     foreach ($time_tracking as $category => $data) {
         unset($time_tracking[$category]);
         $time_tracking[str_replace(" ", "_", $category)] = $data;
         $total_time += $data["total_time"];
     }
     // get count of issues assigned in week of report.
     $stmt = "SELECT\n                    COUNT(*)\n                 FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue,\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user,\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "status\n                 WHERE\n                    iss_id = isu_iss_id AND\n                    iss_sta_id = sta_id AND\n                    isu_usr_id = {$usr_id} AND\n                    isu_assigned_date BETWEEN '{$start_ts}' AND '{$end_ts}'";
     $newly_assigned = $GLOBALS["db_api"]->dbh->getOne($stmt);
     if (PEAR::isError($newly_assigned)) {
         Error_Handler::logError(array($newly_assigned->getMessage(), $newly_assigned->getDebugInfo()), __FILE__, __LINE__);
     }
     $email_count = array("associated" => Support::getSentEmailCountByUser($usr_id, $start_ts, $end_ts, true), "other" => Support::getSentEmailCountByUser($usr_id, $start_ts, $end_ts, false));
     $data = array("start" => str_replace('-', '.', $start), "end" => str_replace('-', '.', $end), "user" => User::getDetails($usr_id), "group_name" => Group::getName(User::getGroupID($usr_id)), "issues" => History::getTouchedIssuesByUser($usr_id, $start_ts, $end_ts, $separate_closed), "status_counts" => History::getTouchedIssueCountByStatus($usr_id, $start_ts, $end_ts), "new_assigned_count" => $newly_assigned, "time_tracking" => $time_tracking, "email_count" => $email_count, "phone_count" => Phone_Support::getCountByUser($usr_id, $start_ts, $end_ts), "note_count" => Note::getCountByUser($usr_id, $start_ts, $end_ts), "total_time" => Misc::getFormattedTime($total_time, false));
     return $data;
 }
 /**
  * Returns summary information about all time spent by a user in a specified time frame.
  *
  * @access  public
  * @param   string $usr_id The ID of the user this report is for.
  * @param   integer The timestamp of the beginning of the report.
  * @param   integer The timestamp of the end of this report.
  * @return  array An array of data containing information about time trackinge
  */
 function getSummaryByUser($usr_id, $start, $end)
 {
     $stmt = "SELECT\n                    ttc_title,\n                    COUNT(ttr_id) as total,\n                    SUM(ttr_time_spent) as total_time\n                 FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "time_tracking,\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "time_tracking_category\n                 WHERE\n                    ttr_ttc_id = ttc_id AND\n                    ttr_usr_id = " . Misc::escapeInteger($usr_id) . " AND\n                    ttr_created_date BETWEEN '" . Misc::escapeString($start) . "' AND '" . Misc::escapeString($end) . "'\n                 GROUP BY\n                    ttc_title";
     $res = $GLOBALS["db_api"]->dbh->getAssoc($stmt, false, array(), DB_FETCHMODE_ASSOC);
     if (PEAR::isError($res)) {
         Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
         return array();
     } else {
         if (count($res) > 0) {
             foreach ($res as $index => $row) {
                 $res[$index]["formatted_time"] = Misc::getFormattedTime($res[$index]["total_time"], true);
             }
         }
         return $res;
     }
 }
 /**
  * Returns information about time to close and time to first response.
  * 
  * @access  private
  * @return  array Array of counts.
  */
 function getTimeStats()
 {
     // time to close
     $stmt = "SELECT\n                    round(((unix_timestamp(iss_closed_date) - unix_timestamp(iss_created_date)) / 60))\n                 FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue\n                 WHERE\n                    iss_closed_date IS NOT NULL AND \n                    " . $this->getWhereClause("iss_customer_id", array("iss_created_date", "iss_closed_date"));
     $res = $GLOBALS["db_api"]->dbh->getCol($stmt);
     if (PEAR::isError($res)) {
         Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
         return array();
     }
     if (count($res) > 0) {
         $stats = new Math_Stats();
         $stats->setData($res);
         $time_to_close = array("avg" => $stats->mean(), "avg_formatted" => Misc::getFormattedTime($stats->mean()), "median" => $stats->median(), "median_formatted" => Misc::getFormattedTime($stats->median()), "max" => $stats->max(), "max_formatted" => Misc::getFormattedTime($stats->max()), "min" => $stats->min(), "min_formatted" => Misc::getFormattedTime($stats->min()));
     } else {
         $time_to_close = array("avg" => 0, "avg_formatted" => Misc::getFormattedTime(0), "median" => 0, "median_formatted" => Misc::getFormattedTime(0), "max" => 0, "max_formatted" => Misc::getFormattedTime(0), "min" => 0, "min_formatted" => Misc::getFormattedTime(0));
     }
     // time to first response
     $stmt = "SELECT\n                    round(((unix_timestamp(iss_first_response_date) - unix_timestamp(iss_created_date)) / 60))\n                 FROM\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue\n                 WHERE\n                    iss_first_response_date IS NOT NULL AND \n                    " . $this->getWhereClause("iss_customer_id", array("iss_created_date", "iss_closed_date"));
     $res = $GLOBALS["db_api"]->dbh->getCol($stmt);
     if (PEAR::isError($res)) {
         Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
         return array();
     }
     if (count($res) > 0) {
         $stats = new Math_Stats();
         $stats->setData($res);
         $time_to_first_response = array("avg" => $stats->mean(), "avg_formatted" => Misc::getFormattedTime($stats->mean()), "median" => $stats->median(), "median_formatted" => Misc::getFormattedTime($stats->median()), "max" => $stats->max(), "max_formatted" => Misc::getFormattedTime($stats->max()), "min" => $stats->min(), "min_formatted" => Misc::getFormattedTime($stats->min()));
     } else {
         $time_to_first_response = array("avg" => 0, "avg_formatted" => Misc::getFormattedTime(0), "median" => 0, "median_formatted" => Misc::getFormattedTime(0), "max" => 0, "max_formatted" => Misc::getFormattedTime(0), "min" => 0, "min_formatted" => Misc::getFormattedTime(0));
     }
     return array("time_to_close" => $time_to_close, "time_to_first_response" => $time_to_first_response);
 }
Example #12
0
 /**
  * Method used to get the details for a specific issue.
  *
  * @access  public
  * @param   integer $issue_id The issue ID
  * @param   boolean $force_refresh If the cache should not be used.
  * @return  array The details for the specified issue
  */
 function getDetails($issue_id, $force_refresh = false)
 {
     global $HTTP_SERVER_VARS;
     static $returns;
     $issue_id = Misc::escapeInteger($issue_id);
     if (empty($issue_id)) {
         return '';
     }
     if (!empty($returns[$issue_id]) && $force_refresh != true) {
         return $returns[$issue_id];
     }
     $stmt = "SELECT\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue.*,\n                    prj_title,\n                    prc_title,\n                    pre_title,\n                    pri_title,\n                    sta_title,\n                    sta_abbreviation,\n                    sta_color status_color,\n                    sta_is_closed,\n\t\t\t\t\tsup_id as last_sup_id,\n\t\t\t\t\tseb_body as last_seb_body,\n\t\t\t\t\tema_id,\n\t\t\t\t\ten_email as reporter_email\n                 FROM\n                    (\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue,\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "project\n                    )\n                 LEFT JOIN\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "project_priority\n                 ON\n                    iss_pri_id=pri_id\n                 LEFT JOIN\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "status\n                 ON\n                    iss_sta_id=sta_id\n                 LEFT JOIN\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "project_category\n                 ON\n                    iss_prc_id=prc_id\n                 LEFT JOIN\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "project_release\n                 ON\n                    iss_pre_id=pre_id\n                 LEFT JOIN\n                    " . ETEL_USER_TABLE_NOSUB . "\n                 ON\n                    iss_usr_id=en_ID\n                 LEFT JOIN\n                    (\n\t\t\t\t\t\tSelect sup_id,sup_iss_id,seb_body\n\t\t\t\t\t\tfrom " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "support_email\n\t\t\t\t\t\tleft join " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "support_email_body on seb_sup_id = sup_id \n\t\t\t\t\t\twhere sup_iss_id = {$issue_id} order by sup_date desc\n\t\t\t\t\t) as sup\n                 ON\n                    sup_iss_id = iss_id\n                 LEFT JOIN\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "email_account\n                 ON\n                    ema_prj_id = iss_prj_id\n                 WHERE\n                    iss_id={$issue_id} AND\n                    iss_prj_id=prj_id";
     $res = $GLOBALS["db_api"]->dbh->getRow($stmt, DB_FETCHMODE_ASSOC);
     if (PEAR::isError($res)) {
         Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
         return "";
     } else {
         if (empty($res)) {
             return "";
         } else {
             $created_date_ts = Date_API::getUnixTimestamp($res['iss_created_date'], Date_API::getDefaultTimezone());
             // get customer information, if any
             if (!empty($res['iss_customer_id']) && Customer::hasCustomerIntegration($res['iss_prj_id'])) {
                 $res['customer_business_hours'] = Customer::getBusinessHours($res['iss_prj_id'], $res['iss_customer_id']);
                 $res['contact_local_time'] = Date_API::getFormattedDate(Date_API::getCurrentDateGMT(), $res['iss_contact_timezone']);
                 $res['customer_info'] = Customer::getDetails($res['iss_prj_id'], $res['iss_customer_id']);
                 $res['redeemed_incidents'] = Customer::getRedeemedIncidentDetails($res['iss_prj_id'], $res['iss_id']);
                 $max_first_response_time = Customer::getMaximumFirstResponseTime($res['iss_prj_id'], $res['iss_customer_id']);
                 $res['max_first_response_time'] = Misc::getFormattedTime($max_first_response_time / 60);
                 if (empty($res['iss_first_response_date'])) {
                     $first_response_deadline = $created_date_ts + $max_first_response_time;
                     if (Date_API::getCurrentUnixTimestampGMT() <= $first_response_deadline) {
                         $res['max_first_response_time_left'] = Date_API::getFormattedDateDiff($first_response_deadline, Date_API::getCurrentUnixTimestampGMT());
                     } else {
                         $res['overdue_first_response_time'] = Date_API::getFormattedDateDiff(Date_API::getCurrentUnixTimestampGMT(), $first_response_deadline);
                     }
                 }
             }
             $res['iss_original_description'] = $res["iss_description"];
             if (!strstr($HTTP_SERVER_VARS["PHP_SELF"], 'update.php')) {
                 $res["iss_description"] = nl2br(htmlspecialchars($res["iss_description"]));
                 $res["iss_resolution"] = Resolution::getTitle($res["iss_res_id"]);
             }
             $res["iss_impact_analysis"] = nl2br(htmlspecialchars($res["iss_impact_analysis"]));
             $res["iss_created_date"] = Date_API::getFormattedDate($res["iss_created_date"]);
             $res['iss_created_date_ts'] = $created_date_ts;
             $res["assignments"] = @implode(", ", array_values(Issue::getAssignedUsers($res["iss_id"])));
             list($res['authorized_names'], $res['authorized_repliers']) = Authorized_Replier::getAuthorizedRepliers($res["iss_id"]);
             $temp = Issue::getAssignedUsersStatus($res["iss_id"]);
             $res["has_inactive_users"] = 0;
             $res["assigned_users"] = array();
             $res["assigned_inactive_users"] = array();
             foreach ($temp as $usr_id => $usr_status) {
                 if (!User::isActiveStatus($usr_status)) {
                     $res["assigned_inactive_users"][] = $usr_id;
                     $res["has_inactive_users"] = 1;
                 } else {
                     $res["assigned_users"][] = $usr_id;
                 }
             }
             if (@in_array(Auth::getUserID(), $res["assigned_users"])) {
                 $res["is_current_user_assigned"] = 1;
             } else {
                 $res["is_current_user_assigned"] = 0;
             }
             $res["associated_issues_details"] = Issue::getAssociatedIssuesDetails($res["iss_id"]);
             $res["associated_issues"] = Issue::getAssociatedIssues($res["iss_id"]);
             $res["reporter"] = User::getFullName($res["iss_usr_id"]);
             $res["email_list_details"] = Support::getFirstEmailer($issue_id);
             if (!$res["reporter"]) {
                 $first_emailer = Support::getFirstEmailer($issue_id);
                 $res["reporter"] = $first_emailer . " (No Account)";
                 $res["reporter_email"] = preg_replace('/.*<|>/', '', $first_emailer);
             }
             if (empty($res["iss_updated_date"])) {
                 $res["iss_updated_date"] = 'not updated yet';
             } else {
                 $res["iss_updated_date"] = Date_API::getFormattedDate($res["iss_updated_date"]);
             }
             $res["estimated_formatted_time"] = Misc::getFormattedTime($res["iss_dev_time"]);
             if (Release::isAssignable($res["iss_pre_id"])) {
                 $release = Release::getDetails($res["iss_pre_id"]);
                 $res["pre_title"] = $release["pre_title"];
                 $res["pre_status"] = $release["pre_status"];
             }
             // need to return the list of issues that are duplicates of this one
             $res["duplicates"] = Issue::getDuplicateList($res["iss_id"]);
             $res["duplicates_details"] = Issue::getDuplicateDetailsList($res["iss_id"]);
             // also get the issue title of the duplicated issue
             if (!empty($res['iss_duplicated_iss_id'])) {
                 $res['duplicated_issue'] = Issue::getDuplicatedDetails($res['iss_duplicated_iss_id']);
             }
             // get group information
             if (!empty($res["iss_grp_id"])) {
                 $res["group"] = Group::getDetails($res["iss_grp_id"]);
             }
             // get quarantine issue
             $res["quarantine"] = Issue::getQuarantineInfo($res["iss_id"]);
             $returns[$issue_id] = $res;
             return $res;
         }
     }
 }
 /**
  * Method used to get the full list of requirements and impact analysis for
  * a specific issue.
  *
  * @access  public
  * @param   integer $issue_id The issue ID
  * @return  array The full list of requirements
  */
 function getListing($issue_id)
 {
     $stmt = "SELECT\n                    isr_id,\n                    isr_requirement,\n                    isr_dev_time,\n                    isr_impact_analysis,\n                    CONCAT(A.en_firstname,' ', A.en_lastname) AS submitter_name,\n                     CONCAT(B.en_firstname,' ', B.en_lastname) AS handler_name\n                 FROM\n                    (\n                    " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_requirement,\n                    " . ETEL_USER_TABLE_NOSUB . " A\n                    )\n                 LEFT JOIN\n                    " . ETEL_USER_TABLE_NOSUB . " B\n                 ON\n                    isr_updated_usr_id=B.en_ID\n                 WHERE\n                    isr_iss_id=" . Misc::escapeInteger($issue_id) . " AND\n                    isr_usr_id=A.en_ID";
     $res = $GLOBALS["db_api"]->dbh->getAll($stmt, DB_FETCHMODE_ASSOC);
     if (PEAR::isError($res)) {
         Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
         return "";
     } else {
         if (count($res) == 0) {
             return "";
         } else {
             for ($i = 0; $i < count($res); $i++) {
                 $res[$i]["isr_requirement"] = Link_Filter::processText(Issue::getProjectID($issue_id), nl2br(htmlspecialchars($res[$i]["isr_requirement"])));
                 $res[$i]["isr_impact_analysis"] = Link_Filter::processText(Issue::getProjectID($issue_id), nl2br(htmlspecialchars($res[$i]["isr_impact_analysis"])));
                 $res[$i]["formatted_dev_time"] = Misc::getFormattedTime($res[$i]["isr_dev_time"]);
             }
             return $res;
         }
     }
 }
 /**
  * Method used to send a diff-style notification email to the issue
  * subscribers about updates to its attributes.
  *
  * @param   integer $issue_id The issue ID
  * @param   array $old The old issue details
  * @param   array $new The new issue details
  * @param   array $updated_custom_fields An array of the custom fields that were changed.
  */
 public static function notifyIssueUpdated($issue_id, $old, $new, $updated_custom_fields)
 {
     $prj_id = Issue::getProjectID($issue_id);
     $diffs = array();
     if (@$new['keep_assignments'] == 'no') {
         if (empty($new['assignments'])) {
             $new['assignments'] = array();
         }
         $assign_diff = Misc::arrayDiff($old['assigned_users'], $new['assignments']);
         if (count($assign_diff) > 0) {
             $diffs[] = '-' . ev_gettext('Assignment List') . ': ' . $old['assignments'];
             @($diffs[] = '+' . ev_gettext('Assignment List') . ': ' . implode(', ', User::getFullName($new['assignments'])));
         }
     }
     if (isset($new['expected_resolution_date']) && @$old['iss_expected_resolution_date'] != $new['expected_resolution_date']) {
         $diffs[] = '-' . ev_gettext('Expected Resolution Date') . ': ' . $old['iss_expected_resolution_date'];
         $diffs[] = '+' . ev_gettext('Expected Resolution Date') . ': ' . $new['expected_resolution_date'];
     }
     if (isset($new['category']) && $old['iss_prc_id'] != $new['category']) {
         $diffs[] = '-' . ev_gettext('Category') . ': ' . Category::getTitle($old['iss_prc_id']);
         $diffs[] = '+' . ev_gettext('Category') . ': ' . Category::getTitle($new['category']);
     }
     if (isset($new['release']) && $old['iss_pre_id'] != $new['release']) {
         $diffs[] = '-' . ev_gettext('Release') . ': ' . Release::getTitle($old['iss_pre_id']);
         $diffs[] = '+' . ev_gettext('Release') . ': ' . Release::getTitle($new['release']);
     }
     if (isset($new['priority']) && $old['iss_pri_id'] != $new['priority']) {
         $diffs[] = '-' . ev_gettext('Priority') . ': ' . Priority::getTitle($old['iss_pri_id']);
         $diffs[] = '+' . ev_gettext('Priority') . ': ' . Priority::getTitle($new['priority']);
     }
     if (isset($new['severity']) && $old['iss_sev_id'] != $new['severity']) {
         $diffs[] = '-' . ev_gettext('Severity') . ': ' . Severity::getTitle($old['iss_sev_id']);
         $diffs[] = '+' . ev_gettext('Severity') . ': ' . Severity::getTitle($new['severity']);
     }
     if (isset($new['status']) && $old['iss_sta_id'] != $new['status']) {
         $diffs[] = '-' . ev_gettext('Status') . ': ' . Status::getStatusTitle($old['iss_sta_id']);
         $diffs[] = '+' . ev_gettext('Status') . ': ' . Status::getStatusTitle($new['status']);
     }
     if (isset($new['resolution']) && $old['iss_res_id'] != $new['resolution']) {
         $diffs[] = '-' . ev_gettext('Resolution') . ': ' . Resolution::getTitle($old['iss_res_id']);
         $diffs[] = '+' . ev_gettext('Resolution') . ': ' . Resolution::getTitle($new['resolution']);
     }
     if (isset($new['estimated_dev_time']) && $old['iss_dev_time'] != $new['estimated_dev_time']) {
         $diffs[] = '-' . ev_gettext('Estimated Dev. Time') . ': ' . Misc::getFormattedTime($old['iss_dev_time'] * 60);
         $diffs[] = '+' . ev_gettext('Estimated Dev. Time') . ': ' . Misc::getFormattedTime($new['estimated_dev_time'] * 60);
     }
     if (isset($new['summary']) && $old['iss_summary'] != $new['summary']) {
         $diffs[] = '-' . ev_gettext('Summary') . ': ' . $old['iss_summary'];
         $diffs[] = '+' . ev_gettext('Summary') . ': ' . $new['summary'];
     }
     if (isset($new['percent_complete']) && $old['iss_original_percent_complete'] != $new['percent_complete']) {
         $diffs[] = '-' . ev_gettext('Percent complete') . ': ' . $old['iss_original_percent_complete'];
         $diffs[] = '+' . ev_gettext('Percent complete') . ': ' . $new['percent_complete'];
     }
     if (isset($new['description']) && $old['iss_description'] != $new['description']) {
         $old['iss_description'] = explode("\n", $old['iss_original_description']);
         $new['description'] = explode("\n", $new['description']);
         $diff = new Text_Diff($old['iss_description'], $new['description']);
         $renderer = new Text_Diff_Renderer_unified();
         $desc_diff = explode("\n", trim($renderer->render($diff)));
         $diffs[] = 'Description:';
         foreach ($desc_diff as $diff) {
             $diffs[] = $diff;
         }
     }
     $data = Issue::getDetails($issue_id);
     $data['diffs'] = implode("\n", $diffs);
     $data['updated_by'] = User::getFullName(Auth::getUserID());
     $all_emails = array();
     $role_emails = array(User::ROLE_VIEWER => array(), User::ROLE_REPORTER => array(), User::ROLE_CUSTOMER => array(), User::ROLE_USER => array(), User::ROLE_DEVELOPER => array(), User::ROLE_MANAGER => array(), User::ROLE_ADMINISTRATOR => array());
     $users = self::getUsersByIssue($issue_id, 'updated');
     foreach ($users as $user) {
         if (empty($user['sub_usr_id'])) {
             $email = $user['sub_email'];
             // non users are treated as "Viewers" for permission checks
             $role = User::ROLE_VIEWER;
         } else {
             $prefs = Prefs::get($user['sub_usr_id']);
             if (Auth::getUserID() == $user['sub_usr_id'] && (empty($prefs['receive_copy_of_own_action'][$prj_id]) || $prefs['receive_copy_of_own_action'][$prj_id] == false)) {
                 continue;
             }
             $email = User::getFromHeader($user['sub_usr_id']);
             $role = $user['pru_role'];
         }
         // now add it to the list of emails
         if (!empty($email) && !in_array($email, $all_emails)) {
             $all_emails[] = $email;
             $role_emails[$role][] = $email;
         }
     }
     // get additional email addresses to notify
     $additional_emails = Workflow::getAdditionalEmailAddresses($prj_id, $issue_id, 'issue_updated', array('old' => $old, 'new' => $new));
     $data['custom_field_diffs'] = implode("\n", Custom_Field::formatUpdatesToDiffs($updated_custom_fields, User::ROLE_VIEWER));
     foreach ($additional_emails as $email) {
         if (!in_array($email, $all_emails)) {
             $role_emails[User::ROLE_VIEWER][] = $email;
         }
     }
     // send email to each role separately due to custom field restrictions
     foreach ($role_emails as $role => $emails) {
         if (count($emails) > 0) {
             $data['custom_field_diffs'] = implode("\n", Custom_Field::formatUpdatesToDiffs($updated_custom_fields, $role));
             if (!empty($data['custom_field_diffs']) || !empty($data['diffs'])) {
                 self::notifySubscribers($issue_id, $emails, 'updated', $data, ev_gettext('Updated'), false);
             }
         }
     }
 }
 /**
  * Method used to send a diff-style notification email to the issue
  * subscribers about updates to its attributes.
  *
  * @access  public
  * @param   integer $issue_id The issue ID
  * @param   array $old The old issue details
  * @param   array $new The new issue details
  */
 function notifyIssueUpdated($issue_id, $old, $new)
 {
     $diffs = array();
     if (@$new["keep_assignments"] == "no") {
         if (empty($new['assignments'])) {
             $new['assignments'] = array();
         }
         $assign_diff = Misc::arrayDiff($old['assigned_users'], $new['assignments']);
         if (count($assign_diff) > 0) {
             $diffs[] = '-Assignment List: ' . $old['assignments'];
             @($diffs[] = '+Assignment List: ' . implode(', ', User::getFullName($new['assignments'])));
         }
     }
     if (@$old['iss_expected_resolution_date'] != $new['expected_resolution_date']) {
         $diffs[] = '-Expected Resolution Date: ' . $old['iss_expected_resolution_date'];
         $diffs[] = '+Expected Resolution Date: ' . $new['expected_resolution_date'];
     }
     if ($old["iss_prc_id"] != $new["category"]) {
         $diffs[] = '-Category: ' . Category::getTitle($old["iss_prc_id"]);
         $diffs[] = '+Category: ' . Category::getTitle($new["category"]);
     }
     if (@$new["keep"] == "no" && $old["iss_pre_id"] != $new["release"]) {
         $diffs[] = '-Release: ' . Release::getTitle($old["iss_pre_id"]);
         $diffs[] = '+Release: ' . Release::getTitle($new["release"]);
     }
     if ($old["iss_pri_id"] != $new["priority"]) {
         $diffs[] = '-Priority: ' . Priority::getTitle($old["iss_pri_id"]);
         $diffs[] = '+Priority: ' . Priority::getTitle($new["priority"]);
     }
     if ($old["iss_sta_id"] != $new["status"]) {
         $diffs[] = '-Status: ' . Status::getStatusTitle($old["iss_sta_id"]);
         $diffs[] = '+Status: ' . Status::getStatusTitle($new["status"]);
     }
     if ($old["iss_res_id"] != $new["resolution"]) {
         $diffs[] = '-Resolution: ' . Resolution::getTitle($old["iss_res_id"]);
         $diffs[] = '+Resolution: ' . Resolution::getTitle($new["resolution"]);
     }
     if ($old["iss_dev_time"] != $new["estimated_dev_time"]) {
         $diffs[] = '-Estimated Dev. Time: ' . Misc::getFormattedTime($old["iss_dev_time"] * 60);
         $diffs[] = '+Estimated Dev. Time: ' . Misc::getFormattedTime($new["estimated_dev_time"] * 60);
     }
     if ($old["iss_summary"] != $new["summary"]) {
         $diffs[] = '-Summary: ' . $old['iss_summary'];
         $diffs[] = '+Summary: ' . $new['summary'];
     }
     if ($old["iss_description"] != $new["description"]) {
         // need real diff engine here
         include_once 'Text_Diff/Diff.php';
         include_once 'Text_Diff/Diff/Renderer.php';
         include_once 'Text_Diff/Diff/Renderer/unified.php';
         $old['iss_description'] = explode("\n", $old['iss_description']);
         $new['description'] = explode("\n", $new['description']);
         $diff =& new Text_Diff($old["iss_description"], $new["description"]);
         $renderer =& new Text_Diff_Renderer_unified();
         $desc_diff = explode("\n", trim($renderer->render($diff)));
         $diffs[] = 'Description:';
         for ($i = 0; $i < count($desc_diff); $i++) {
             $diffs[] = $desc_diff[$i];
         }
     }
     $emails = array();
     $users = Notification::getUsersByIssue($issue_id, 'updated');
     $user_emails = Project::getUserEmailAssocList(Issue::getProjectID($issue_id), 'active', User::getRoleID('Customer'));
     $user_emails = array_map('strtolower', $user_emails);
     for ($i = 0; $i < count($users); $i++) {
         if (empty($users[$i]["sub_usr_id"])) {
             $email = $users[$i]["sub_email"];
         } else {
             $email = User::getFromHeader($users[$i]["sub_usr_id"]);
         }
         // now add it to the list of emails
         if (!empty($email) && !in_array($email, $emails)) {
             $emails[] = $email;
         }
     }
     $data = Notification::getIssueDetails($issue_id);
     $data['diffs'] = implode("\n", $diffs);
     $data['updated_by'] = User::getFullName(Auth::getUserID());
     Notification::notifySubscribers($issue_id, $emails, 'updated', $data, 'Updated', FALSE);
 }
Example #16
0
 /**
  * Method used to send a diff-style notification email to the issue
  * subscribers about updates to its attributes.
  *
  * @param   integer $issue_id The issue ID
  * @param   array $old The old issue details
  * @param   array $new The new issue details
  */
 public static function notifyIssueUpdated($issue_id, $old, $new)
 {
     $prj_id = Issue::getProjectID($issue_id);
     $diffs = array();
     if (@$new['keep_assignments'] == 'no') {
         if (empty($new['assignments'])) {
             $new['assignments'] = array();
         }
         $assign_diff = Misc::arrayDiff($old['assigned_users'], $new['assignments']);
         if (count($assign_diff) > 0) {
             $diffs[] = '-' . ev_gettext('Assignment List') . ': ' . $old['assignments'];
             @($diffs[] = '+' . ev_gettext('Assignment List') . ': ' . implode(', ', User::getFullName($new['assignments'])));
         }
     }
     if (isset($new['expected_resolution_date']) && @$old['iss_expected_resolution_date'] != $new['expected_resolution_date']) {
         $diffs[] = '-' . ev_gettext('Expected Resolution Date') . ': ' . $old['iss_expected_resolution_date'];
         $diffs[] = '+' . ev_gettext('Expected Resolution Date') . ': ' . $new['expected_resolution_date'];
     }
     if (isset($new['category']) && $old['iss_prc_id'] != $new['category']) {
         $diffs[] = '-' . ev_gettext('Category') . ': ' . Category::getTitle($old['iss_prc_id']);
         $diffs[] = '+' . ev_gettext('Category') . ': ' . Category::getTitle($new['category']);
     }
     if (isset($new['release']) && $old['iss_pre_id'] != $new['release']) {
         $diffs[] = '-' . ev_gettext('Release') . ': ' . Release::getTitle($old['iss_pre_id']);
         $diffs[] = '+' . ev_gettext('Release') . ': ' . Release::getTitle($new['release']);
     }
     if (isset($new['priority']) && $old['iss_pri_id'] != $new['priority']) {
         $diffs[] = '-' . ev_gettext('Priority') . ': ' . Priority::getTitle($old['iss_pri_id']);
         $diffs[] = '+' . ev_gettext('Priority') . ': ' . Priority::getTitle($new['priority']);
     }
     if (isset($new['severity']) && $old['iss_sev_id'] != $new['severity']) {
         $diffs[] = '-' . ev_gettext('Severity') . ': ' . Severity::getTitle($old['iss_sev_id']);
         $diffs[] = '+' . ev_gettext('Severity') . ': ' . Severity::getTitle($new['severity']);
     }
     if (isset($new['status']) && $old['iss_sta_id'] != $new['status']) {
         $diffs[] = '-' . ev_gettext('Status') . ': ' . Status::getStatusTitle($old['iss_sta_id']);
         $diffs[] = '+' . ev_gettext('Status') . ': ' . Status::getStatusTitle($new['status']);
     }
     if (isset($new['resolution']) && $old['iss_res_id'] != $new['resolution']) {
         $diffs[] = '-' . ev_gettext('Resolution') . ': ' . Resolution::getTitle($old['iss_res_id']);
         $diffs[] = '+' . ev_gettext('Resolution') . ': ' . Resolution::getTitle($new['resolution']);
     }
     if (isset($new['estimated_dev_time']) && $old['iss_dev_time'] != $new['estimated_dev_time']) {
         $diffs[] = '-' . ev_gettext('Estimated Dev. Time') . ': ' . Misc::getFormattedTime($old['iss_dev_time'] * 60);
         $diffs[] = '+' . ev_gettext('Estimated Dev. Time') . ': ' . Misc::getFormattedTime($new['estimated_dev_time'] * 60);
     }
     if (isset($new['summary']) && $old['iss_summary'] != $new['summary']) {
         $diffs[] = '-' . ev_gettext('Summary') . ': ' . $old['iss_summary'];
         $diffs[] = '+' . ev_gettext('Summary') . ': ' . $new['summary'];
     }
     if (isset($new['percent_complete']) && $old['iss_original_percent_complete'] != $new['percent_complete']) {
         $diffs[] = '-' . ev_gettext('Percent complete') . ': ' . $old['iss_original_percent_complete'];
         $diffs[] = '+' . ev_gettext('Percent complete') . ': ' . $new['percent_complete'];
     }
     if (isset($new['description']) && $old['iss_description'] != $new['description']) {
         $old['iss_description'] = explode("\n", $old['iss_original_description']);
         $new['description'] = explode("\n", $new['description']);
         $diff = new Text_Diff($old['iss_description'], $new['description']);
         $renderer = new Text_Diff_Renderer_unified();
         $desc_diff = explode("\n", trim($renderer->render($diff)));
         $diffs[] = 'Description:';
         foreach ($desc_diff as $diff) {
             $diffs[] = $diff;
         }
     }
     $emails = array();
     $users = self::getUsersByIssue($issue_id, 'updated');
     $user_emails = Project::getUserEmailAssocList(Issue::getProjectID($issue_id), 'active', User::getRoleID('Customer'));
     // FIXME: $user_emails unused
     $user_emails = array_map(function ($s) {
         return strtolower($s);
     }, $user_emails);
     foreach ($users as $user) {
         if (empty($user['sub_usr_id'])) {
             $email = $user['sub_email'];
         } else {
             $prefs = Prefs::get($user['sub_usr_id']);
             if (Auth::getUserID() == $user['sub_usr_id'] && (empty($prefs['receive_copy_of_own_action'][$prj_id]) || $prefs['receive_copy_of_own_action'][$prj_id] == false)) {
                 continue;
             }
             $email = User::getFromHeader($user['sub_usr_id']);
         }
         // now add it to the list of emails
         if (!empty($email) && !in_array($email, $emails)) {
             $emails[] = $email;
         }
     }
     // get additional email addresses to notify
     $emails = array_merge($emails, Workflow::getAdditionalEmailAddresses($prj_id, $issue_id, 'issue_updated', array('old' => $old, 'new' => $new)));
     $data = Issue::getDetails($issue_id);
     $data['diffs'] = implode("\n", $diffs);
     $data['updated_by'] = User::getFullName(Auth::getUserID());
     self::notifySubscribers($issue_id, $emails, 'updated', $data, ev_gettext('Updated'), false);
 }