diff --git a/src/IDF/Project.php b/src/IDF/Project.php index 2f09219..14f66c7 100644 --- a/src/IDF/Project.php +++ b/src/IDF/Project.php @@ -132,6 +132,47 @@ class IDF_Project extends Pluf_Model } return $projects[0]; } + + /** + * Returns the number of open/closed issues. + * + * @param string Status ('open'), 'closed' + * @param IDF_Tag Subfilter with a label (null) + * @return int Count + */ + public function getIssueCountByOwner($status='open') + { + switch ($status) { + case 'open': + $tags = implode(',', $this->getTagIdsByStatus('open')); + break; + case 'closed': + default: + $tags = implode(',', $this->getTagIdsByStatus('closed')); + break; + } + $sqlIssueTable = Pluf::factory('IDF_Issue')->getSqlTable(); + $query = <<<"QUERY" +SELECT uid AS id,COUNT(uid) AS nb +FROM ( + SELECT COALESCE(owner, -1) AS uid + FROM $sqlIssueTable + WHERE status IN ($tags) + ) AS ff +GROUP BY uid +QUERY; + $db = Pluf::db(); + $dbData = $db->select($query); + $ownerStatistics = array(); + foreach ($dbData as $k => $v) { + $key = ($v['id'] === '-1') ? null : $v['id']; + $ownerStatistics[$key] = (int)$v['nb']; + } + + arsort($ownerStatistics); + + return $ownerStatistics; + } /** * Returns the number of open/closed issues. diff --git a/src/IDF/Views/Issue.php b/src/IDF/Views/Issue.php index 91fdc40..fc9d7b4 100644 --- a/src/IDF/Views/Issue.php +++ b/src/IDF/Views/Issue.php @@ -77,6 +77,79 @@ class IDF_Views_Issue $params, $request); } + /** + * View the issue summary. + * TODO Add thoses data in cache, and process it only after an issue update + */ + public $summary_precond = array('IDF_Precondition::accessIssues'); + public function summary($request, $match) + { + $tagStatistics = array(); + $ownerStatistics = array(); + $status = array(); + $isTrackerEmpty = false; + + $prj = $request->project; + $opened = $prj->getIssueCountByStatus('open'); + $closed = $prj->getIssueCountByStatus('closed'); + + // Check if the tracker is empty + if ($opened === 0 && $closed === 0) { + $isTrackerEmpty = true; + } else { + if ($opened > 0 || $closed > 0) { + // Issue status statistics + $status['Open'] = array($opened, (int)(100 * $opened / ($opened + $closed))); + $status['Closed'] = array($closed, (int)(100 * $closed / ($opened + $closed))); + } + + if ($opened > 0) { + // Issue owner statistics + $owners = $prj->getIssueCountByOwner('open'); + foreach ($owners as $user => $nb) { + if ($user === '') { + $key = __('Not assigned'); + } else { + $obj = Pluf::factory('Pluf_User')->getOne(array('filter'=>'id='.$user)); + $key = $obj->first_name . ' ' . $obj->last_name; + } + $ownerStatistics[$key] = array($nb, (int)(100 * $nb / $opened)); + } + + // Issue class tag statistics + $tags = $prj->getTagCloud(); + foreach ($tags as $t) { + $tagStatistics[$t->class][$t->name] = array($t->nb_use, $t->id); + } + foreach($tagStatistics as $k => $v) { + $nbIssueInClass = 0; + foreach ($v as $val) { + $nbIssueInClass += $val[0]; + } + foreach ($v as $kk => $vv) { + $tagStatistics[$k][$kk] = array($vv[0], (int)(100 * $vv[0] / $nbIssueInClass), $vv[1]); + } + } + + // Sort + krsort($tagStatistics); + arsort($ownerStatistics); + } + } + + $title = sprintf(__('Summary of tracked issues in %s.'), (string) $prj); + + return Pluf_Shortcuts_RenderToResponse('idf/issues/summary.html', + array('page_title' => $title, + 'trackerEmpty' => $isTrackerEmpty, + 'project' => $prj, + 'tagStatistics' => $tagStatistics, + 'ownerStatistics' => $ownerStatistics, + 'status' => $status, + ), + $request); + } + /** * View the issues watch list of a given user. * Limited to a specified project diff --git a/src/IDF/conf/urls.php b/src/IDF/conf/urls.php index 55c47fa..03779c0 100644 --- a/src/IDF/conf/urls.php +++ b/src/IDF/conf/urls.php @@ -117,6 +117,11 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/$#', 'base' => $base, 'model' => 'IDF_Views_Issue', 'method' => 'index'); + +$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/summary/$#', + 'base' => $base, + 'model' => 'IDF_Views_Issue', + 'method' => 'summary'); $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/search/$#', 'base' => $base, diff --git a/src/IDF/templates/idf/issues/base.html b/src/IDF/templates/idf/issues/base.html index 779de34..636d5da 100644 --- a/src/IDF/templates/idf/issues/base.html +++ b/src/IDF/templates/idf/issues/base.html @@ -2,7 +2,8 @@ {block tabissues} class="active"{/block} {block subtabs}