/** * Process all commits from trac repository $repository_id matching issue association commits * * @param int $repository_id */ function processCommits($repository_id) { global $db, $scm_name; $sth = $db->prepare('SELECT * FROM revision WHERE repos=? AND message LIKE ?'); $sth->execute(array($repository_id, '%issue%')); $nissues = $ncommits = 0; while ($commit = $sth->fetch(PDO::FETCH_ASSOC)) { $issues = parseIssueIds($commit['message']); if (!$issues) { echo "Skipping {$commit['rev']} (no issue id in commit message): {$commit['message']}\n"; continue; } $ts = Date_Helper::getDateTime((int) ($commit['time'] / 1000000), 'GMT'); $commit_time = $ts->format('Y-m-d H:i:s'); $files = getRevInfo($repository_id, $commit['rev']); foreach ($issues as $issue_id) { foreach ($files as $file) { TracScm::importCheckin($issue_id, $commit_time, $scm_name, $file, $commit['author'], $commit['message']); $ncommits++; } $nissues++; } } echo "Added {$ncommits} commits to {$nissues} issues\n"; }
/** * Returns data on when support emails are sent/received. * * @param string $timezone Timezone to display time in in addition to GMT * @param boolean $graph If the data should be formatted for use in a graph. Default false * @return array An array of data. */ public static function getEmailWorkloadByTimePeriod($timezone, $graph = false) { // get total counts $stmt = 'SELECT hour(sup_date) AS time_period, count(*) as events FROM {{%support_email}} GROUP BY time_period'; try { $total = DB_Helper::getInstance()->fetchAssoc($stmt); } catch (DbException $e) { return array(); } // get all developer email addresses $users = User::getActiveAssocList(Auth::getCurrentProject(), User::getRoleID('customer')); $emails = array(); foreach ($users as $usr_id => $usr_full_name) { $emails[] = User::getFromHeader($usr_id); } // get number of support emails from developers $list = DB_Helper::buildList($emails); $stmt = "SELECT\n hour(sup_date) AS time_period,\n count(*) as events\n FROM\n {{%support_email}}\n WHERE\n sup_from IN({$list})\n GROUP BY\n time_period"; try { $dev_stats = DB_Helper::getInstance()->fetchAssoc($stmt, $emails); } catch (DbException $e) { return array(); } // get total number of developer and customer events and build cust_stats array $dev_count = 0; $cust_count = 0; $cust_stats = array(); for ($i = 0; $i < 24; $i++) { if (empty($dev_stats[$i])) { $dev_stats[$i] = 0; } $cust_stats[$i] = @$total[$i] - @$dev_stats[$i]; $cust_count += @$total[$i] - @$dev_stats[$i]; $dev_count += @$dev_stats[$i]; } $data = array(); $sort_values = array(); for ($i = 0; $i < 24; $i++) { // convert to the users time zone $dt = Date_Helper::getDateTime(mktime($i, 0, 0), 'GMT'); $gmt_time = $dt->format('H:i'); $dt->setTimeZone(new DateTimeZone($timezone)); $hour = $dt->format('H'); $user_time = $dt->format('H:i'); if ($graph) { $data['developer'][$hour] = ''; $data['customer'][$hour] = ''; } else { $data[$i]['display_time_gmt'] = $gmt_time; $data[$i]['display_time_user'] = $user_time; } // use later to find highest value $sort_values['developer'][$i] = $dev_stats[$i]; $sort_values['customer'][$i] = $cust_stats[$i]; if ($graph) { if ($dev_count == 0) { $data['developer'][$hour] = 0; } else { $data['developer'][$hour] = $dev_stats[$i] / $dev_count * 100; } if ($cust_count == 0) { $data['customer'][$hour] = 0; } else { $data['customer'][$hour] = $cust_stats[$i] / $cust_count * 100; } } else { $data[$i]['developer']['count'] = $dev_stats[$i]; if ($dev_count == 0) { $data[$i]['developer']['percentage'] = 0; } else { $data[$i]['developer']['percentage'] = $dev_stats[$i] / $dev_count * 100; } $data[$i]['customer']['count'] = $cust_stats[$i]; if ($cust_count == 0) { $data[$i]['customer']['percentage'] = 0; } else { $data[$i]['customer']['percentage'] = $cust_stats[$i] / $cust_count * 100; } } } if (!$graph) { // get the highest action times foreach ($sort_values as $performer => $values) { arsort($values); reset($values); $data[key($values)][$performer]['rank'] = 1; } } return $data; }
/** * Get date this message was sent. * Uses IMAP Date, and fallbacks to Date header. * * @return DateTime */ public function getMailDate() { $headers = $this->headers; if ($headers->has('X-IMAP-UnixDate')) { // does it have imap date? $date = $headers->get('X-IMAP-UnixDate')->getFieldValue(); } elseif ($headers->has('Date')) { // fallback to date header $date = $headers->get('Date')->getFieldValue(); } else { throw new InvalidArgumentException('No date header for mail'); } return Date_Helper::getDateTime($date); }
/** * Retrieves the next assignee in the given project's round robin queue. * * @param integer $prj_id The project ID * @return integer The assignee's user ID */ public static function getNextAssignee($prj_id) { // get the full list of users for the given project list($blackout_start, $blackout_end, $users) = self::getUsersByProject($prj_id); if (count($users) == 0) { return 0; } else { $user_ids = array_keys($users); $next_usr_id = 0; foreach ($users as $usr_id => $details) { if ($details['is_next']) { $next_usr_id = $usr_id; break; } } // if no user is currently set as the 'next' assignee, // then just get the first one in the list if (empty($next_usr_id)) { $next_usr_id = $user_ids[0]; } // counter to keep the number of times we found an invalid user $ignored_users = 0; // check the blackout hours do { $timezone = $users[$next_usr_id]['timezone']; $user = Date_Helper::getDateTime(false, $timezone); list($today, $tomorrow) = self::getBlackoutDates($user, $blackout_start, $blackout_end); $first = Date_Helper::getDateTime($today . ' ' . $blackout_start, $timezone); $second = Date_Helper::getDateTime($tomorrow . ' ' . $blackout_end, $timezone); if ($first < $user && $user < $second) { $ignored_users++; $current_index = array_search($next_usr_id, $user_ids); // if we reached the end of the list of users and none of them // was a valid one, then just select the first one // however, we want to complete at least one full iteration over the list of users // that is, if we didn't start checking the users in the beginning of the list, // then do another run over the users just in case if ($ignored_users >= count($user_ids) && $current_index == count($user_ids) - 1) { $assignee = $user_ids[0]; break; } // if we reached the end of the list, and we still didn't find an user, // then go back to the beginning of the list one last time if ($current_index == count($user_ids) - 1) { $current_index = 0; $next_usr_id = $user_ids[++$current_index]; continue; } $next_usr_id = $user_ids[++$current_index]; $found = 0; } else { $assignee = $next_usr_id; $found = 1; } } while (!$found); // mark the next user in the list as the 'next' assignment $assignee_index = array_search($assignee, $user_ids); if ($assignee_index == count($user_ids) - 1) { $next_assignee = $user_ids[0]; } else { $next_assignee = $user_ids[++$assignee_index]; } self::markNextAssignee($prj_id, $next_assignee); return $assignee; } }