diff --git a/src/IDF/Forge.php b/src/IDF/Forge.php index 97ce9c1..fc4d430 100644 --- a/src/IDF/Forge.php +++ b/src/IDF/Forge.php @@ -51,4 +51,23 @@ class IDF_Forge public function setProjectLabels($labels) { $this->conf->setVal('project_labels', $labels); } + + public function getProjectLabelsWithCounts() { + $sql = new Pluf_SQL('project=0'); + $tagList = Pluf::factory('IDF_Tag')->getList(array( + 'filter' => $sql->gen(), + 'view' => 'join_projects', + 'order' => 'class ASC, lcname ASC' + )); + + $tags = array(); + foreach ($tagList as $tag) { + // group by class + if (!array_key_exists($tag->class, $tags)) { + $tags[$tag->class] = array(); + } + $tags[$tag->class][] = $tag; + } + return $tags; + } } \ No newline at end of file diff --git a/src/IDF/Project.php b/src/IDF/Project.php index fc8a340..8cafd2c 100644 --- a/src/IDF/Project.php +++ b/src/IDF/Project.php @@ -108,13 +108,15 @@ class IDF_Project extends Pluf_Model 'verbose' => __('current project activity'), ), ); - $table = $this->_con->pfx.'idf_projectactivities'; + $activityTable = $this->_con->pfx.'idf_projectactivities'; + $tagTable = $this->_con->pfx.'idf_project_idf_tag_assoc'; $this->_a['views'] = array( - 'join_activities' => + 'join_activities_and_tags' => array( - 'join' => 'LEFT JOIN '.$table - .' ON current_activity='.$table.'.id', + 'join' => 'LEFT JOIN '.$activityTable.' ON current_activity='.$activityTable.'.id ' + .'LEFT JOIN '.$tagTable.' ON idf_project_id='.$this->getSqlTable().'.id', 'select' => $this->getSelect().', date, value', + 'group' => $this->getSqlTable().'.id', 'props' => array( 'date' => 'current_activity_date', 'value' => 'current_activity_value' diff --git a/src/IDF/Tag.php b/src/IDF/Tag.php index 24441a6..b9fa25d 100644 --- a/src/IDF/Tag.php +++ b/src/IDF/Tag.php @@ -75,6 +75,18 @@ class IDF_Tag extends Pluf_Model ), ); + $table = $this->_con->pfx.'idf_project_idf_tag_assoc'; + $this->_a['views'] = array( + 'join_projects' => + array( + 'join' => 'LEFT JOIN '.$table + .' ON idf_tag_id=id', + 'select' => $this->getSelect().',COUNT(idf_project_id) as project_count', + 'group' => 'idf_tag_id', + 'props' => array('project_count' => 'project_count'), + ), + ); + $this->_a['idx'] = array( 'lcname_idx' => array( diff --git a/src/IDF/Views.php b/src/IDF/Views.php index bd1569f..3eaa01c 100644 --- a/src/IDF/Views.php +++ b/src/IDF/Views.php @@ -38,6 +38,7 @@ class IDF_Views { // TODO: add a switch here later on to determine whether the project list // or a custom start page should be displayed + $match = array('', 'all', 'name'); return $this->listProjects($request, $match); } @@ -47,15 +48,30 @@ class IDF_Views * Only the public projects are listed or the private with correct * rights. */ - public function listProjects($request, $match, $api=false) + public function listProjects($request, $match) { - $projects = self::getProjects($request->user); - $stats = self::getProjectsStatistics($projects); + list(, $tagId, $order) = $match; + + $tag = false; + if ($tagId !== 'all') { + $tag = Pluf::factory('IDF_Tag')->get($match[1]); + // ignore non-global tags + if ($tag !== false && $tag->project > 0) { + $tag = false; + } + } + $order = in_array($order, array('name', 'activity')) ? $order : 'name'; + + $projects = self::getProjects($request->user, $tag, $order); + $stats = self::getProjectsStatistics($projects); + $projectLabels = IDF_Forge::instance()->getProjectLabelsWithCounts(); - if ($api == true) return $projects; return Pluf_Shortcuts_RenderToResponse('idf/listProjects.html', array('page_title' => __('Projects'), 'projects' => $projects, + 'projectLabels' => $projectLabels, + 'tag' => $tag, + 'order' => $order, 'stats' => new Pluf_Template_ContextVars($stats)), $request); } @@ -335,16 +351,20 @@ class IDF_Views } /** - * Returns a list of projects accessible for the user. + * Returns a list of projects accessible for the user and optionally filtered by tag. * * @param Pluf_User + * @param IDF_Tag * @return ArrayObject IDF_Project */ - public static function getProjects($user) + public static function getProjects($user, $tag = false, $order = 'name') { $db =& Pluf::db(); $false = Pluf_DB_BooleanToDb(false, $db); $sql = new Pluf_SQL(1); + if ($tag !== false) { + $sql->SAnd(new Pluf_SQL('idf_tag_id=%s', $tag->id)); + } if ($user->isAnonymous()) { @@ -373,10 +393,14 @@ class IDF_Views $sql->SAnd($authSql); } + $orderTypes = array( + 'name' => 'name ASC', + 'activity' => 'value DESC, name ASC', + ); return Pluf::factory('IDF_Project')->getList(array( 'filter'=> $sql->gen(), - 'view' => 'join_activities', - 'order' => 'name ASC' + 'view' => 'join_activities_and_tags', + 'order' => $orderTypes[$order], )); } @@ -397,7 +421,7 @@ class IDF_Views // Count for each projects foreach ($projects as $p) { - $pstats = $p->getStats (); + $pstats = $p->getStats(); $forgestats['downloads'] += $pstats['downloads']; $forgestats['reviews'] += $pstats['reviews']; $forgestats['issues'] += $pstats['issues']; @@ -405,9 +429,6 @@ class IDF_Views $forgestats['commits'] += $pstats['commits']; } - // Count projects - $forgestats['projects'] = count($projects); - // Count members $sql = new Pluf_SQL('first_name != %s', array('---')); $forgestats['members'] = Pluf::factory('Pluf_User') diff --git a/src/IDF/conf/urls.php b/src/IDF/conf/urls.php index 1755ae6..5995e5b 100644 --- a/src/IDF/conf/urls.php +++ b/src/IDF/conf/urls.php @@ -29,7 +29,7 @@ $ctl[] = array('regex' => '#^/$#', 'model' => 'IDF_Views', 'method' => 'index'); -$ctl[] = array('regex' => '#^/label/(\d+)/$#', +$ctl[] = array('regex' => '#^/label/(\w+)/(\w+)/$#', 'base' => $base, 'model' => 'IDF_Views', 'method' => 'listProjects'); diff --git a/src/IDF/templates/idf/issues/search.html b/src/IDF/templates/idf/issues/search.html index 4c0b720..4ffce24 100644 --- a/src/IDF/templates/idf/issues/search.html +++ b/src/IDF/templates/idf/issues/search.html @@ -22,11 +22,11 @@ {$tag.class}:{$tag.name}
{/blocktrans} {else} {* yes, this is duplicated from tags-cloud.html, but the code there cannot be easily overridden *} -