/** * Retrieves the next assignee in the given project's round robin queue. * * @access public * @param integer $prj_id The project ID * @return integer The assignee's user ID */ function getNextAssignee($prj_id) { // get the full list of users for the given project list($blackout_start, $blackout_end, $users) = Round_Robin::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 { $user = new Date(Date_API::getCurrentUnixTimestampGMT()); $user->convertTZById($users[$next_usr_id]['timezone']); list($today, $tomorrow) = Round_Robin::getBlackoutDates(&$user, $blackout_start, $blackout_end); $first = new Date($today . ' ' . $blackout_start); $first->setTZById($users[$next_usr_id]['timezone']); $second = new Date($tomorrow . ' ' . $blackout_end); $second->setTZById($users[$next_usr_id]['timezone']); if (Date::compare($first, $user) == -1 && Date::compare($user, $second) == -1) { $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]; $found = 0; 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]; } Round_Robin::markNextAssignee($prj_id, $next_assignee); return $assignee; } }