| <?php | |
| /*********************************************************************** | |
| * Copyright (c) Eclipse Foundation and others. | |
| * | |
| * This program and the accompanying materials | |
| * are made available under the terms of the Eclipse Public License 2.0 | |
| * which accompanies this distribution, and is available at | |
| * http://www.eclipse.org/legal/epl-2.0 | |
| ***********************************************************************/ | |
| require_once "../../eclipse.org-common/system/app.class.php"; | |
| require_once ($_SERVER ['DOCUMENT_ROOT'] . "/eclipse.org-common/system/nav.class.php"); | |
| require_once ($_SERVER ['DOCUMENT_ROOT'] . "/eclipse.org-common/system/menu.class.php"); | |
| $App = new App (); | |
| $Nav = new Nav (); | |
| $Menu = new Menu (); | |
| include ($App->getProjectCommon ()); | |
| require_once '../classes/Project.class.php'; | |
| require_once '../classes/ProjectStatusReporter.class.inc'; | |
| require_once '../classes/debug.php'; | |
| require_once '../classes/database.inc'; | |
| require_once '../classes/common.php'; | |
| require_once './charts.inc'; | |
| callIfNotCommitter(function() { | |
| header('Location: /projects'); | |
| exit; | |
| }); | |
| $pageTitle = "Eclipse Project Overview"; | |
| $pageKeywords = ""; | |
| $pageAuthor = "Wayne Beaton"; | |
| ob_start (); | |
| if (!(($id = @$_GET['id']) && isValidProjectId($id))) $id = null; | |
| $options = array(); | |
| $options['width'] = is_numeric(@$_GET['width']) ? @$_GET['width'] : 500; | |
| $options['height'] = is_numeric(@$_GET['height']) ? @$_GET['height'] : 200; | |
| $options['start'] = @$_GET['start'] ? date('Y-m-d', strtotime(@$_GET['start'])) : null; | |
| $options['end'] = @$_GET['end'] ? date('Y-m-d', strtotime(@$_GET['end'])) : null; | |
| // The 'committers' parameter when present or set to anything | |
| // but 'false' will result in charts being rendered for every | |
| // project committer. This can be expensive, so we only do it | |
| // when asked. | |
| $showCommitters = isset($_GET['committers']) && ($_GET['committers']!='false'); | |
| // NOTE that subprojects are not rendered when the committers are | |
| // (to do both can be *very* expensive for a top-level project). | |
| $showSubprojects = $showCommitters ? false : (isset($_GET['subprojects']) && ($_GET['subprojects']!='false')); | |
| // Add an entry to focus the report on every | |
| // top-level project to the navigation bar. | |
| $Nav->addNavSeparator("Report", "./report.php"); | |
| foreach(Project::getTopLevelProjects() as $project) { | |
| $Nav->addCustomNav($project->getName(), "?id={$project->getId()}", "_self", 2); | |
| } | |
| /** | |
| * Render an HTML report for a particular project. | |
| * | |
| * This uses an instance of the ProjectStatusReporter class to collect | |
| * and render specific bits of information about the project. | |
| * | |
| * @see ProjectStatusReporter | |
| * | |
| * @param Project $project | |
| * @param boolean $showCommitters | |
| */ | |
| function renderProjectReport(Project $project, $options, $showCommitters = false) { | |
| if (! $project) | |
| return; | |
| $status = new ProjectStatusReporter ( array ( | |
| $project->getId () | |
| ) ); | |
| echo "<h2><a href=\"?id={$project->getId()}\">{$project->getFormalName()}</a></h2>"; | |
| echo "<div style=\"margin-left:1em\">"; | |
| // Render alerts. Alerts are a warning about something that might | |
| // be odd or wrong about a project. We render each line using a | |
| // warning icon as the bullet. | |
| if ($alerts = $status->alerts($project)) { | |
| echo "<h3>Alerts</h3>"; | |
| echo "<ul style=\"list-style-type: none\">"; | |
| foreach($alerts as $message) { | |
| echo "<li><span style=\"color: red;\">⚠</span> {$message}</li>"; | |
| } | |
| echo "</ul>"; | |
| } | |
| // Render project stats in a table. This is a little clunky in my | |
| // attempt to make the specification of individual stats easily | |
| // extended while making the rendering very consistent. Each of the | |
| // "values" from the ProjectStatusReporter contains information about | |
| // a particular bit of data from the project (including a label and | |
| // corresponding value). | |
| echo "<h3>Lifetime stats</h3>"; | |
| echo "<div class=\"container\">"; | |
| $status->values ( $project->getId (), function ($column) { | |
| echo "<div class=\"row\"><div class=\"col-md-6\">{$column->getTitle()}:</div><div class=\"col-md-6\">{$column->getValue()}</div></div>"; | |
| } ); | |
| echo "</div>"; | |
| // Render charts | |
| // FIXME Experimental. | |
| $status->charts($project, function($builder) use (&$options) { | |
| $builder | |
| ->width ( $options['width'] ) | |
| ->height ( $options['height'] ) | |
| ->substitute (':start', $options['start']) | |
| ->substitute (':end', $options['end']) | |
| ->render(); | |
| }); | |
| // Show committers if required. | |
| // FIXME Experimental | |
| if ($showCommitters) { | |
| echo "<h3>Committer Activity</h3>"; | |
| echo "<p>Commit activity for current committers.</p>"; | |
| echo "<p>Commits in {$project->getName()} repositories specificially.</p>"; | |
| /* | |
| * Get a list of active committers and render an activity chart for each of them. | |
| */ | |
| $sql = " | |
| select | |
| concat(cm.first, ' ', cm.last) as name, cm.id | |
| from CommitterProject as cp | |
| join Committer as cm on cp.id=cm.id | |
| where cp.project=':project' and inactiveDate>now()"; | |
| query('dashboard', $sql, array(':project' => $project->getId()), function($row) use (&$project, &$options) { | |
| echo "<div style=\"margin-left:2em\">"; | |
| echo "<h4>{$row['name']} Commits</h4>"; | |
| ChartBuilder::named("committer_activity_" . rand()) | |
| ->query('dashboard', " | |
| select | |
| periods.period as period, | |
| if (commits.count is null, 0, commits.count) as count | |
| from ( | |
| select distinct period | |
| from CommitterProjectActivity | |
| where | |
| period | |
| between ( | |
| select min(period) | |
| from CommitterProjectActivity | |
| where | |
| login=':id' | |
| and project=':project') | |
| and date_format(now(),'%Y%m') | |
| ) as periods | |
| left join | |
| CommitterProjectActivity as commits | |
| on (periods.period = commits.period | |
| and commits.login=':id' | |
| and commits.project=':project') | |
| order by period | |
| ") | |
| ->substitute(':id', $row['id']) | |
| ->substitute(':project', $project->getId()) | |
| ->column ( 'Month', 'period', 'string', function ($value) { | |
| return asYearMonth ( $value ); | |
| } ) | |
| ->column ( 'Commits', 'count', 'number' ) | |
| ->columnChart () | |
| ->height ( $options['height'] ) | |
| ->width ( $options['width'] ) | |
| ->option ( 'legend', 'none' ) | |
| ->option ('hAxis', array('slantedText' => false)) | |
| ->render(); | |
| echo "</div>"; | |
| }); | |
| } | |
| echo "</div>"; | |
| } | |
| ?> | |
| <div id="maincontent"> | |
| <div id="midcolumn"> | |
| <h1><?=$pageTitle?></h1> | |
| <p>EXPERIMENTAL. This page shows some basic metrics.</p> | |
| <?php | |
| if ($id == null) { | |
| foreach(Project::getTopLevelProjects() as $project) { | |
| renderProjectReport($project, $options, false); | |
| } | |
| } else { | |
| $project = Project::getProject($id); | |
| if ($project) { | |
| renderProjectReport($project, $options, $showCommitters); | |
| if ($showSubprojects) { | |
| foreach($project->getChildren() as $child) { | |
| renderProjectReport($child, $options, false); | |
| } | |
| } | |
| } else { | |
| print "<p>There is no project with that ID.</p>"; | |
| } | |
| } | |
| ?> | |
| </div> | |
| </div> | |
| <?php | |
| $html = ob_get_contents (); | |
| ob_end_clean (); | |
| $App->generatePage ( null, $Menu, $Nav, $pageAuthor, $pageKeywords, $pageTitle, $html ); | |
| ?> |