Indefero

Indefero Commit Details


Date:2012-05-04 16:31:07 (12 years 7 months ago)
Author:Thomas Keller
Branch:develop, release-1.3
Commit:03404adf6437565764ddf8fd9d66b0fb99691ff3
Parents: dd2fa6f90290c91bda577fc7c2a9bfc1398edb7b
Message:- 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

Changes:

File differences

NEWS.mdtext
55
66
77
8
9
810
911
1012
- Compatiblity fixes for PostgreSQL (fixes issue 800)
- Fix TOC generation in wiki (issue 803)
- Make the display of large files and diffs faster (fixes 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
src/IDF/Forge.php
5252
5353
5454
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
8055
8156
8257
$this->conf->setVal('project_labels', $labels);
}
public function getProjectLabelsWithCounts() {
$sql = new Pluf_SQL('project IS NULL');
$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) {
$this->conf->setVal('custom_forge_page_enabled', $enabled);
}
src/IDF/Views.php
8585
8686
8787
88
88
8989
9090
9191
......
372372
373373
374374
375
375
376376
377
378
379
377
380378
381
379
382380
383381
382
383
384
385
386
387
388
389
390
391
392
393
384394
385
386
387
395
396
397
398
399
400
401
402
388403
389404
390
391
392
393
394
395
396
397
405
406
407
398408
399409
400410
401411
402412
403
413
414
415
416
404417
405
406
407418
408
409419
420
421
410422
411423
412
413424
414
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
415447
416448
417449
......
426458
427459
428460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
429501
430502
431503
......
433505
434506
435507
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
508
509
510
451511
452512
453
454
455
456
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
457532
458533
459534
$projects = self::getProjects($request->user, $tag, $order);
$stats = self::getProjectsStatistics($projects);
$projectLabels = IDF_Forge::instance()->getProjectLabelsWithCounts();
$projectLabels = self::getProjectLabelsWithCounts($request->user);
return Pluf_Shortcuts_RenderToResponse('idf/listProjects.html',
array('page_title' => __('Projects'),
}
/**
* Returns a list of projects accessible for the user and optionally filtered by tag.
* Returns a list of ids of projects that are visible for the given user
*
* @param Pluf_User
* @param IDF_Tag
* @return ArrayObject IDF_Project
* @param Pluf_User $user
*/
public static function getProjects($user, $tag = false, $order = 'name')
private static function getUserVisibleProjectIds($user)
{
$db =& Pluf::db();
// the administrator can see all projects
if ($user->administrator) {
$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 = new Pluf_SQL('1=1');
if ($tag !== false) {
$sql->SAnd(new Pluf_SQL('idf_tag_id=%s', $tag->id));
$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'];
}
if ($user->isAnonymous())
{
$authSql = new Pluf_SQL($db->qn('private').'='.$false);
$sql->SAnd($authSql);
} else
if (!$user->administrator) {
// grab the list of projects where the user is admin,
// member or authorized
// 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);
$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($db->qn('private').'='.$false);
if ($rows->count() > 0) {
$ids = array();
foreach ($rows as $row) {
if (in_array($row->model_id, $ids))
continue;
$ids[] = $row->model_id;
}
$authSql->SOr(new Pluf_SQL(sprintf($db->pfx.'idf_projects.id IN (%s)', implode(', ', $ids))));
}
$sql->SAnd($authSql);
}
return $ids;
}
/**
* 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, $tag = false, $order = 'name')
{
$db =& Pluf::db();
$sql = new Pluf_SQL('1=1');
if ($tag !== false) {
$sql->SAnd(new Pluf_SQL('idf_tag_id=%s', $tag->id));
}
$projectIds = self::getUserVisibleProjectIds($user);
if (count($projectIds) > 0) {
$sql->SAnd(new Pluf_SQL(sprintf($db->pfx.'idf_projects.id IN (%s)', implode(', ', $projectIds))));
}
$orderTypes = array(
}
/**
* 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.
*
* @param ArrayObject IDF_Project
*/
public static function getProjectsStatistics($projects)
{
// Init the return var
$forgestats = array('downloads' => 0,
'reviews' => 0,
'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'];
$projectIds = array();
foreach ($projects as $project) {
$projectIds[] = $project->id;
}
// Count members
$sql = new Pluf_SQL('first_name != %s', array('---'));
$forgestats['members'] = Pluf::factory('Pluf_User')
->getCount(array('filter' => $sql->gen()));
$forgestats = array();
// count overall project stats
$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;
}
src/IDF/templates/idf/listProjects.html
4848
4949
5050
51
5251
5352
5453
<strong>{trans 'Filtered project stats'}</strong>
<dl class="statistics smaller">
<dt>{trans 'Members:'}</dt><dd>{$stats.members}</dd>
<dt>{trans 'Issues:'}</dt><dd>{$stats.issues}</dd>
<dt>{trans 'Commits:'}</dt><dd>{$stats.commits}</dd>
<dt>{trans 'Documentations:'}</dt><dd>{$stats.docpages}</dd>

Archive Download the corresponding diff file

Page rendered in 0.09816s using 13 queries.