public function getJPGraphBar($issueActivityMapping) { $user = UserCache::getInstance()->getUser($this->userid); $issue = IssueCache::getInstance()->getIssue($this->bugid); if (NULL != $issue->getTcId()) { $formatedActivityName = substr($this->bugid . " [" . $issue->getTcId() . "] - " . $issue->getSummary(), 0, 50); } else { $formatedActivityName = substr($this->bugid . " - " . $issue->getSummary(), 0, 50); } $formatedActivityInfo = $user->getName(); if ($issue->getCurrentStatus() < $issue->getBugResolvedStatusThreshold()) { $formatedActivityInfo .= " (" . Constants::$statusNames[$issue->getCurrentStatus()] . ")"; } $bar = new GanttBar($this->activityIdx, utf8_decode($formatedActivityName), date('Y-m-d', $this->startTimestamp), date('Y-m-d', $this->endTimestamp), $formatedActivityInfo, 10); // --- colors $bar->SetPattern(GANTT_SOLID, $this->color); $bar->progress->Set($this->progress); $bar->progress->SetPattern(GANTT_SOLID, 'slateblue'); // --- add constrains $relationships = $issue->getRelationships(); $relationships = $relationships['' . Constants::$relationship_constrains]; if (is_array($relationships)) { foreach ($relationships as $bugid) { // Add a constrain from the end of this activity to the start of the activity $bugid $bar->SetConstrain($issueActivityMapping[$bugid], CONSTRAIN_ENDSTART); } } if (self::$logger->isDebugEnabled()) { self::$logger->debug("JPGraphBar bugid={$this->bugid} prj=" . $issue->getProjectId() . " activityIdx={$this->activityIdx}" . " progress={$this->progress} [" . date('Y-m-d', $this->startTimestamp) . " -> " . date('Y-m-d', $this->endTimestamp) . "]"); self::$logger->debug("JPGraphBar bugid={$this->bugid} GanttBar = " . var_export($bar, TRUE)); } return $bar; }
/** * * @param type $relationshipList */ private static function getFormattedRelationshipsInfo($issue) { $relationships = $issue->getRelationships(); $relationshipsInfo = array(); foreach ($relationships as $relType => $bugids) { $typeLabel = Issue::getRelationshipLabel($relType); foreach ($bugids as $bugid) { $relatedIssue = IssueCache::getInstance()->getIssue($bugid); $relationshipsInfo["{$bugid}"] = array('url' => Tools::issueInfoURL($bugid), 'relationship' => $typeLabel, 'status' => $relatedIssue->getCurrentStatusName(), 'progress' => round(100 * $relatedIssue->getProgress())); } } ksort($relationshipsInfo); return $relationshipsInfo; }
/** * * @param type $relationshipList */ private static function getFormattedRelationshipsInfo($issue) { $relationships = $issue->getRelationships(); $relationshipsInfo = array(); foreach ($relationships as $relType => $bugids) { $typeLabel = Issue::getRelationshipLabel($relType); foreach ($bugids as $bugid) { $relatedIssue = IssueCache::getInstance()->getIssue($bugid); $summary = htmlspecialchars(preg_replace('![\\t\\r\\n]+!', ' ', $relatedIssue->getSummary())); $relationshipsInfo["{$bugid}"] = array('url' => Tools::issueInfoURL($bugid), 'relationship' => $typeLabel, 'status' => $relatedIssue->getCurrentStatusName(), 'progress' => round(100 * $relatedIssue->getProgress()), 'summary' => $summary); } } ksort($relationshipsInfo); return $relationshipsInfo; }
private function getMonthlyActivityReport(array $tracks) { $userList = array(); // first is 'All', then one per user #$userList['0'] = array(); // All users together foreach ($tracks as $t) { $userid = $t->getUserId(); $bugid = $t->getIssueId(); if (!array_key_exists($userid, $userList)) { $user = UserCache::getInstance()->getUser($userid); $userList["{$userid}"] = array('name' => $user->getName(), 'realname' => $user->getRealname(), 'elapsedInPeriod' => 0, 'tasks' => array()); #echo "new user $userid<br>"; } if (!array_key_exists($bugid, $userList["{$userid}"]['tasks'])) { try { $issue = IssueCache::getInstance()->getIssue($bugid); $project = ProjectCache::getInstance()->getProject($issue->getProjectId()); if (!$project->isSideTasksProject(array($this->teamid)) && !$project->isExternalTasksProject()) { $tooltipAttr = $issue->getTooltipItems($this->teamid, $this->session_userid); $infoTooltip = Tools::imgWithTooltip('images/b_info.png', $tooltipAttr); $progress = round(100 * $issue->getProgress()); $backlog = $issue->getBacklog(); } else { $infoTooltip = NULL; $progress = NULL; $backlog = NULL; } $projectName = $issue->getProjectName(); $summary = SmartyTools::getIssueDescription($bugid, $issue->getTcId(), $issue->getSummary()); } catch (Exception $e) { $infoTooltip = NULL; $progress = NULL; $backlog = NULL; $projectName = '<span class="error_font">' . T_('Error') . '</span>'; $summary = $bugid . ' : <span class="error_font">' . T_('Error: Task not found in Mantis DB !') . '</span>'; } $userList["{$userid}"]['tasks']["{$bugid}"] = array('id' => $bugid, 'infoTooltip' => $infoTooltip, 'projectName' => $projectName, 'summary' => $summary, 'progress' => $progress, 'backlog' => $backlog, 'elapsedInPeriod' => 0); #echo "new UserTask $bugid : ".$issue->getSummary()."<br>"; } $userList["{$userid}"]['tasks']["{$bugid}"]['elapsedInPeriod'] += $t->getDuration(); $userList["{$userid}"]['elapsedInPeriod'] += $t->getDuration(); #echo "user $userid task $bugid elapsedInPeriod = ".$userList["$userid"]['tasks']["$bugid"]['elapsedInPeriod'].'<br>'; } #var_dump($userList); return $userList; }
/** * fiches analyzed dont BI non renseignes * fiches analyzed dont RAE non renseignes * @return ConsistencyError[] */ public function checkAnalyzed() { // CoDev FDJ custom, defined in Mantis $status_analyzed = Config::getVariableKeyFromValue(Config::id_statusNames, 'analyzed'); $status_accepted = Config::getVariableKeyFromValue(Config::id_statusNames, 'accepted'); $status_deferred = Config::getVariableKeyFromValue(Config::id_statusNames, 'deferred'); $FDJ_teamid = Config::getInstance()->getValue(Config::id_ClientTeamid); $cerrList = array(); // select all issues which current status is 'analyzed' $query = "SELECT * " . "FROM `mantis_bug_table` " . "WHERE status in ({$status_analyzed}, {$status_accepted}, " . Constants::$status_open . ", {$status_deferred}) "; if (0 != count($this->projectList)) { $formatedProjects = implode(', ', array_keys($this->projectList)); $query .= "AND project_id IN ({$formatedProjects}) "; } $query .= "ORDER BY last_updated DESC, bug_id DESC"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { $issue = IssueCache::getInstance()->getIssue($row->id, $row); if (NULL == $issue->getEffortEstim()) { $cerr = new ConsistencyError($row->id, $row->handler_id, $row->status, $row->last_updated, T_("BI not specified: BI = Time(Analysis + Dev + Tests)")); $cerr->severity = T_("Error"); $cerrList[] = $cerr; } if (is_null($issue->getBacklog())) { $cerr = new ConsistencyError($row->bug_id, $row->handler_id, $row->status, $row->last_updated, T_("Backlog not specified: Backlog = Time(BI - Analysis)")); $cerr->severity = T_("Error"); $cerrList[] = $cerr; } if ($status_analyzed == $row->status) { $user = UserCache::getInstance()->getUser($row->handler_id); if (!$user->isTeamMember($FDJ_teamid)) { $cerr = new ConsistencyError($row->bug_id, $row->handler_id, $row->status, $row->last_updated, T_("Once analysed, a Task must be assigned to 'FDJ' for validation")); $cerr->severity = T_("Error"); $cerrList[] = $cerr; } } } // check if fields correctly set return $cerrList; }
/** * Get consistency errors * @param int $teamid * @return mixed[] */ private function getTeamConsistencyErrors($teamid) { if (self::$logger->isDebugEnabled()) { self::$logger->debug("getTeamConsistencyErrors teamid={$teamid}"); } // get team projects $issueList = TeamCache::getInstance()->getTeam($teamid)->getTeamIssueList(true, false); if (self::$logger->isDebugEnabled()) { self::$logger->debug("getTeamConsistencyErrors nbIssues=" . count($issueList)); } #$ccheck = new ConsistencyCheck2($issueList); $ccheck = new ConsistencyCheck2($issueList, $teamid); $cerrList = $ccheck->check(); $cerrs = NULL; if (count($cerrList) > 0) { $i = 0; foreach ($cerrList as $cerr) { $i += 1; if (NULL != $cerr->userId) { $user = UserCache::getInstance()->getUser($cerr->userId); } else { $user = NULL; } if (Issue::exists($cerr->bugId)) { $issue = IssueCache::getInstance()->getIssue($cerr->bugId); $summary = $issue->getSummary(); $projName = $issue->getProjectName(); $refExt = $issue->getTcId(); } else { $summary = ''; $projName = ''; } $cerrs[$i] = array('userName' => isset($user) ? $user->getName() : '', 'issueURL' => NULL == $cerr->bugId ? '' : Tools::issueInfoURL($cerr->bugId, $summary), 'mantisURL' => NULL == $cerr->bugId ? '' : Tools::mantisIssueURL($cerr->bugId, $summary, true), 'extRef' => NULL == $refExt ? '' : $refExt, 'date' => NULL == $cerr->timestamp ? '' : date("Y-m-d", $cerr->timestamp), 'status' => NULL == $cerr->status ? '' : Constants::$statusNames[$cerr->status], 'severity' => $cerr->getLiteralSeverity(), 'project' => $projName, 'desc' => $cerr->desc, 'summary' => $summary); } } return $cerrs; }
/** * * @param \PluginDataProviderInterface $pluginMgr * @throws Exception */ public function initialize(PluginDataProviderInterface $pluginDataProv) { if (NULL != $pluginDataProv->getParam(PluginDataProviderInterface::PARAM_ISSUE_SELECTION)) { $this->inputIssueSel = $pluginDataProv->getParam(PluginDataProviderInterface::PARAM_ISSUE_SELECTION); } else { throw new Exception("Missing parameter: " . PluginDataProviderInterface::PARAM_ISSUE_SELECTION); } $bugidList = array_keys($this->inputIssueSel->getIssueList()); if (1 != count($bugidList)) { throw new Exception('There should be only one issue in IssueSelection !'); } $bugid = current($bugidList); $this->issue = IssueCache::getInstance()->getIssue($bugid); }
/** Compares the EffortEstim to the elapsed time. REM: an issue that has been reopened before endTimestamp will NOT be recorded. (For the bugs that where re-opened, the EffortEstim may not have been re-estimated, and thus the result is not reliable.) EffortEstimReliabilityRate = nbResolvedIssues * EffortEstim / elapsed @param projects: $prodProjectList or your own selection. */ public function getEffortEstimReliabilityRate($projects, $startTimestamp, $endTimestamp) { $resolvedList = array(); $EEReliability = array(); // {'MEE', 'EE'} $EEReliability['MEE'] = 0; $EEReliability['EE'] = 0; $totalElapsed = 0; $bugResolvedStatusThreshold = Config::getInstance()->getValue(Config::id_bugResolvedStatusThreshold); // -------- $formatedProjList = implode(', ', $projects); if ("" == $formatedProjList) { // TODO throw exception echo "<div style='color:red'>ERROR getEffortEstimReliabilityRate: no project defined for this team !<br/></div>"; return 0; } // all bugs which status changed to 'resolved' whthin the timestamp $query = "SELECT mantis_bug_table.id, " . "mantis_bug_history_table.new_value, " . "mantis_bug_history_table.old_value, " . "mantis_bug_history_table.date_modified " . "FROM `mantis_bug_table`, `mantis_bug_history_table` " . "WHERE mantis_bug_table.id = mantis_bug_history_table.bug_id " . "AND mantis_bug_table.project_id IN ({$formatedProjList}) " . "AND mantis_bug_history_table.field_name='status' " . "AND mantis_bug_history_table.date_modified >= {$startTimestamp} " . "AND mantis_bug_history_table.date_modified < {$endTimestamp} " . "AND mantis_bug_history_table.new_value = {$bugResolvedStatusThreshold} " . " ORDER BY mantis_bug_table.id DESC"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { // check if the bug has been reopened before endTimestamp $issue = IssueCache::getInstance()->getIssue($row->id); $latestStatus = $issue->getStatus($this->endTimestamp); if ($latestStatus >= $bugResolvedStatusThreshold) { // remove doubloons if (!in_array($row->id, $resolvedList)) { if (self::$logger->isDebugEnabled()) { self::$logger->debug("getEffortEstimReliabilityRate() Found : bugid = {$row->id}, old_status={$row->old_value}, new_status={$row->new_value}, mgrEE=" . $issue->getMgrEffortEstim() . " date_modified=" . date("d F Y", $row->date_modified) . ", effortEstim=" . $issue->getEffortEstim() . ", BS=" . $issue->getEffortAdd() . ", elapsed = " . $issue->getElapsed()); } $resolvedList[] = $row->id; $totalElapsed += $issue->getElapsed(); $EEReliability['MEE'] += $issue->getMgrEffortEstim(); $EEReliability['EE'] += $issue->getEffortEstim() + $issue->getEffortAdd(); if (self::$logger->isDebugEnabled()) { self::$logger->debug("getEffortEstimReliabilityRate(MEE) : " . $EEReliability['MEE'] . " + " . $issue->getMgrEffortEstim() . " = " . ($EEReliability['MEE'] + $issue->getMgrEffortEstim())); self::$logger->debug("getEffortEstimReliabilityRate(EE) : " . $EEReliability['EE'] . " + (" . $issue->getEffortEstim() . " + " . $issue->getEffortAdd() . ") = " . ($EEReliability['EE'] + $issue->getEffortEstim() + $issue->getEffortAdd())); } } } else { $statusName = Constants::$statusNames[$latestStatus]; if (self::$logger->isDebugEnabled()) { self::$logger->debug("getEffortEstimReliabilityRate REOPENED : bugid = {$row->id} status = " . $statusName); } } } // ------- if (self::$logger->isDebugEnabled()) { self::$logger->debug("getEffortEstimReliabilityRate: Reliability (MEE) = " . $EEReliability['MEE'] . " / {$totalElapsed}, nbBugs=" . count($resolvedList)); self::$logger->debug("getEffortEstimReliabilityRate: Reliability (EE) = " . $EEReliability['EE'] . " / {$totalElapsed}, nbBugs=" . count($resolvedList)); } if (0 != $totalElapsed) { $EEReliability['MEE'] /= $totalElapsed; $EEReliability['EE'] /= $totalElapsed; } else { $EEReliability['MEE'] = 0; $EEReliability['EE'] = 0; } return $EEReliability; }
/** * @param string $userName * @param int $dayPixSize * @param ScheduledTask[] $scheduledTaskList * @param int $teamid * @return mixed[][] */ private function getScheduledTasks($userName, $dayPixSize, array $scheduledTaskList, $teamid, $session_userid, $isManager) { $totalPix = 0; $projList = TeamCache::getInstance()->getTeam($teamid)->getProjects(); $scheduledTasks = array(); foreach ($scheduledTaskList as $scheduledTask) { $taskPixSize = $scheduledTask->getPixSize($dayPixSize); $totalPix += $taskPixSize; // set color if (NULL != $scheduledTask->getDeadline()) { if (!$scheduledTask->isOnTime()) { $color = "red"; } else { $color = $scheduledTask->isMonitored() ? "grey" : "green"; } } else { $color = $scheduledTask->isMonitored() ? "grey" : "blue"; } // hide tasks not in team projects $issue = IssueCache::getInstance()->getIssue($scheduledTask->getIssueId()); $taskTitle = $scheduledTask->getDescription(); $formatedTitle = str_replace("'", ' ', $taskTitle); $formatedTitle = str_replace('"', ' ', $formatedTitle); $drawnTaskPixSize = $taskPixSize - 1; $optDisplayExtRef = $this->session_user->getPlanningOption($teamid, 'displayExtRef'); $displayedId = 1 == $optDisplayExtRef ? $issue->getTcId() : $scheduledTask->getIssueId(); $taskTooltip = $this->getTaskTooltip($issue, $scheduledTask, $teamid, $session_userid, $isManager); $sTask = array("bugid" => $scheduledTask->getIssueId(), "extRef" => $issue->getTcId(), "displayedId" => $displayedId, "title" => $formatedTitle, "width" => $drawnTaskPixSize, "color" => $color, "strike" => !array_key_exists($issue->getProjectId(), $projList), "taskTooltip" => $taskTooltip); if ($scheduledTask->isMonitored()) { $sTask["handlerName"] = $scheduledTask->getHandlerName(); } if ($scheduledTask->getDeadline() > 0) { $sTask["deadLine"] = date(T_("Y-m-d"), $scheduledTask->getDeadline()); } $scheduledTasks[$scheduledTask->getIssueId()] = $sTask; } return $scheduledTasks; }
protected function display() { if (Tools::isConnectedUser()) { $user = UserCache::getInstance()->getUser($_SESSION['userid']); $teamid = $_SESSION['teamid']; $teamList = $user->getTeamList(); if (count($teamList) > 0) { // --- define the list of tasks the user can display // All projects from teams where I'm a Developper or Manager AND Observer $allProject[0] = T_('(all)'); $dTeamList = $user->getDevTeamList(); $devProjList = count($dTeamList) > 0 ? $user->getProjectList($dTeamList, true, false) : array(); $managedTeamList = $user->getManagedTeamList(); $managedProjList = count($managedTeamList) > 0 ? $user->getProjectList($managedTeamList, true, false) : array(); $oTeamList = $user->getObservedTeamList(); $observedProjList = count($oTeamList) > 0 ? $user->getProjectList($oTeamList, true, false) : array(); $projList = $allProject + $devProjList + $managedProjList + $observedProjList; // if 'support' is set in the URL, display graphs for 'with/without Support' $displaySupport = filter_input(INPUT_GET, 'support') ? true : false; if ($displaySupport) { $this->smartyHelper->assign('support', $displaySupport); } if (filter_input(INPUT_GET, 'bugid')) { $bug_id = Tools::getSecureGETIntValue('bugid', 0); } else { if (isset($_SESSION['bugid'])) { $bug_id = $_SESSION['bugid']; } else { $bug_id = 0; unset($_SESSION['bugid']); } } $bugs = NULL; $projects = NULL; if ($bug_id != 0) { try { $issue = IssueCache::getInstance()->getIssue($bug_id); $defaultProjectid = $issue->getProjectId(); $bugs = SmartyTools::getBugs($defaultProjectid, $bug_id); if (array_key_exists($defaultProjectid, $projList) && array_key_exists($bug_id, $bugs)) { $consistencyErrors = NULL; $ccheck = new ConsistencyCheck2(array($issue)); $cerrList = $ccheck->check(); if (0 != count($cerrList)) { foreach ($cerrList as $cerr) { $consistencyErrors[] = array('severity' => $cerr->getLiteralSeverity(), 'severityColor' => $cerr->getSeverityColor(), 'desc' => $cerr->desc); } $this->smartyHelper->assign('ccheckButtonTitle', count($consistencyErrors) . ' ' . T_("Errors")); $this->smartyHelper->assign('ccheckBoxTitle', count($consistencyErrors) . ' ' . T_("Errors")); $this->smartyHelper->assign('ccheckErrList', $consistencyErrors); } $this->smartyHelper->assign('isManager', $user->isTeamManager($teamid)); $this->smartyHelper->assign('isObserver', $user->isTeamObserver($teamid)); $isManagerView = array_key_exists($issue->getProjectId(), $managedProjList) ? true : false; $isObserverView = array_key_exists($issue->getProjectId(), $observedProjList) ? true : false; $this->smartyHelper->assign('issueGeneralInfo', IssueInfoTools::getIssueGeneralInfo($issue, $isManagerView || $isObserverView, $displaySupport)); $timeTracks = $issue->getTimeTracks(); $this->smartyHelper->assign('jobDetails', $this->getJobDetails($timeTracks)); $this->smartyHelper->assign('timeDrift', $this->getTimeDrift($issue)); $this->smartyHelper->assign('months', $this->getCalendar($issue, $timeTracks)); // set Commands I belong to $parentCmds = $this->getParentCommands($issue); $this->smartyHelper->assign('parentCommands', $parentCmds); $this->smartyHelper->assign('nbParentCommands', count($parentCmds)); } $projects = SmartyTools::getSmartyArray($projList, $defaultProjectid); $_SESSION['projectid'] = $defaultProjectid; $_SESSION['bugid'] = $bug_id; // Dashboard IssueInfoTools::dashboardSettings($this->smartyHelper, $issue, $this->session_userid, $this->teamid); } catch (Exception $e) { self::$logger->warn("issue {$bug_id} not found in mantis DB !"); unset($_SESSION['bugid']); } } else { try { $defaultProjectid = 0; if (isset($_SESSION['projectid']) && 0 != $_SESSION['projectid']) { $defaultProjectid = $_SESSION['projectid']; $bugs = SmartyTools::getBugs($defaultProjectid, $bug_id); } else { $bugs = SmartyTools::getBugs($defaultProjectid, $bug_id, $projList); } $projects = SmartyTools::getSmartyArray($projList, $defaultProjectid); } catch (Exception $e) { self::$logger->warn("issue {$bug_id} not found in mantis DB !"); unset($_SESSION['bugid']); } } $this->smartyHelper->assign('bugs', $bugs); $this->smartyHelper->assign('projects', $projects); } } }
/** * returns all issues not already assigned to a command * and which project_id is defined in the team * * @param int $this->teamid * @return mixed[] */ private function getChildIssuesCandidates($teamid) { $issueArray = array(); // team projects except externalTasksProject & NoStats projects $projects = TeamCache::getInstance()->getTeam($this->teamid)->getProjects(); $extProjId = Config::getInstance()->getValue(Config::id_externalTasksProject); unset($projects[$extProjId]); $formattedProjectList = implode(', ', array_keys($projects)); $query = "SELECT * FROM `mantis_bug_table` " . "WHERE project_id IN ({$formattedProjectList}) " . "AND 0 = is_issue_in_team_commands(id, {$teamid}) " . "ORDER BY id DESC"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { $issue = IssueCache::getInstance()->getIssue($row->id, $row); $issueArray[$row->id] = array("bugid" => Tools::issueInfoURL(sprintf("%07d\n", $issue->getId())), "extRef" => $issue->getTcId(), "project" => $issue->getProjectName(), "target" => $issue->getTargetVersion(), "status" => $issue->getCurrentStatusName(), "summary" => htmlspecialchars($issue->getSummary())); } return $issueArray; }
$oTeamList = $user->getObservedTeamList(); $observedProjList = count($oTeamList) > 0 ? $user->getProjectList($oTeamList, true, $withDisabled) : array(); $projList = $allProject + $devProjList + $managedProjList + $observedProjList; // WORKAROUND if ($_GET['bugid'] == 'null') { $_GET['bugid'] = 0; } $smartyHelper->assign('bugs', SmartyTools::getBugs(Tools::getSecureGETIntValue('projectid'), Tools::getSecureGETIntValue('bugid', 0), $projList)); $smartyHelper->display('form/bugSelector'); } elseif ($_GET['action'] == 'getYearsToNow') { $team = TeamCache::getInstance()->getTeam(Tools::getSecureGETIntValue('teamid')); $min_year = date("Y", $team->getDate()); $year = isset($_POST['year']) && $_POST['year'] > $min_year ? $_POST['year'] : $min_year; $smartyHelper->assign('years', SmartyTools::getYearsToNow($min_year, $year)); $smartyHelper->display('form/yearSelector'); } else { Tools::sendNotFoundAccess(); } } else { if ($_POST['action']) { if ($_POST['action'] == 'updateBacklogAction') { $issue = IssueCache::getInstance()->getIssue(Tools::getSecurePOSTIntValue('bugid')); $issue->setBacklog(Tools::getSecurePOSTNumberValue('backlog')); } else { Tools::sendNotFoundAccess(); } } } } else { Tools::sendUnauthorizedAccess(); }
/** * @param TimeTracking $timeTracking * @param bool $isDetailed * @param int[] $weekDates * @return mixed[] */ private function getWeekDetails(TimeTracking $timeTracking, $isDetailed, $weekDates, $session_userid) { $team = TeamCache::getInstance()->getTeam($timeTracking->getTeamid()); $weekDetails = array(); $session_users = $team->getUsers(); foreach ($session_users as $session_user) { // if user was working on the project during the timestamp if ($session_user->isTeamDeveloper($timeTracking->getTeamid(), $timeTracking->getStartTimestamp(), $timeTracking->getEndTimestamp()) || $session_user->isTeamManager($timeTracking->getTeamid(), $timeTracking->getStartTimestamp(), $timeTracking->getEndTimestamp())) { // PERIOD week //$thisWeekId=date("W"); $weekTracks = $timeTracking->getWeekDetails($session_user->getId(), !$isDetailed); $holidays = Holidays::getInstance(); $weekJobDetails = array(); foreach ($weekTracks as $bugid => $jobList) { try { $issue = IssueCache::getInstance()->getIssue($bugid); } catch (Exception $e) { self::$logger->error("getWeekDetails() skip issue {$bugid} : " . $e->getMessage()); $weekJobDetails[] = array("description" => '<span class="error_font">' . $bugid . ' : ' . T_('Error: Task not found in Mantis DB !') . '</span>', "duration" => "!", "progress" => "!", "projectName" => "!", "targetVersion" => "!", "jobName" => "!", "daysDetails" => "!", "totalDuration" => "!"); continue; } $project = ProjectCache::getInstance()->getProject($issue->getProjectId()); if ($isDetailed) { $formatedJobList = implode(', ', array_keys($jobList)); $query = 'SELECT id, name FROM `codev_job_table` WHERE id IN (' . $formatedJobList . ');'; $result2 = SqlWrapper::getInstance()->sql_query($query); if (!$result2) { continue; } while ($row2 = SqlWrapper::getInstance()->sql_fetch_object($result2)) { $jobName = $row2->name; $dayList = $jobList[$row2->id]; $daysDetails = array(); $weekDuration = 0; for ($i = 1; $i <= 7; $i++) { $dayDetails = $this->getDaysDetails($i, $holidays, $weekDates, $dayList[$i]); $weekDuration += $dayDetails['duration']; $daysDetails[] = $dayDetails; } if (!$project->isSideTasksProject(array($team->getId())) && !$project->isExternalTasksProject()) { $tooltipAttr = $issue->getTooltipItems($team->getId(), $session_userid); // force some fields #$tooltipAttr[T_('Elapsed')] = $issue->getElapsed(); #$tooltipAttr[T_('Backlog')] = $issue->getDuration(); #$tooltipAttr[T_('Drift')] = $issue->getDrift(); #$tooltipAttr[T_('DriftColor')] = $issue->getDriftColor(); $infoTooltip = Tools::imgWithTooltip('images/b_info.png', $tooltipAttr); } else { $infoTooltip = NULL; } // prepare json data for the IssueNoteDialogbox $issueNoteData = $this->getIssueNoteTooltip($project, $team, $issue); $weekJobDetails[] = array('description' => SmartyTools::getIssueDescription($bugid, $issue->getTcId(), $issue->getSummary()), 'duration' => $issue->getDuration(), 'progress' => round(100 * $issue->getProgress()), 'projectName' => $issue->getProjectName(), 'targetVersion' => $issue->getTargetVersion(), 'jobName' => $jobName, 'daysDetails' => $daysDetails, 'totalDuration' => $weekDuration, 'infoTooltip' => $infoTooltip, 'issueNoteId' => $issueNoteData['id'], 'noteTooltip' => $issueNoteData['tooltip']); } } else { // for each day, concat jobs duration $daysDetails = array(); $weekDuration = 0; for ($i = 1; $i <= 7; $i++) { $duration = 0; foreach ($jobList as $dayList) { if (array_key_exists($i, $dayList)) { $duration += $dayList[$i]; } } if ($duration == 0) { $duration = ""; } $dayDetails = $this->getDaysDetails($i, $holidays, $weekDates, $duration); $weekDuration += $dayDetails['duration']; $daysDetails[] = $dayDetails; } if (!$project->isSideTasksProject(array($team->getId())) && !$project->isExternalTasksProject()) { $tooltipAttr = $issue->getTooltipItems($team->getId(), $session_userid); // force some fields #$tooltipAttr[T_('Elapsed')] = $issue->getElapsed(); #$tooltipAttr[T_('Backlog')] = $issue->getDuration(); #$tooltipAttr[T_('Drift')] = $issue->getDrift(); #$tooltipAttr[T_('DriftColor')] = $issue->getDriftColor(); $infoTooltip = Tools::imgWithTooltip('images/b_info.png', $tooltipAttr); } else { $infoTooltip = NULL; } // prepare json data for the IssueNoteDialogbox $issueNoteData = $this->getIssueNoteTooltip($project, $team, $issue); $weekJobDetails[] = array('description' => SmartyTools::getIssueDescription($bugid, $issue->getTcId(), $issue->getSummary()), 'duration' => $issue->getDuration(), 'progress' => round(100 * $issue->getProgress()), 'projectName' => $issue->getProjectName(), 'daysDetails' => $daysDetails, 'totalDuration' => $weekDuration, 'infoTooltip' => $infoTooltip, 'issueNoteId' => $issueNoteData['id'], 'noteTooltip' => $issueNoteData['tooltip']); } } if (!empty($weekJobDetails)) { $weekDetails[] = array('name' => $session_user->getName(), 'realname' => $session_user->getRealname(), 'forecastWorkload' => $session_user->getForecastWorkload(), 'weekDates' => array(Tools::formatDate("%A\n%d %b", $weekDates[1]), Tools::formatDate("%A\n%d %b", $weekDates[2]), Tools::formatDate("%A\n%d %b", $weekDates[3]), Tools::formatDate("%A\n%d %b", $weekDates[4]), Tools::formatDate("%A\n%d %b", $weekDates[5])), 'weekEndDates' => array(Tools::formatDate("%A\n%d %b", $weekDates[6]), Tools::formatDate("%A\n%d %b", $weekDates[7])), 'weekJobDetails' => $weekJobDetails); } } } return $weekDetails; }
/** * returns $durationPerCategory[CategoryName]['duration'] = duration * * @param array $projectidList list of project_id * @return array[] $durationPerCategory[CategoryName] = array (duration, bugidList), */ private function getRawInfoPerCategory($timeTracks, $projectidList) { $durPerCat = array(); $bugsPerCat = array(); foreach ($timeTracks as $timeTrack) { try { $bugid = $timeTrack->getIssueId(); $issue = IssueCache::getInstance()->getIssue($bugid); $project_id = $issue->getProjectId(); $catName = $issue->getCategoryName(); $duration = $timeTrack->getDuration(); if (in_array($project_id, $projectidList)) { if (self::$logger->isDebugEnabled()) { self::$logger->debug("project[{$project_id}][" . $catName . "]( bug " . $bugid . ") = " . $duration); } // save duration per category if (array_key_exists($catName, $durPerCat)) { $durPerCat[$catName] += $duration; } else { $durPerCat[$catName] = $duration; } // save bugid list per category if ($this->isDisplayTasks) { if (!array_key_exists($catName, $bugsPerCat)) { $bugsPerCat[$catName] = array(); } if (array_key_exists($bugid, $bugsPerCat[$catName])) { $bugsPerCat[$catName][$bugid] += $duration; } else { $bugsPerCat[$catName][$bugid] = $duration; } } } } catch (Exception $e) { self::$logger->warn("getDurationPerProjectCategory() issue " . $timeTrack->getIssueId() . " not found in Mantis DB (duration = " . $timeTrack->getDuration() . " on " . date('Y-m-d', $timeTrack->getDate()) . ')'); } } $ret = array('durationPerCat' => $durPerCat); if ($this->isDisplayTasks) { $ret['bugidsPerCat'] = $bugsPerCat; } return $ret; }
/** * get all unassigned tasks found in team projects * * Note: sideTasks and nostatsProjects excluded, resolved tasks excluded. * * @return Issue[] : issueList (id => Issue) */ public function getUnassignedTasks() { $issueList = array(); $query_projects = "SELECT project.id " . "FROM `mantis_project_table` as project " . "JOIN `codev_team_project_table` as team_project ON project.id = team_project.project_id " . "WHERE team_project.team_id = {$this->id} " . "AND team_project.type NOT IN (" . Project::type_noStatsProject . ', ' . Project::type_sideTaskProject . ') '; $query = "SELECT * " . "FROM `mantis_bug_table` " . "WHERE project_id IN ({$query_projects}) " . "AND handler_id = '0' " . "AND status < get_project_resolved_status_threshold(project_id) " . "ORDER BY project_id ASC, id ASC"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { $issueList[$row->id] = IssueCache::getInstance()->getIssue($row->id, $row); } if (self::$logger->isDebugEnabled()) { self::$logger->debug("getUnassignedTasks(teamid={$this->id}) nbIssues=" . count($issueList)); } return $issueList; }
/** * @param int $teamid * @param int $startTimestamp * @param int $endTimestamp * @param string $myFile * @return string */ public static function exportManagedIssuesToCSV($teamid, $startTimestamp, $endTimestamp, $myFile) { $sepChar = ';'; $fh = fopen($myFile, 'w'); // write header // WARNING i18n: translations with HTML chars (é) include ';' which is the CSV separation char ! $stringData = T_("Project") . $sepChar . T_("m_id") . $sepChar . T_("ExtRef") . $sepChar . T_("Summary") . $sepChar . T_("Status") . $sepChar . T_("Submitted") . $sepChar . T_("Start date") . $sepChar . T_("DeadLine") . $sepChar . T_("Product Version") . $sepChar . T_("Priority") . $sepChar . "Category" . $sepChar . T_("Resolution") . $sepChar . T_("MgrEffortEstim") . $sepChar . T_("BI") . $sepChar . T_("BS") . $sepChar . "Elapsed" . $sepChar . T_("BL") . $sepChar . T_("Progress") . $sepChar . T_("Delivery Date") . $sepChar . T_("Delivery Sheet") . $sepChar . T_("Assigned to") . $sepChar . "\n"; fwrite($fh, $stringData); $projList = TeamCache::getInstance()->getTeam($teamid)->getProjects(); $formatedProjList = implode(', ', array_keys($projList)); // Note: if you filter on TeamMembers, you won't have issues temporarily affected to other teams //$memberList = Team::getMemberList($teamid); //$formatedMemberList = implode( ', ', array_keys($memberList)); // for all issues with status != {resolved, closed} $query = "SELECT * FROM `mantis_bug_table` " . "WHERE status < get_project_resolved_status_threshold(project_id) " . "AND project_id IN ({$formatedProjList}) " . "ORDER BY id DESC"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { $issue = IssueCache::getInstance()->getIssue($row->id, $row); $user = UserCache::getInstance()->getUser($issue->getHandlerId()); $deadLine = ""; if (NULL != $issue->getDeadLine()) { $deadLine = date("d/m/Y", $issue->getDeadLine()); } $deliveryDate = ""; if (NULL != $issue->getDeliveryDate()) { $deliveryDate = date("d/m/Y", $issue->getDeliveryDate()); } // remove sepChar from summary text $formatedSummary = str_replace($sepChar, " ", $issue->getSummary()); $startDate = ""; if (NULL != ($d = $issue->startDate())) { $startDate = date("d/m/Y", $d); } // write data $stringData = $issue->getProjectName() . $sepChar . $issue->getId() . $sepChar . $issue->getTcId() . $sepChar . $formatedSummary . $sepChar . $issue->getCurrentStatusName() . $sepChar . date("d/m/Y", $issue->getDateSubmission()) . $sepChar . $startDate . $sepChar . $deadLine . $sepChar . $issue->getVersion() . $sepChar . $issue->getPriorityName() . $sepChar . $issue->getCategoryName() . $sepChar . $issue->getResolutionName() . $sepChar . $issue->getMgrEffortEstim() . $sepChar . $issue->getEffortEstim() . $sepChar . $issue->getEffortAdd() . $sepChar . $issue->getElapsed() . $sepChar . $issue->getBacklog() . $sepChar . round(100 * $issue->getProgress()) . "%" . $sepChar . $deliveryDate . $sepChar . $issue->getDeliveryId() . $sepChar . $user->getShortname() . "\n"; fwrite($fh, $stringData); } // Add resolved issues modified into the period $query = "SELECT * FROM `mantis_bug_table` " . "WHERE status >= get_project_resolved_status_threshold(project_id) " . "AND project_id IN ({$formatedProjList}) " . "AND last_updated > {$startTimestamp} " . "AND last_updated < {$endTimestamp} " . "ORDER BY id DESC"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { $issue = IssueCache::getInstance()->getIssue($row->id, $row); $user = UserCache::getInstance()->getUser($issue->getHandlerId()); $deliveryDate = ""; if (NULL != $issue->getDeliveryDate()) { $deliveryDate = date("d/m/Y", $issue->getDeliveryDate()); } // remove sepChar from summary text $formatedSummary = str_replace($sepChar, " ", $issue->getSummary()); $startDate = ""; if (NULL != ($d = $issue->startDate())) { $startDate = date("d/m/Y", $d); } // write data $stringData = $issue->getProjectName() . $sepChar . $issue->getId() . $sepChar . $issue->getTcId() . $sepChar . $formatedSummary . $sepChar . $issue->getCurrentStatusName() . $sepChar . date("d/m/Y", $issue->getDateSubmission()) . $sepChar . $startDate . $sepChar . $deadLine . $sepChar . $issue->getVersion() . $sepChar . $issue->getPriorityName() . $sepChar . $issue->getCategoryName() . $sepChar . $issue->getResolutionName() . $sepChar . $issue->getMgrEffortEstim() . $sepChar . $issue->getEffortEstim() . $sepChar . $issue->getEffortAdd() . $sepChar . $issue->getElapsed() . $sepChar . $issue->getBacklog() . $sepChar . round(100 * $issue->getProgress()) . "%" . $sepChar . $deliveryDate . $sepChar . $issue->getDeliveryId() . $sepChar . $user->getShortname() . "\n"; fwrite($fh, $stringData); } fclose($fh); return $myFile; }
/** * @param int $bugid * @return bool true if added, false if not (already in list) * @exception if issue does not exist in mantis DB */ public function addIssue($bugid) { $retCode = false; // do not add twice the same issue if (!array_key_exists($bugid, $this->issueList)) { $issue = IssueCache::getInstance()->getIssue($bugid); $this->issueList[$bugid] = $issue; $this->elapsed += $issue->getElapsed(); $this->duration += $issue->getDuration(); $this->mgrEffortEstim += $issue->getMgrEffortEstim(); $this->effortEstim += $issue->getEffortEstim(); $this->effortAdd += $issue->getEffortAdd(); if (self::$logger->isDebugEnabled()) { self::$logger->debug("IssueSelection [{$this->name}] : addIssue({$bugid}) version = <" . $issue->getTargetVersion() . "> MgrEE=" . $issue->getMgrEffortEstim() . " BI+BS=" . ($issue->getEffortEstim() + $issue->getEffortAdd()) . " elapsed=" . $issue->getElapsed() . " RAF=" . $issue->getDuration() . " drift=" . $issue->getDrift() . " driftMgr=" . $issue->getDriftMgr()); } $retCode = true; } return $retCode; }
/** * @static * @param int[] $projectIds * @return Issue[] */ public static function getProjectIssues($projectIds) { $formatedProjList = implode(', ', $projectIds); $query = "SELECT * FROM `mantis_bug_table` " . "WHERE project_id IN ({$formatedProjList}) " . "ORDER BY id DESC;"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } $issueList = array(); if (0 != SqlWrapper::getInstance()->sql_num_rows($result)) { while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { $issueList[] = IssueCache::getInstance()->getIssue($row->id, $row); } return $issueList; } return $issueList; }
/** * Returns the Issues that I monitor. * the issue list is ordered by priority. * * priority criteria are: * - opened * - deadLine * - priority * * @return Issue[] */ public function getMonitoredIssues() { if (NULL == $this->monitoredIssues) { $query = "SELECT DISTINCT bug.* " . "FROM `mantis_bug_table` as bug " . "JOIN `mantis_bug_monitor_table` as monitor ON bug.id = monitor.bug_id " . "WHERE monitor.user_id = {$this->id} " . "ORDER BY bug.id DESC;"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } $this->monitoredIssues = array(); while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { $issue = IssueCache::getInstance()->getIssue($row->id, $row); if ($issue->getCurrentStatus() < $issue->getBugResolvedStatusThreshold()) { $this->monitoredIssues[] = $issue; } } // quickSort the list Tools::usort($this->monitoredIssues); } return $this->monitoredIssues; }
/** * * returns an array of [user][activity] * activity in (elapsed, sidetask, other, external, leave) * */ public function execute() { $team = TeamCache::getInstance()->getTeam($this->teamid); $members = $team->getActiveMembers($this->startTimestamp, $this->endTimestamp); $formatedUseridString = implode(', ', array_keys($members)); $extProjId = Config::getInstance()->getValue(Config::id_externalTasksProject); $extTasksCatLeave = Config::getInstance()->getValue(Config::id_externalTasksCat_leave); // get timetracks for each Issue, $issueList = $this->inputIssueSel->getIssueList(); $bugidList = array_keys($issueList); $query = "SELECT * FROM `codev_timetracking_table` " . "WHERE userid IN (" . $formatedUseridString . ") "; if (isset($this->startTimestamp)) { $query .= "AND date >= {$this->startTimestamp} "; } if (isset($this->endTimestamp)) { $query .= "AND date <= {$this->endTimestamp} "; } $query .= " ORDER BY bugid"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } $timeTracks = array(); while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { $timeTracks[$row->id] = TimeTrackCache::getInstance()->getTimeTrack($row->id, $row); } // --- // un tablean de users avec repartition temps en categories: regular,external,sidetask $teams = array($this->teamid); $usersActivity = array(); foreach ($timeTracks as $tt) { $issueId = $tt->getIssueId(); try { $issue = IssueCache::getInstance()->getIssue($issueId); } catch (Exception $e) { self::$logger->error("execute() skip issue {$issueId} : " . $e->getMessage()); continue; } $userid = $tt->getUserId(); if (!array_key_exists($userid, $usersActivity)) { $usersActivity[$userid] = array(); } //$activityList = $usersActivity[$userid]; $duration = $tt->getDuration(); try { if ($extProjId == $tt->getProjectId()) { #self::$logger->error("external ".$tt->getIssueId()); if ($extTasksCatLeave == $issue->getCategoryId()) { if (array_key_exists('leave', $usersActivity[$userid])) { $usersActivity[$userid]['leave'] += $duration; } else { $usersActivity[$userid]['leave'] = $duration; } } else { if (array_key_exists('external', $usersActivity[$userid])) { $usersActivity[$userid]['external'] += $duration; } else { $usersActivity[$userid]['external'] = $duration; } } } else { if ($issue->isSideTaskNonProductionIssue($teams)) { #self::$logger->error("execute showSidetasks = ".$this->showSidetasks.' cat='.$cat); // if sideTask is in the IssueSelection, then it is considered as 'normal', // else it should not be included if (in_array($issueId, $bugidList)) { $cat = $this->showSidetasks ? 'sidetask' : 'elapsed'; if (array_key_exists($cat, $usersActivity[$userid])) { $usersActivity[$userid][$cat] += $duration; } else { $usersActivity[$userid][$cat] = $duration; } } else { // all sideTasks are in 'other' except inactivity tasks. $project = ProjectCache::getInstance()->getProject($issue->getProjectId()); if ($project->getCategory(Project::cat_st_inactivity) == $issue->getCategoryId()) { if (array_key_exists('leave', $usersActivity[$userid])) { $usersActivity[$userid]['leave'] += $duration; } else { $usersActivity[$userid]['leave'] = $duration; } } else { if (array_key_exists('other', $usersActivity[$userid])) { $usersActivity[$userid]['other'] += $duration; } else { $usersActivity[$userid]['other'] = $duration; } } } } else { if (in_array($issueId, $bugidList)) { #self::$logger->error("selection ".$tt->getIssueId()); if (array_key_exists('elapsed', $usersActivity[$userid])) { $usersActivity[$userid]['elapsed'] += $duration; } else { $usersActivity[$userid]['elapsed'] = $duration; } } else { #echo "other ".$tt->getIssueId()."<br>"; if (array_key_exists('other', $usersActivity[$userid])) { $usersActivity[$userid]['other'] += $duration; } else { $usersActivity[$userid]['other'] = $duration; } } } } } catch (Exception $e) { // Issue::isSideTaskIssue() throws an Ex if project not found in mantis self::$logger->error("Unknown activity for issue {$issueId}, duration ({$duration}) added to 'elapsed'\n" . $e->getMessage()); $usersActivity[$userid]['elapsed'] += $duration; // should it be added in userActivity[$userid]['unknown'] ? } } #var_dump($usersActivity); $this->execData = $usersActivity; }
/** * @param int $teamid * @param int $startTimestamp * @param int $endTimestamp * @param int[] $projectIds * @return GanttGraph */ private function getGanttGraph($teamid, $startTimestamp, $endTimestamp, array $projectIds) { $graph = new GanttGraph(); // set graph title $team = TeamCache::getInstance()->getTeam($teamid); if (0 != count($projectIds)) { $pnameList = ""; foreach ($projectIds as $pid) { if ("" != $pnameList) { $pnameList .= ","; } $project = ProjectCache::getInstance()->getProject($pid); $pnameList .= $project->getName(); } $graph->title->Set(T_('Team') . ' ' . $team->getName() . ' ' . T_('Project(s)') . ': ' . $pnameList); } else { $graph->title->Set(T_('Team') . ' ' . $team->getName() . ' (' . T_('All projects') . ')'); } // Setup scale $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH | GANTT_HDAY | GANTT_HWEEK); $graph->scale->week->SetStyle(WEEKSTYLE_FIRSTDAYWNBR); $gantManager = new GanttManager($teamid, $startTimestamp, $endTimestamp); $teamActivities = $gantManager->getTeamActivities(); // mapping to ease constrains building // Note: $issueActivityMapping must be completed before calling $a->getJPGraphBar() $issueActivityMapping = array(); $activityIdx = 0; foreach ($teamActivities as $a) { $a->setActivityIdx($activityIdx); $issueActivityMapping[$a->bugid] = $activityIdx; ++$activityIdx; } // Add the specified activities foreach ($teamActivities as $a) { // FILTER on projects if (NULL != $projectIds && 0 != sizeof($projectIds)) { $issue = IssueCache::getInstance()->getIssue($a->bugid); if (!in_array($issue->getProjectId(), $projectIds)) { // skip activity indexing continue; } } $filterTeamActivities[] = $a; // Shorten bar depending on gantt startDate if (NULL != $startTimestamp && $a->startTimestamp < $startTimestamp) { // leave one day to insert prefixBar $newStartTimestamp = $startTimestamp + 60 * 60 * 24; if ($newStartTimestamp > $a->endTimestamp) { // there is not enough space for a prefixBar $newStartTimestamp = $startTimestamp; self::$logger->debug("bugid=" . $a->bugid . ": Shorten bar to Gantt start date"); } else { $formattedStartDate = date('Y-m-d', $startTimestamp); $prefixBar = new GanttBar($a->activityIdx, "", $formattedStartDate, $formattedStartDate, "", 10); $prefixBar->SetBreakStyle(true, 'dotted', 1); $graph->Add($prefixBar); self::$logger->debug("bugid=" . $a->bugid . ": Shorten bar & add prefixBar"); } self::$logger->debug("bugid=" . $a->bugid . ": Shorten bar from " . date('Y-m-d', $a->startTimestamp) . " to " . date('Y-m-d', $newStartTimestamp)); $a->startTimestamp = $newStartTimestamp; } $bar = $a->getJPGraphBar($issueActivityMapping); $graph->Add($bar); } return $graph; }
/** * Get consistency errors * @return mixed[] */ private function getConsistencyErrors() { $consistencyErrors = array(); // if null, array_merge fails ! if (0 != $this->teamid) { // only this team's projects #$teamList = $this->teamList; $teamList = array($this->teamid => $this->teamList[$this->teamid]); // except disabled projects $projList = $this->session_user->getProjectList($teamList, true, false); $issueList = $this->session_user->getAssignedIssues($projList, true); $ccheck = new ConsistencyCheck2($issueList, $this->teamid); $cerrList = $ccheck->check(); if (count($cerrList) > 0) { foreach ($cerrList as $cerr) { if ($this->session_user->getId() == $cerr->userId) { $issue = IssueCache::getInstance()->getIssue($cerr->bugId); $titleAttr = array(T_('Project') => $issue->getProjectName(), T_('Summary') => $issue->getSummary()); $consistencyErrors[] = array('issueURL' => Tools::issueInfoURL($cerr->bugId, $titleAttr), 'status' => Constants::$statusNames[$cerr->status], 'desc' => $cerr->desc); } } } } return $consistencyErrors; }
// no backlog update for this task $data = array('diagnostic' => 'BacklogUpdateNotNeeded'); $updateBacklogJsonData = json_encode($data); } else { $managedUserid = Tools::getSecurePOSTIntValue('userid', 0); $trackDuration = Tools::getSecurePOSTNumberValue('trackDuration', 0); $trackDate = Tools::getSecurePOSTStringValue('trackDate', 0); $updateBacklogJsonData = TimeTrackingTools::getUpdateBacklogJsonData($bugid, $job, $teamid, $managedUserid, $trackDate, $trackDuration); } // return data echo $updateBacklogJsonData; } else { if ($action == 'updateBacklog') { // updateBacklogDoalogbox with 'updateBacklog' action $bugid = Tools::getSecurePOSTIntValue('bugid'); $issue = IssueCache::getInstance()->getIssue($bugid); $formattedBacklog = Tools::getSecurePOSTNumberValue('backlog'); $issue->setBacklog($formattedBacklog); // setStatus $newStatus = Tools::getSecurePOSTNumberValue('statusid'); $issue->setStatus($newStatus); // return data // the complete WeekTaskDetails Div must be updated $weekid = Tools::getSecurePOSTIntValue('weekid'); $year = Tools::getSecurePOSTIntValue('year'); $userid = Tools::getSecurePOSTIntValue('userid', $session_user); setWeekTaskDetails($smartyHelper, $weekid, $year, $userid, $teamid); $smartyHelper->display('ajax/weekTaskDetails'); } else { if ($action == 'getIssueNoteText') { $bugid = Tools::getSecurePOSTIntValue('bugid');
/** * returns a list of all the tasks having been reopened in the period * (status changed from resolved_threshold to lower value) * * Note: internal tasks (tasks having no ExternalReference) NOT INCLUDED * * @return Issue[] */ public function getReopened() { if (is_null($this->reopenedList)) { $formatedProjList = implode(', ', $this->prodProjectList); if ("" == $formatedProjList) { echo "<div style='color:red'>ERROR getReopened: no project defined for this team !<br/></div>"; return 0; } $extIdField = Config::getInstance()->getValue(Config::id_customField_ExtId); // all bugs which resolution changed to 'reopened' whthin the timestamp // having an ExternalReference $query = "SELECT bug.*" . "FROM `mantis_custom_field_string_table`, `mantis_bug_table` as bug " . "JOIN `mantis_bug_history_table` as history ON bug.id = history.bug_id " . "WHERE bug.project_id IN ({$formatedProjList}) " . "AND mantis_custom_field_string_table.bug_id = bug.id " . "AND mantis_custom_field_string_table.field_id = {$extIdField} " . "AND mantis_custom_field_string_table.value <> '' " . "AND history.field_name='status' " . "AND history.date_modified >= {$this->startTimestamp} AND history.date_modified < {$this->endTimestamp} " . "AND history.old_value >= get_project_resolved_status_threshold(bug.project_id) " . "AND history.new_value < get_project_resolved_status_threshold(bug.project_id) " . "GROUP BY bug.id ORDER BY bug.id DESC;"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } $this->reopenedList = array(); while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { $issue = IssueCache::getInstance()->getIssue($row->id, $row); $this->reopenedList[$row->id] = $issue; if (self::$logger->isDebugEnabled()) { self::$logger->debug("getReopened: found issue {$row->id}"); } } } #echo "getReopened $query RESULT=".count($this->reopenedList)."<br>"; return $this->reopenedList; }
/** * Get project activity report * @param mixed[][][] $projectTracks * @param int $teamid The team id * @param boolean $isDetailed * @return mixed[] */ private function getProjectActivityReport(array $projectTracks, $teamid, $isDetailed) { $team = TeamCache::getInstance()->getTeam($teamid); $projectActivityReport = NULL; foreach ($projectTracks as $projectId => $bugList) { $project = ProjectCache::getInstance()->getProject($projectId); $jobList = $project->getJobList($team->getProjectType($projectId)); $jobTypeList = array(); if ($isDetailed) { foreach ($jobList as $jobId => $jobName) { $jobTypeList[$jobId] = $jobName; } } // write table content (by bugid) $row_id = 0; $bugDetailedList = ""; foreach ($bugList as $bugid => $jobs) { $issue = IssueCache::getInstance()->getIssue($bugid); $totalTime = 0; $tr_class = $row_id & 1 ? "row_even" : "row_odd"; $subJobList = array(); foreach ($jobList as $jobId => $jobName) { $jobTime = 0; if (array_key_exists($jobId, $jobs)) { $jobTime = $jobs[$jobId]; } if ($isDetailed) { $subJobList[$jobId] = $jobTime; } $totalTime += $jobTime; } $row_id += 1; $bugDetailedList[$bugid] = array('class' => $tr_class, 'description' => SmartyTools::getIssueDescription($bugid, $issue->getTcId(), $issue->getSummary()), 'jobList' => $subJobList, 'targetVersion' => $issue->getTargetVersion(), 'currentStatusName' => $issue->getCurrentStatusName(), 'progress' => round(100 * $issue->getProgress()), 'backlog' => $issue->getBacklog(), 'totalTime' => $totalTime); } $projectActivityReport[$projectId] = array('id' => $projectId, 'name' => $project->getName(), 'jobList' => $jobTypeList, 'bugList' => $bugDetailedList); } return $projectActivityReport; }
/** * @param int $userid * @param TimeTracking $timeTracking * @param string $realname * @param resource $fh */ private function exportWeekDetailsToCSV($userid, TimeTracking $timeTracking, $realname, $fh) { $sepChar = ';'; $weekTracks = $timeTracking->getWeekDetails($userid); foreach ($weekTracks as $bugid => $jobList) { try { $issue = IssueCache::getInstance()->getIssue($bugid); // remove sepChar from summary text $formatedSummary = str_replace($sepChar, " ", $issue->getSummary()); foreach ($jobList as $jobid => $dayList) { $query = "SELECT name FROM `codev_job_table` WHERE id={$jobid}"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } $jobName = SqlWrapper::getInstance()->sql_result($result, 0); $stringData = $bugid . $sepChar . $jobName . $sepChar . $formatedSummary . $sepChar . $realname . $sepChar; for ($i = 1; $i <= 4; $i++) { if (array_key_exists($i, $dayList)) { $stringData .= $dayList[$i]; } $stringData .= $sepChar; } if (array_key_exists(5, $dayList)) { $stringData .= $dayList[5]; } $stringData .= "\n"; fwrite($fh, $stringData); } } catch (Exception $e) { self::$logger->error('exportWeekDetailsToCSV(): issue $bugid not found in mantis DB !'); } } }
/** * add Issue to command (in DB & current instance) * * @param int $bugid * @param bool $isDBonly if true, do not update current instance (PERF issue on) * * @return int insertion id if success, NULL on failure * @throws Exception */ public function addIssue($bugid, $isDBonly = false) { // security check if (!is_numeric($bugid)) { echo "<span style='color:red'>ERROR: Please contact your CodevTT administrator</span>"; $e = new Exception("SECURITY ALERT: Attempt to set non_numeric value ({$bugid})"); self::$logger->fatal("EXCEPTION addIssue: " . $e->getMessage()); self::$logger->fatal("EXCEPTION stack-trace:\n" . $e->getTraceAsString()); throw $e; } try { $issue = IssueCache::getInstance()->getIssue($bugid); } catch (Exception $e) { self::$logger->error("addIssue({$bugid}): issue {$bugid} does not exist !"); echo "<span style='color:red'>ERROR: issue '{$bugid}' does not exist !</span>"; return NULL; } $id = NULL; if (!array_key_exists($this->id, $issue->getCommandList())) { if (self::$logger->isDebugEnabled()) { self::$logger->debug("Add issue {$bugid} to command {$this->id}"); } $query = "INSERT INTO `codev_command_bug_table` (`command_id`, `bug_id`) VALUES ({$this->id}, {$bugid});"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } $id = SqlWrapper::getInstance()->sql_insert_id(); // add to WBS $wbsChild = new WBSElement(NULL, $this->wbsid, $bugid, $this->wbsid); if (self::$logger->isDebugEnabled()) { self::$logger->debug("Add issue {$bugid} from command {$this->id} to WBS root_id={$this->wbsid} wbse_id=" . $wbsChild->getId()); } } else { if (self::$logger->isDebugEnabled()) { self::$logger->debug("addIssue({$bugid}) to command {$this->id}: already in !"); } } if (!$isDBonly) { $this->getIssueSelection()->addIssue($bugid); } return $id; }
protected function display() { if (Tools::isConnectedUser()) { // only teamMembers & observers can access this page if (0 == $this->teamid || $this->session_user->isTeamCustomer($this->teamid)) { $this->smartyHelper->assign('accessDenied', TRUE); } else { $team = TeamCache::getInstance()->getTeam($this->teamid); // if first call to this page if (!array_key_exists('nextForm', $_POST)) { $activeMembers = $team->getActiveMembers(); if ($this->session_user->isTeamManager($this->teamid)) { $this->smartyHelper->assign('users', SmartyTools::getSmartyArray($activeMembers, $this->session_userid)); } else { // developper & manager can add timeTracks if (array_key_exists($this->session_userid, $activeMembers)) { $_POST['userid'] = $this->session_userid; $_POST['nextForm'] = "addHolidaysForm"; //$_POST['days'] = 'dayid'; } } } $nextForm = Tools::getSecurePOSTStringValue('nextForm', ''); if ($nextForm == "addHolidaysForm") { $userid = Tools::getSecurePOSTIntValue('userid', $this->session_userid); $managed_user = UserCache::getInstance()->getUser($userid); // dates $startdate = Tools::getSecurePOSTStringValue('startdate', date("Y-m-d")); $enddate = Tools::getSecurePOSTStringValue('enddate', ''); $defaultBugid = Tools::getSecurePOSTIntValue('bugid', 0); $action = Tools::getSecurePOSTStringValue('action', ''); $duration = Tools::getSecurePOSTNumberValue('duree', 0); if ("addHolidays" == $action) { // TODO add tracks ! $job = Tools::getSecurePOSTStringValue('job'); $duration = Tools::getSecurePOSTNumberValue('duree'); $holydays = Holidays::getInstance(); $keyvalue = Tools::getSecurePOSTStringValue('checkedDays'); $checkedDaysList = Tools::doubleExplode(':', ',', $keyvalue); $startTimestamp = Tools::date2timestamp($startdate); $endTimestamp = Tools::date2timestamp($enddate); // save to DB $weekday = date('l', strtotime($startdate)); $timestamp = $startTimestamp; while ($timestamp <= $endTimestamp) { // check if not a fixed holiday if (!$holydays->isHoliday($timestamp)) { // check existing timetracks on $timestamp and adjust duration $availabletime = $managed_user->getAvailableTime($timestamp); // not imput more than possible if ($duration >= $availabletime) { $imput = $availabletime; } else { $imput = $duration; } // check if weekday checkbox is checked if (1 == $checkedDaysList[$weekday]) { if ($duration > 0) { if (self::$logger->isDebugEnabled()) { self::$logger->debug(date("Y-m-d", $timestamp) . " duration {$imput} job {$job}"); } TimeTrack::create($managed_user->getId(), $defaultBugid, $job, $timestamp, $imput, $this->session_userid); } } } $timestamp = strtotime("+1 day", $timestamp); $weekday = date('l', strtotime(date("Y-m-d", $timestamp))); } // We redirect to holidays report, so the user can verify his holidays header('Location:holidays_report.php'); } $this->smartyHelper->assign('startDate', $startdate); $this->smartyHelper->assign('endDate', $enddate); if ($this->session_userid != $managed_user->getId()) { $this->smartyHelper->assign('otherrealname', $managed_user->getRealname()); } // Get Team SideTasks Project List $projList = $team->getProjects(true, false); foreach ($projList as $pid => $pname) { // we want only SideTasks projects try { if (!$team->isSideTasksProject($pid)) { unset($projList[$pid]); } } catch (Exception $e) { self::$logger->error("project {$pid}: " . $e->getMessage()); } } $extproj_id = Config::getInstance()->getValue(Config::id_externalTasksProject); $extProj = ProjectCache::getInstance()->getProject($extproj_id); $projList[$extproj_id] = $extProj->getName(); $defaultProjectid = Tools::getSecurePOSTIntValue('projectid', 0); if ($defaultBugid != 0 && $action == 'setBugId') { // find ProjectId to update categories $issue = IssueCache::getInstance()->getIssue($defaultBugid); $defaultProjectid = $issue->getProjectId(); } $this->smartyHelper->assign('projects', SmartyTools::getSmartyArray($projList, $defaultProjectid)); $this->smartyHelper->assign('issues', $this->getIssues($defaultProjectid, $projList, $extproj_id, $defaultBugid)); $this->smartyHelper->assign('jobs', $this->getJobs($defaultProjectid, $projList)); $this->smartyHelper->assign('duration', SmartyTools::getSmartyArray(TimeTrackingTools::getDurationList($team->getId()), $duration)); $this->smartyHelper->assign('userid', $managed_user->getId()); } } } }
/** * Get consistency errors * @param Command $cmd * @return mixed[] */ private function getConsistencyErrors(Command $cmd) { $consistencyErrors = array(); // if null, array_merge fails ! $cerrList = $cmd->getConsistencyErrors(); if (count($cerrList) > 0) { foreach ($cerrList as $cerr) { if (!is_null($cerr->userId)) { $user = UserCache::getInstance()->getUser($cerr->userId); } else { $user = NULL; } if (Issue::exists($cerr->bugId)) { $issue = IssueCache::getInstance()->getIssue($cerr->bugId); $projName = $issue->getProjectName(); $summary = $issue->getSummary(); } else { $projName = ''; $summary = ''; } $titleAttr = array(T_('Project') => $projName, T_('Summary') => $summary); $consistencyErrors[] = array('issueURL' => Tools::issueInfoURL($cerr->bugId, $titleAttr), 'issueStatus' => Constants::$statusNames[$cerr->status], 'user' => isset($user) ? $user->getName() : '', 'severity' => $cerr->getLiteralSeverity(), 'severityColor' => $cerr->getSeverityColor(), 'desc' => $cerr->desc); } } return $consistencyErrors; }
/** * all bugs changing status from 'resolved' to a higher status (validated, closed) * and that it is still validated at the end of the period. * * @param array $formattedBugidList comma-separated list to be included in SQL request * @param int $startTimestamp * @param int $endTimestamp * @return array bugidList */ private function getValidated($formattedBugidList, $start, $end) { $query = "SELECT bug.* " . "FROM `mantis_bug_table` as bug " . "JOIN `mantis_bug_history_table` as history ON bug.id = history.bug_id " . "WHERE bug.id IN ({$formattedBugidList}) " . "AND history.field_name='status' " . "AND history.date_modified >= {$start} AND history.date_modified < {$end} " . "AND history.old_value <= get_project_resolved_status_threshold(bug.project_id) " . "AND history.new_value > get_project_resolved_status_threshold(bug.project_id) " . "GROUP BY bug.id ;"; $result = SqlWrapper::getInstance()->sql_query($query); if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } $bugidList = array(); while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { // check that it is still in a 'validated' state. $issue = IssueCache::getInstance()->getIssue($row->id, $row); $latestStatus = $issue->getStatus($end); if ($latestStatus > $issue->getBugResolvedStatusThreshold()) { $bugidList[] = $row->id; } else { if (self::$logger->isDebugEnabled()) { self::$logger->debug("validated but then reopened: {$row->id}"); } } } // remove duplicated values $bugidList = array_unique($bugidList); return $bugidList; }