25 Commits
v1.3 ... v1.3.2

Author SHA1 Message Date
Thomas Keller
1c037f81a0 Release 1.3.2. 2012-05-09 22:09:13 +02:00
Thomas Keller
71c41fe940 Of course $ids should have been initialized beforehand... 2012-05-07 23:26:23 +02:00
Thomas Keller
8ad0707509 Fix the project display when no projects are available or visible. 2012-05-07 23:12:55 +02:00
Thomas Keller
a2d5b14a2c Start with 1.3.2 development. 2012-05-06 22:49:04 +02:00
Thomas Keller
16de6a0d77 Enter a release date and pin the current version. 2012-05-06 22:34:56 +02:00
Thomas Keller
03404adf64 - move getProjectsWithLabelCounts to IDF_Views (where the other functions
reside as well) and make it static
- refactor out the code from getProjects that determines which projects
  are visible by a user and use the same code to restrict the count that
  we calculate for all available project tags
- calculating the project stats is now no longer O(5n) but simply O(5)
  when it comes to SQL queries (where n is the number of filtered projects);
  remove the member statistic since it makes no sense in this context
2012-05-04 23:31:07 +02:00
Thomas Keller
dd2fa6f902 Remove OS9 line ending support again, this was left out for a reason.
Fix tests after issue 804 was fixed.
2012-05-04 01:01:33 +02:00
Thomas Keller
b6acf4c0e2 Replace the implementation of splitIntoLines by a new one that does
not need PHP's array_shift which tends to be very slow for arrays
with many thousand entries (fixes issue 804).
2012-05-04 00:48:53 +02:00
Thomas Keller
8db3c45763 Revamp this a little and make it jQuery 1.7 compatible (fixes issue 803) 2012-04-29 00:24:09 +02:00
Thomas Keller
e8882292b5 Improve the error we throw at the user if no configuration is found
to calculate the project activities.
2012-04-24 20:37:23 +02:00
Thomas Keller
bca3eb332e Reference the issue in which the Postgres issues have been tracked. 2012-04-22 23:11:48 +02:00
Thomas Keller
307c35ff42 Pulled updated French translation from Transifex (thanks to
Jonathan Aillet, again!)
2012-04-22 00:52:33 +02:00
Thomas Keller
786e9f81c0 Added Jonathan's email. 2012-04-21 19:03:25 +02:00
Thomas Keller
8cd19c0f53 Escape the xml file path arg. 2012-04-20 00:50:24 +02:00
Thomas Keller
d5394265ba Formatting fix. 2012-04-20 00:12:45 +02:00
Thomas Keller
0919cb83d8 Properly mark 1.3.1 dev version. 2012-04-19 23:40:50 +02:00
Thomas Keller
b7ad4bf47a Apparently the default project for tags is still 0, so make it explicit. 2012-04-19 00:37:09 +02:00
Thomas Keller
75f62663a9 Make the project field in the tags table nullable so it is (hopefully)
optional on setups with enabled foreign key constraints.
2012-04-19 00:14:10 +02:00
Thomas Keller
169fbe6216 Another Postgres issue fixed. 2012-04-18 23:22:32 +02:00
Thomas Keller
84d80af1ce Postgres seems to need every column in the group by, not only the PK. 2012-04-18 23:00:37 +02:00
Thomas Keller
d1542c9c00 Another Postgres issue (hopefully fixes issue 800). 2012-04-18 22:09:53 +02:00
Thomas Keller
4da01b2732 Another Postgres nuisance. 2012-04-18 22:05:17 +02:00
Thomas Keller
b44ad48fd5 Another PostgreSQL issue (hopefully) fixed. 2012-04-18 07:17:35 +02:00
Thomas Keller
3ae92627bc French translation pulled from transifex. 2012-04-18 00:59:41 +02:00
Thomas Keller
d46df5c129 Fix PostgreSQL compatibility issues. 2012-04-18 00:55:29 +02:00
16 changed files with 421 additions and 293 deletions

View File

@@ -22,6 +22,7 @@ Much appreciated contributors (in alphabetical order):
Janez Troha <http://www.dz0ny.info> - Slovenian translation Janez Troha <http://www.dz0ny.info> - Slovenian translation
Jean-Philippe Fleury <jpfleury> Jean-Philippe Fleury <jpfleury>
Jerry <lxb429@gmail.com> - Chinese translation Jerry <lxb429@gmail.com> - Chinese translation
Jonathan Aillet <jonathan.aillet@gmail.com> - French translation
Julien Issler <julien@issler.net> Julien Issler <julien@issler.net>
Litew <litew9@gmail.com> - Russian translation Litew <litew9@gmail.com> - Russian translation
Ludovic Bellière <xrogaan> Ludovic Bellière <xrogaan>

View File

@@ -1,4 +1,25 @@
# InDefero 1.3 - Sun Apr 15 21:10 2011 UTC # InDefero 1.3.2 - Wed May 09 20:05 2012 UTC
## Bugfixes
- Fix two bugs in the project list view if no project
is visible to the user or available in the forge (issue 805)
# InDefero 1.3.1 - Sun May 06 20:32 2012 UTC
## Bugfixes
- Compatiblity fixes for PostgreSQL (issue 800)
- Fix TOC generation in wiki (issue 803)
- Make the display of large files and diffs faster (issue 804)
- Make the project list faster and its tag list more accurate by not
counting projects that are invisible to the current user
## Language and Translations
- French translation updated (thanks to Jonathan Aillet!)
# InDefero 1.3 - Sun Apr 15 21:10 2012 UTC
This new major release of Indefero is possible thanks to the sponsor of This new major release of Indefero is possible thanks to the sponsor of
[Scilab Enterprises](http://www.scilab-enterprises.com/). [Scilab Enterprises](http://www.scilab-enterprises.com/).
@@ -34,7 +55,7 @@ or newer to properly run this version of Indefero!
emails for one object are uniquely identifyable to support a grouped view emails for one object are uniquely identifyable to support a grouped view
in email clients that support that. (fixes issues 334, 452, 480, and 791) in email clients that support that. (fixes issues 334, 452, 480, and 791)
- Indefero can now be configured to record activity metrics for all projects - Indefero can now be configured to record activity metrics for all projects
in a forge. This needs a special cron job named 'activitycron.php` in a forge. This needs a special cron job named `activitycron.php`
(under `scripts`) that is run on a regular basis. The metrics can be (under `scripts`) that is run on a regular basis. The metrics can be
fine-tuned via `activity_section_weights` and `activity_lookback` in fine-tuned via `activity_section_weights` and `activity_lookback` in
`idf.php` and the result is visible as green bar in the project list view. `idf.php` and the result is visible as green bar in the project list view.

View File

@@ -2,7 +2,7 @@
<?php <?php
$xmlfile = dirname(__FILE__) .'/test/report.xml'; $xmlfile = dirname(__FILE__) .'/test/report.xml';
passthru('phpunit --coverage-clover='.$xmlfile); passthru('phpunit --coverage-clover='.escapeshellarg($xmlfile));
$xml = simplexml_load_string(file_get_contents($xmlfile)); $xml = simplexml_load_string(file_get_contents($xmlfile));
unlink($xmlfile); unlink($xmlfile);
printf( printf(

View File

@@ -44,10 +44,15 @@ class IDF_ActivityTaxonomy
{ {
public static function recalculateTaxnomies(DateTime $date) public static function recalculateTaxnomies(DateTime $date)
{ {
$sectionWeights = Pluf::f('activity_section_weights', null);
$lookback = Pluf::f('activity_lookback', null);
if ($sectionWeights === null || $lookback === null) {
throw new LogicException('activity configuration is missing in idf.php');
}
// //
// query and normalize the section weights // query and normalize the section weights
// //
$sectionWeights = Pluf::f('activity_section_weights', array());
$allWeights = array_sum($sectionWeights); $allWeights = array_sum($sectionWeights);
if ($allWeights == 0) { if ($allWeights == 0) {
throw new LogicException('the sum of all "activity_section_weights" must not be 0'); throw new LogicException('the sum of all "activity_section_weights" must not be 0');
@@ -59,7 +64,6 @@ class IDF_ActivityTaxonomy
// //
// determine the date boundaries // determine the date boundaries
// //
$lookback = Pluf::f('activity_lookback', 0);
if ($lookback < 1) { if ($lookback < 1) {
throw new LogicException('lookback must be greater or equal to 1'); throw new LogicException('lookback must be greater or equal to 1');
} }
@@ -141,7 +145,12 @@ class IDF_ActivityTaxonomy
$cache[$argIdent] = 0; $cache[$argIdent] = 0;
list($higher, $lower) = $dateBoundaries; list($higher, $lower) = $dateBoundaries;
$sql = new Pluf_SQL('model_class IN ("'.implode('","', $classes).'") '. $db = Pluf::db();
$classes_esc = array();
foreach ($classes as $class) {
$classes_esc[] = $db->esc($class);
}
$sql = new Pluf_SQL('model_class IN ('.implode(',', $classes_esc).') '.
'AND creation_dtime >= %s AND creation_dtime <= %s', 'AND creation_dtime >= %s AND creation_dtime <= %s',
array($lower, $higher)); array($lower, $higher));

View File

@@ -147,7 +147,7 @@ class IDF_FileUtil
* Splits a string into separate lines while retaining the individual * Splits a string into separate lines while retaining the individual
* line ending character for every line. * line ending character for every line.
* *
* OS9 line endings are not supported. * OS 9 line endings are not supported.
* *
* @param string content * @param string content
* @param boolean if true, skip completely empty lines * @param boolean if true, skip completely empty lines
@@ -155,19 +155,16 @@ class IDF_FileUtil
*/ */
public static function splitIntoLines($content, $skipEmpty = false) public static function splitIntoLines($content, $skipEmpty = false)
{ {
$flags = PREG_SPLIT_OFFSET_CAPTURE; $last_off = 0;
if ($skipEmpty) $flags |= PREG_SPLIT_NO_EMPTY;
$splitted = preg_split("/\r\n|\n/", $content, -1, $flags);
$last_off = -1;
$lines = array(); $lines = array();
while (($split = array_shift($splitted)) !== null) { while (preg_match("/\r\n|\n/", $content, $m, PREG_OFFSET_CAPTURE, $last_off)) {
if ($last_off != -1) { $next_off = strlen($m[0][0]) + $m[0][1];
$lines[] .= substr($content, $last_off, $split[1] - $last_off); $line = substr($content, $last_off, $next_off - $last_off);
} $last_off = $next_off;
$last_off = $split[1]; if ($line !== $m[0][0] || !$skipEmpty) $lines[] = $line;
} }
$lines[] = substr($content, $last_off); $line = substr($content, $last_off);
if ($line !== false && strlen($line) > 0) $lines[] = $line;
return $lines; return $lines;
} }

View File

@@ -52,31 +52,6 @@ class IDF_Forge
$this->conf->setVal('project_labels', $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'
));
$maxProjectCount = 0;
foreach ($tagList as $tag) {
$maxProjectCount = max($maxProjectCount, $tag->project_count);
}
$tags = array();
foreach ($tagList as $tag) {
// group by class
if (!array_key_exists($tag->class, $tags)) {
$tags[$tag->class] = array();
}
$tag->rel_project_count = $tag->project_count / (double) $maxProjectCount;
$tags[$tag->class][] = $tag;
}
return $tags;
}
public function setCustomForgePageEnabled($enabled) { public function setCustomForgePageEnabled($enabled) {
$this->conf->setVal('custom_forge_page_enabled', $enabled); $this->conf->setVal('custom_forge_page_enabled', $enabled);
} }
@@ -92,4 +67,4 @@ class IDF_Forge
public function setCustomForgePageContent($content) { public function setCustomForgePageContent($content) {
$this->conf->setVal('custom_forge_page_content', $content); $this->conf->setVal('custom_forge_page_content', $content);
} }
} }

View File

@@ -0,0 +1,46 @@
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008-2011 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
function IDF_Migrations_25NullableProjectInTag_up($params=null)
{
$engine = Pluf::f('db_engine');
$db = Pluf::db();
if ($engine === 'PostgreSQL') {
$db->execute('ALTER TABLE '.$db->pfx.'idf_tags ALTER COLUMN project DROP NOT NULL');
} else if ($engine === 'MySQL') {
$db->execute('ALTER TABLE '.$db->pfx.'idf_tags MODIFY project MEDIUMINT NULL');
// this is only needed for non-transactional setups where MySQL set 0 as default value
$db->execute('UPDATE '.$db->pfx.'idf_tags SET project=NULL WHERE project=0');
}
}
function IDF_Migrations_25NullableProjectInTag_down($params=null)
{
$db = Pluf::db();
if ($engine === 'PostgreSQL') {
$db->execute('ALTER TABLE '.$db->pfx.'idf_tags ALTER COLUMN project SET NOT NULL');
} else if ($engine === 'MySQL') {
$db->execute('ALTER TABLE '.$db->pfx.'idf_tags MODIFY project MEDIUMINT NOT NULL');
}
}

View File

@@ -115,8 +115,7 @@ class IDF_Project extends Pluf_Model
array( array(
'join' => 'LEFT JOIN '.$activityTable.' ON current_activity='.$activityTable.'.id ' 'join' => 'LEFT JOIN '.$activityTable.' ON current_activity='.$activityTable.'.id '
.'LEFT JOIN '.$tagTable.' ON idf_project_id='.$this->getSqlTable().'.id', .'LEFT JOIN '.$tagTable.' ON idf_project_id='.$this->getSqlTable().'.id',
'select' => $this->getSelect().', date, value', 'select' => 'DISTINCT '.$this->getSelect().', date, value',
'group' => $this->getSqlTable().'.id',
'props' => array( 'props' => array(
'date' => 'current_activity_date', 'date' => 'current_activity_date',
'value' => 'current_activity_value' 'value' => 'current_activity_value'

View File

@@ -48,7 +48,8 @@ class IDF_Tag extends Pluf_Model
array( array(
'type' => 'Pluf_DB_Field_Foreignkey', 'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'IDF_Project', 'model' => 'IDF_Project',
'blank' => false, 'blank' => true,
'is_null' => true,
'verbose' => __('project'), 'verbose' => __('project'),
), ),
'class' => 'class' =>
@@ -76,13 +77,14 @@ class IDF_Tag extends Pluf_Model
); );
$table = $this->_con->pfx.'idf_project_idf_tag_assoc'; $table = $this->_con->pfx.'idf_project_idf_tag_assoc';
$cols = implode(', ', array_keys($this->_a['cols']));
$this->_a['views'] = array( $this->_a['views'] = array(
'join_projects' => 'join_projects' =>
array( array(
'join' => 'LEFT JOIN '.$table 'join' => 'LEFT JOIN '.$table
.' ON idf_tag_id=id', .' ON idf_tag_id=id',
'select' => $this->getSelect().',COUNT(idf_project_id) as project_count', 'select' => $this->getSelect().',COUNT(idf_project_id) as project_count',
'group' => 'idf_tag_id', 'group' => $cols,
'props' => array('project_count' => 'project_count'), 'props' => array('project_count' => 'project_count'),
), ),
); );
@@ -146,7 +148,7 @@ class IDF_Tag extends Pluf_Model
$class = trim($class); $class = trim($class);
$name = trim($name); $name = trim($name);
$gtag = new IDF_Tag(); $gtag = new IDF_Tag();
$sql = new Pluf_SQL('class=%s AND lcname=%s AND project=0', $sql = new Pluf_SQL('class=%s AND lcname=%s AND project IS NULL',
array($class, mb_strtolower($name))); array($class, mb_strtolower($name)));
$tags = $gtag->getList(array('filter' => $sql->gen())); $tags = $gtag->getList(array('filter' => $sql->gen()));
if ($tags->count() < 1) { if ($tags->count() < 1) {
@@ -154,6 +156,7 @@ class IDF_Tag extends Pluf_Model
$tag = new IDF_Tag(); $tag = new IDF_Tag();
$tag->name = $name; $tag->name = $name;
$tag->class = $class; $tag->class = $class;
$tag->project = null;
$tag->create(); $tag->create();
return $tag; return $tag;
} }

View File

@@ -83,7 +83,7 @@ class IDF_Template_MarkdownForge extends Pluf_Template_Tag
$name = $class; $name = $class;
$class = IDF_TAG_DEFAULT_CLASS; $class = IDF_TAG_DEFAULT_CLASS;
} }
$sql = new Pluf_SQL('class=%s AND lcname=%s AND project=0', $sql = new Pluf_SQL('class=%s AND lcname=%s AND project IS NULL',
array(strtolower($class), mb_strtolower($name))); array(strtolower($class), mb_strtolower($name)));
$tag = Pluf::factory('IDF_Tag')->getOne(array('filter' => $sql->gen())); $tag = Pluf::factory('IDF_Tag')->getOne(array('filter' => $sql->gen()));
} }

View File

@@ -85,7 +85,7 @@ class IDF_Views
$projects = self::getProjects($request->user, $tag, $order); $projects = self::getProjects($request->user, $tag, $order);
$stats = self::getProjectsStatistics($projects); $stats = self::getProjectsStatistics($projects);
$projectLabels = IDF_Forge::instance()->getProjectLabelsWithCounts(); $projectLabels = self::getProjectLabelsWithCounts($request->user);
return Pluf_Shortcuts_RenderToResponse('idf/listProjects.html', return Pluf_Shortcuts_RenderToResponse('idf/listProjects.html',
array('page_title' => __('Projects'), array('page_title' => __('Projects'),
@@ -371,6 +371,62 @@ class IDF_Views
} }
/**
* Returns a list of ids of projects that are visible for the given user
*
* @param Pluf_User $user
*/
private static function getUserVisibleProjectIds($user)
{
$db =& Pluf::db();
// the administrator can see all projects
if ($user->administrator) {
$ids = array();
$sql_results = $db->select(
'SELECT id FROM '.Pluf::f('db_table_prefix', '').'idf_projects'
);
foreach ($sql_results as $id) {
$ids[] = $id['id'];
}
return $ids;
}
// anonymous users can only see non-private projects
$false = Pluf_DB_BooleanToDb(false, $db);
$sql_results = $db->select(
'SELECT id FROM '.$db->pfx.'idf_projects '.
'WHERE '.$db->qn('private').'='.$false
);
$ids = array();
foreach ($sql_results as $id) {
$ids[] = $id['id'];
}
// registered users may additionally see private projects with which
// they're somehow affiliated
if (!$user->isAnonymous()) {
$perms = array(
Pluf_Permission::getFromString('IDF.project-member'),
Pluf_Permission::getFromString('IDF.project-owner'),
Pluf_Permission::getFromString('IDF.project-authorized-user')
);
$permSql = new Pluf_SQL(
"model_class='IDF_Project' AND owner_class='Pluf_User' ".
"AND owner_id=%s AND negative=".$false, $user->id
);
$rows = Pluf::factory('Pluf_RowPermission')->getList(array('filter' => $permSql->gen()));
if ($rows->count() > 0) {
foreach ($rows as $row) {
if (in_array($row->model_id, $ids))
continue;
$ids[] = $row->model_id;
}
}
}
return $ids;
}
/** /**
* Returns a list of projects accessible for the user and optionally filtered by tag. * Returns a list of projects accessible for the user and optionally filtered by tag.
* *
@@ -381,37 +437,14 @@ class IDF_Views
public static function getProjects($user, $tag = false, $order = 'name') public static function getProjects($user, $tag = false, $order = 'name')
{ {
$db =& Pluf::db(); $db =& Pluf::db();
$false = Pluf_DB_BooleanToDb(false, $db); $sql = new Pluf_SQL('1=1');
$sql = new Pluf_SQL(1);
if ($tag !== false) { if ($tag !== false) {
$sql->SAnd(new Pluf_SQL('idf_tag_id=%s', $tag->id)); $sql->SAnd(new Pluf_SQL('idf_tag_id=%s', $tag->id));
} }
if ($user->isAnonymous()) $projectIds = self::getUserVisibleProjectIds($user);
{ if (count($projectIds) > 0) {
$authSql = new Pluf_SQL('private=%s', $false); $sql->SAnd(new Pluf_SQL(sprintf($db->pfx.'idf_projects.id IN (%s)', implode(', ', $projectIds))));
$sql->SAnd($authSql);
} else
if (!$user->administrator) {
// grab the list of projects where the user is admin,
// member or authorized
$perms = array(
Pluf_Permission::getFromString('IDF.project-member'),
Pluf_Permission::getFromString('IDF.project-owner'),
Pluf_Permission::getFromString('IDF.project-authorized-user')
);
$permSql = new Pluf_SQL("model_class='IDF_Project' AND owner_class='Pluf_User' AND owner_id=%s AND negative=".$false, $user->id);
$rows = Pluf::factory('Pluf_RowPermission')->getList(array('filter' => $permSql->gen()));
$authSql = new Pluf_SQL('private=%s', $false);
if ($rows->count() > 0) {
$ids = array();
foreach ($rows as $row) {
$ids[] = $row->model_id;
}
$authSql->SOr(new Pluf_SQL(sprintf($db->pfx.'idf_projects.id IN (%s)', implode(', ', $ids))));
}
$sql->SAnd($authSql);
} }
$orderTypes = array( $orderTypes = array(
@@ -425,6 +458,46 @@ class IDF_Views
)); ));
} }
/**
* Returns a list of global tags each carrying the number of projects that have the
* particular tag set
*
* @param Pluf_User $user
* @return array
*/
public static function getProjectLabelsWithCounts($user) {
$sql = new Pluf_SQL('project IS NULL');
$projectIds = self::getUserVisibleProjectIds($user);
if (count($projectIds) > 0) {
$sql->SAnd(new Pluf_SQL(sprintf('idf_project_id IN (%s)', implode(', ', $projectIds))));
}
$tagList = Pluf::factory('IDF_Tag')->getList(array(
'filter' => $sql->gen(),
'view' => 'join_projects',
'order' => 'class ASC, lcname ASC'
));
$maxProjectCount = 0;
foreach ($tagList as $tag) {
$maxProjectCount = max($maxProjectCount, $tag->project_count);
}
$tags = array();
foreach ($tagList as $tag) {
// group by class
if (!array_key_exists($tag->class, $tags)) {
$tags[$tag->class] = array();
}
$tag->rel_project_count = $tag->project_count / (double) $maxProjectCount;
$tags[$tag->class][] = $tag;
}
return $tags;
}
/** /**
* Returns statistics on a list of projects. * Returns statistics on a list of projects.
* *
@@ -433,27 +506,30 @@ class IDF_Views
*/ */
public static function getProjectsStatistics($projects) public static function getProjectsStatistics($projects)
{ {
// Init the return var $projectIds = array(0);
$forgestats = array('downloads' => 0, foreach ($projects as $project) {
'reviews' => 0, $projectIds[] = $project->id;
'issues' => 0,
'docpages' => 0,
'commits' => 0);
// Count for each projects
foreach ($projects as $p) {
$pstats = $p->getStats();
$forgestats['downloads'] += $pstats['downloads'];
$forgestats['reviews'] += $pstats['reviews'];
$forgestats['issues'] += $pstats['issues'];
$forgestats['docpages'] += $pstats['docpages'];
$forgestats['commits'] += $pstats['commits'];
} }
// Count members $forgestats = array();
$sql = new Pluf_SQL('first_name != %s', array('---'));
$forgestats['members'] = Pluf::factory('Pluf_User') // count overall project stats
->getCount(array('filter' => $sql->gen())); $forgestats['total'] = 0;
$what = array(
'downloads' => 'IDF_Upload',
'reviews' => 'IDF_Review',
'issues' => 'IDF_Issue',
'docpages' => 'IDF_Wiki_Page',
'commits' => 'IDF_Commit',
);
foreach ($what as $key => $model) {
$count = Pluf::factory($model)->getCount(array(
'filter' => sprintf('project IN (%s)', implode(', ', $projectIds))
));
$forgestats[$key] = $count;
$forgestats['total'] += $count;
}
return $forgestats; return $forgestats;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -48,7 +48,6 @@
<strong>{trans 'Filtered project stats'}</strong> <strong>{trans 'Filtered project stats'}</strong>
<dl class="statistics smaller"> <dl class="statistics smaller">
<dt>{trans 'Members:'}</dt><dd>{$stats.members}</dd>
<dt>{trans 'Issues:'}</dt><dd>{$stats.issues}</dd> <dt>{trans 'Issues:'}</dt><dd>{$stats.issues}</dd>
<dt>{trans 'Commits:'}</dt><dd>{$stats.commits}</dd> <dt>{trans 'Commits:'}</dt><dd>{$stats.commits}</dd>
<dt>{trans 'Documentations:'}</dt><dd>{$stats.docpages}</dd> <dt>{trans 'Documentations:'}</dt><dd>{$stats.docpages}</dd>

View File

@@ -1,5 +1,5 @@
<?php <?php
return array( return array(
'version' => '1.3-dev', 'version' => '1.3.2',
'revision' => '$Format:%H$', 'revision' => '$Format:%H$',
); );

View File

@@ -80,7 +80,6 @@
0 => '', 0 => '',
1 => 11, 1 => 11,
2 => ' 2 => '
', ',
), ),
), ),
@@ -102,4 +101,4 @@
), ),
), ),
), ),
); );

View File

@@ -1,9 +1,12 @@
$(document).ready(function() { $(document).ready(function() {
$(":header", "#wiki-content").map(function(index) { $(":header", "#wiki-content").map(function(index) {
this.id = "wikititle_" + index; var $header = $(this);
$("<a href='#" + this.id + "'>" + jQuery.fn.text([this]) + "</a>") var $toc = $('#wiki-toc-content');
.addClass("wiki-" + this.tagName.toLowerCase()) $header.attr('id', 'wikititle_' + index);
.appendTo('#wiki-toc-content'); $('<a />').attr('href', '#' + $header.attr('id'))
.text($header.text())
.addClass("wiki-" + $header[0].tagName.toLowerCase())
.appendTo($toc);
}); });
if ($('#wiki-toc-content *').size() < 2) if ($('#wiki-toc-content *').size() < 2)
$('#wiki-toc').hide(); $('#wiki-toc').hide();