blob: 0f9972f57c61d8a6c161c649641e277162ba34fc [file] [log] [blame]
<?php
/*******************************************************************************
* Copyright (c) 2008, 2011 Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Bjorn Feeman-Benson (Eclipse Foundation) - initial API and implementation
* Wayne Beaton (Eclipse Foundation) - Bug 344065
*******************************************************************************/
require_once("common/shared_functions.php");
/*------------------------------------------------------------------------------
Inputs:
$projectids = array of projectid
Outputs:
$errors = array of error messages
$activecqs = array of rows from bugs from ipzilla database
row includes extra columns for keywords keyword_*, e.g., keyword_modified:
modified, unmodified, binary, source, sourceandbinary
$unusedcqs = array of .ditto.
$pendingcqs = array of .ditto.
$prereqcqs = array of .ditto.
$committers_at_least_once = array of PID, FName, LName, Name1, Name2, Comment
$committers_never = array of .ditto.
$committers_excluded = array of .ditto.
$contributors = array of [login name] =>
array of
realname =>
login_name =>
bugs => array of
bug_id =>
type => 'A' (attachment) | 'C' (comment)
attach_id => (also comment_id if type = 'C')
size =>
bug_desc =>
attach_desc =>
$contributors_excluded = array of [login name] =>
array of
realname =>
login_name =>
bugs => array of
bug_id =>
type => 'A' (attachment) | 'C' (comment)
attach_id => (also comment_id if type = 'C')
size =>
bug_desc =>
attach_desc =>
Functions:
pretty_size( $v )
*------------------------------------------------------------------------------
*/
function get_ip_log_data_structures( $projectids ) {
global $App;
$errors = array();
/*=================================================
* C Q S
*/
/*
* Step 1:
* Translate the projectids into ipzilla component ids.
* Error if a component name does not match.
*/
$componentids = array();
foreach( $projectids as $projectid ) {
$sql = "SELECT id FROM components WHERE name = '" . $projectid . "'";
$result = $App->ipzilla_sql( $sql );
if( ($row = mysql_fetch_array($result)) ) {
$componentids[] = $row[0];
} else {
$errors[] = "Error: $projectid does not exist in ipzilla; contact the EMO.";
}
}
/*
* If the conpentids is empty then we found no projects so return, else we get an SQL error
*/
if(empty($componentids)){
return array(
$errors,
$activecqs,
$unusedcqs,
$pendingcqs,
$prereqcqs,
$committers_at_least_once,
$committers_never,
$committers_excluded,
// $contributors,
// $contributors_excluded
);
}
/*
* Step 2:
* Get all the CQs for the projects
*/
$sql = "SELECT * FROM bugs
WHERE component_id IN ( " . implode( ',', $componentids ) . ")
";
$result = $App->ipzilla_sql( $sql );
$activecqs = array();
$unusedcqs = array();
$pendingcqs = array();
$prereqcqs = array();
$bugids = array();
$keywords = array( 'modified', 'unmodified', 'source', 'binary', 'sourceandbinary',
'obsolete', 'unused', 'withdrawn', 'nonepl' , 'epl', 'thirdparty', 'projectcode');
while( $row = mysql_fetch_assoc($result) ) {
foreach( $keywords as $key ) {
$row["keyword_$key"] = 0;
}
$bugids[] = $row['bug_id'];
switch( $row['bug_severity'] ) {
case 'approved_all_projects':
case 'approved_one_project':
case 'approved':
case 'reuse':
$activecqs[$row['bug_id']] = $row;
break;
case 'exempt_prereq':
case 'workswith':
case 'prereq':
$prereqcqs[$row['bug_id']] = $row;
break;
case 'awaiting_analysis':
case 'awaiting_committer':
case 'awaiting_emo':
case 'awaiting_pmc':
case 'awaiting_project':
case 'awaiting_triage':
case 'new':
case 'under_review':
if( ($row['bug_status'] == 'RESOLVED'
|| $row['bug_status'] == 'CLOSED')
&& $row['resolution'] == 'FIXED' ) {
$activecqs[$row['bug_id']] = $row;
} else if( $row['bug_status'] == 'RESOLVED'
|| $row['bug_status'] == 'CLOSED') {
/* ignore */
} else {
$pendingcqs[$row['bug_id']] = $row;
}
break;
case 'closed':
case 'rejected':
case 'withdrawn':
/* ignore */
break;
default:
$pendingcqs[$row['bug_id']] = $row;
break;
}
}
/*
* Step 3:
* Collect the usage and used keywords for the cqs
*/
if(!empty($bugids)){
$sql = "
SELECT bug_id, name FROM keywords
LEFT JOIN keyworddefs ON keywordid = id
WHERE name in ( 'modified', 'unmodified', 'source', 'binary', 'sourceandbinary',
'obsolete', 'unused', 'withdrawn', 'nonepl', 'epl', 'thirdparty', 'projectcode' )
AND bug_id IN ( " . implode( ",", $bugids ) . " )
";
$result = $App->ipzilla_sql( $sql );
while( $row = mysql_fetch_assoc($result) ) {
if( isset($activecqs[$row['bug_id']]) )
$activecqs[$row['bug_id']]["keyword_" . $row['name']] = 1;
if( isset($pendingcqs[$row['bug_id']]) )
$pendingcqs[$row['bug_id']]["keyword_" . $row['name']] = 1;
if( isset($prereqcqs[$row['bug_id']]) )
$prereqcqs[$row['bug_id']]["keyword_" . $row['name']] = 1;
}
}
/*
* Setp 3.5:
* drop any CQs that are under the EPL and without keyword nonepl
* drop any CQs with the keyword EPL
*/
$activecqs = remove_EPL_CQs($activecqs);
$pendingcqs = remove_EPL_CQs($pendingcqs);
$prereqcqs = remove_EPL_CQs($prereqcqs);
/*
* Step 4:
* Move the unused CQs from active, pending, and prereq to unused
*/
$xa = array();
$xp = array();
$xr = array();
foreach( $activecqs as $key => $value ) {
if( $value['keyword_obsolete'] || $value['keyword_unused'] || $value['keyword_withdrawn']
/* || $value['keyword_nonepl'] -- removed by Bjorn 24-Oct because it was excluding obviously active CQs */ )
$unusedcqs[$key] = $value;
else
$xa[$key] = $value;
}
foreach( $pendingcqs as $key => $value ) {
if( $value['keyword_obsolete'] || $value['keyword_unused'] || $value['keyword_withdrawn'] )
$unusedcqs[$key] = $value;
else
$xp[$key] = $value;
}
foreach( $prereqcqs as $key => $value ) {
if( $value['keyword_obsolete'] || $value['keyword_unused'] || $value['keyword_withdrawn'] )
$unusedcqs[$key] = $value;
else
$xr[$key] = $value;
}
$activecqs = $xa;
$pendingcqs = $xp;
$prereqcqs = $xr;
/*=================================================
* C O M M I T T E R S
*/
/*
* Step 1:
* Find ALL the past and present committers on this project
* complete with their current employer's name
*/
$all_committers_in_db = array();
// $sql = "
// SELECT DISTINCT(People.PersonID) as PID, FName, LName, Name1, Name2
// FROM PeopleProjects, Projects, People
// LEFT JOIN OrganizationContacts
// ON OrganizationContacts.PersonID = People.PersonID
// LEFT JOIN Organizations
// ON OrganizationContacts.OrganizationID = Organizations.OrganizationID
// LEFT JOIN IPLogCorrections ON (IPLogCorrections.ProjectID=Projects.ProjectID and IPLogCorrections.ItemID=People.PersonID)
// WHERE PeopleProjects.Relation in ('CM')
// AND People.PersonID = PeopleProjects.PersonID
// AND Projects.ProjectID = PeopleProjects.ProjectID
// AND (
// Projects.ProjectID IN ( '" . implode( "','", $projectids ) . "' )
// OR (
// ParentProjectID IN ( '" . implode( "','", $projectids ) . "' )
// AND IsComponent = 1)
// )
// AND (IPLogCorrections.Action<>'REMOVE')
// ";
/*
* WTB: Modified to exclude committers only from the projects that they are actually
* excluded from. Original code excluded a committer from the rollup ip log (i.e.
* a log for multiple projects) if they are excluded from any project in the rollup.
* By making the exclusion part of the query, we can make sure that those committeres
* who should be there actually appear. To make this work, I had to turn off the
* tracking of excluded entries which may have the effect of making it impossible to
* "unexclude" somebody.
*/
// SELECT DISTINCT(People.PersonID) as PID, FName, LName, Name1, Name2
//FROM People
//JOIN PeopleProjects ON (People.PersonID = PeopleProjects.PersonID)
//JOIN Projects ON (Projects.ProjectID = PeopleProjects.ProjectID)
//LEFT JOIN OrganizationContacts ON OrganizationContacts.PersonID = People.PersonID
//LEFT JOIN Organizations ON OrganizationContacts.OrganizationID = Organizations.OrganizationID
//LEFT JOIN IPLogCorrections ON (IPLogCorrections.ProjectID=Projects.ProjectID and IPLogCorrections.ItemID=People.PersonID and IPLogCorrections.Action = 'REMOVE')
//WHERE PeopleProjects.Relation in ('CM')
//
//AND Projects.ProjectID IN ( 'webtools.jsf', 'webtools.common')
//or (ParentProjectID IN ( 'webtools.jsf', 'webtools.common') and IsComponent=1)
//AND (IPLogCorrections.Action is NULL)
$sql = "
SELECT DISTINCT(People.PersonID) as PID, FName, LName, Name1, Name2
FROM People
JOIN PeopleProjects ON (People.PersonID = PeopleProjects.PersonID)
JOIN Projects ON (Projects.ProjectID = PeopleProjects.ProjectID)
LEFT JOIN OrganizationContacts ON OrganizationContacts.PersonID = People.PersonID
LEFT JOIN Organizations ON OrganizationContacts.OrganizationID = Organizations.OrganizationID
LEFT JOIN IPLogCorrections ON (IPLogCorrections.ProjectID=Projects.ProjectID and IPLogCorrections.ItemID=People.PersonID and IPLogCorrections.Action = 'REMOVE')
WHERE PeopleProjects.Relation in ('CM')
AND (Projects.ProjectID IN ( '" . implode( "','", $projectids ) . "' )
OR (ParentProjectID IN ( '" . implode( "','", $projectids ) . "' ) AND IsComponent = 1))
AND (IPLogCorrections.Action is NULL)";
if (isset($_GET['debug'])) echo $sql;
$result = $App->foundation_sql( $sql );
mysql_error_check();
while( $row = mysql_fetch_assoc($result) ) {
$row['Comment'] = '';
$all_committers_in_db[ $row['PID'] ] = $row;
}
/*
* Step 2:
* Get the commits activity to figure out everyone who
* ever committed code to the project.
*/
$blob = file("http://dash.eclipse.org/dash/commits/web-api/commits-index.php?projectid=" . implode(',', $projectids) );
$cm_counts = array();
foreach( $blob as $line ) {
$words = split( "\t", $line );
if( substr($words[0],0,1) == '#' ) // skip comments
continue;
if( $words[2] == 999999 ) // only use the 'inf' records
// WTB Only add if the person is actually a committer on the project.
if (isset($all_committers_in_db[$words[0]]))
$cm_counts[$words[0]] = $words[1];
}
/*
* Step 3:
* Get the corrections ItemType = COMMITTR, Action = ?
* COMENT: Just comments
* REMOVE: Committer is not a committer (move to excluded list)
* ACTIVE: Committer was active (move to at least once list)
* ADD: Add a committer (move to at least once list)
*/
$sql = "
SELECT * FROM IPLogCorrections
WHERE ProjectID IN ( '" . implode( "','", $projectids ) . "' )
AND ItemType = 'COMMITTR'
";
$result = $App->foundation_sql( $sql );
$committer_corrections = array();
while( $row = mysql_fetch_assoc( $result ) ) {
$committer_corrections[$row['Action']][$row['ItemID']] = $row;
}
/*
* Step 4:
* Compute three lists: committers who once committed code
* and committers who appear never to have committed any code
* and committers who have been excluded
*/
$committers_at_least_once = array();
$committers_never = array();
$committers_excluded = array();
foreach( $all_committers_in_db as $key => $row ) {
if( isset($committer_corrections['COMENT'][$key]) ) {
$row['Comment'] = $committer_corrections['COMENT'][$key]['Comment'];
}
// if( isset($committer_corrections['REMOVE'][$key]) ) {
// //$committers_excluded[$key] = $row;
// } else {
if( isset($committer_corrections['ACTIVE'][$key]) ) {
if (isset($_GET['debug'])) echo "<p>Committers forced active: $key</p>";
$committers_at_least_once[$key] = $row;
} else {
if( isset($cm_counts[$key]) ) {
if (isset($_GET['debug'])) echo "<p>Committers at least once: $key</p>";
$committers_at_least_once[$key] = $row;
} else {
if (isset($_GET['debug'])) echo "<p>Committers never: $key</p>";
$committers_never[$key] = $row;
}
}
// }
}
foreach( $cm_counts as $key => $row ) {
if( !isset($all_committers_in_db[$key] ) ) {
if( isset($committer_corrections['REMOVE'][$key]) ) {
$committers_excluded[$key] =
array( 'PID' => $key,
'FName' => $key,
'LName' => '',
'Name1' => '(not a current committer)',
'Name2' => '',
'Comment' =>
(isset($committer_corrections['COMENT'][$key]['Comment']) ?
$committer_corrections['COMENT'][$key]['Comment'] : '' )
);
} else {
$committers_at_least_once[$key] =
array( 'PID' => $key,
'FName' => $key,
'LName' => '',
'Name1' => '(not a current committer)',
'Name2' => '',
'Comment' =>
(isset($committer_corrections['COMENT'][$key]['Comment']) ?
$committer_corrections['COMENT'][$key]['Comment'] : '' )
);
}
}
}
if( isset($committer_corrections['ADD']) ) {
foreach( $committer_corrections['ADD'] as $key => $rec ) {
$x = explode( '|', $rec['Value'] );
$committers_at_least_once[$key] =
array( 'PID' => $key,
'FName' => $x[0],
'LName' => '',
'Name1' => $x[1],
'Name2' => '',
'Comment' => $rec['Comment'] );
}
}
/*
* HACK
* Identify historical CDT committers and add them to the
* list of committers (if they're not already there).
* This hack needs to be generalized (and made into a non hack).
* See Bug 435987
*/
if (in_array('tools.cdt', $projectids)) {
$sql = "SELECT
if(!isnull(cm.id),cm.id,substring_index(a.email,'@',1)) as PID,
if(!isnull(cm.first),cm.first,substring_index(a.name,' ',1)) as FName,
if(!isnull(cm.last),cm.last,substring_index(a.name,' ',-1)) as LName,
null as Name1,
null as Name2,
'' as Comment
from GitRepo as r
join GitCommit as c on r.path=c.path
join GitCommitAuthor as a on c.path=a.path and c.ref=a.ref
join GitCommitFile as f on c.path=f.path and c.ref=f.ref
left join CommitterEmail as ce on ce.email=a.email
left join Committer as cm on ce.id=cm.id
left join CommitterProject as cp
on r.project=cp.project
and cp.id=cm.id
where r.project in ('tools.cdt')
and a.email not in ('cvs', 'cvs2git')
and a.name not in ('cvs2svn', 'cvs2git migration')
and a.name not like 'uid%'
and c.date < date('2011-06-25')
and cp.id is null
group by a.name";
$result = $App->dashboard_sql($sql);
while ($row = mysql_fetch_assoc($result)) {
$key = $row['PID'];
if (isset($committers_at_least_once[$key])) continue;
$committers_at_least_once[$key] = $row;
}
}
/*
* Step 5:
* Sort the lists
*/
uasort( $committers_at_least_once, 'sortcms' );
uasort( $committers_never, 'sortcms' );
uasort( $committers_excluded, 'sortcms' );
// WTB Moved to IPLog.class.php
// /*=================================================
// * C O N T R I B U T O R S
// */
// /*
// * Step 1:
// * Get the bugzilla project info records for each project.
// * Error if a project does not have a bugzilla record.
// */
// $bugzillakeys = array(); // list of productname, '' or productname, component
// foreach( $projectids as $projectid ) {
// $project = new ProjectInfoData($projectid);
// if( $project->bugzilla ) {
// foreach( $project->bugzillas as $bugzilla ) {
// if( $bugzilla->productname ) {
// if( $bugzilla->components ) {
// $x = explode(',', $bugzilla->components);
// foreach( $x as $component ) {
// $bugzillakeys[] = array( trim($bugzilla->productname), trim($component) );
// }
// } else {
// $bugzillakeys[] = array( trim($bugzilla->productname), '' );
// }
// } else {
// $errors[] = "
// Error: the project meta-data key 'bugzilla/productname' \"" . $bugzillakeys[$i][0] . "\"
// is blank;
// use <a href='http://portal.eclipse.org/'>the portal</a>
// \"[maintain] project info meta-data\" to enter the correct
// <a href='http://bugs.eclipse.org/'>bugzilla</a> Product name for $projectid";
// }
// }
// } else {
// $errors[] = "
// Error: there is no project meta-data key 'bugzilla' for $projectid;
// use <a href='http://portal.eclipse.org/'>the portal</a>
// \"[maintain] project info meta-data\" to enter the correct
// <a href='http://bugs.eclipse.org/'>bugzilla</a> Product name for $projectid";
// }
// }
// /*
// * Step 2:
// * Translate the productnames and components into ids.
// * Error if a productname or component name does not match.
// */
// $lastname = '';
// $lastid = 0;
// for( $i = 0; $i < count($bugzillakeys); $i += 1 ) {
// if( $lastname == $bugzillakeys[$i][0] ) {
// $bugzillakeys[$i][2] = $lastid;
// } else {
// $sql = "SELECT id FROM products WHERE name = '" . $bugzillakeys[$i][0] . "' LIMIT 1";
// $result = $App->bugzilla_sql( $sql );
// if( ($row = mysql_fetch_array($result)) ) {
// $bugzillakeys[$i][2] = $row[0];
// $lastname = $bugzillakeys[$i][0];
// $lastid = $row[0];
// } else {
// $errors[] = "
// Error: the project meta-data key 'bugzilla/productname' \"" . $bugzillakeys[$i][0] . "\"
// is not a valid Product name in <a href='http://bugs.eclipse.org/'>bugzilla</a>;
// use <a href='http://portal.eclipse.org/'>the portal</a>
// \"[maintain] project info meta-data\" to enter the correct
// bugzilla Product name for $projectid";
// }
// }
// if( $bugzillakeys[$i][1] ) {
// $sql = "SELECT id FROM components WHERE name = '" . $bugzillakeys[$i][1] . "'
// AND product_id = " . $lastid . " LIMIT 1";
// $result = $App->bugzilla_sql( $sql );
// if( ($row = mysql_fetch_array($result)) ) {
// $bugzillakeys[$i][3] = $row[0];
// } else {
// $errors[] = "
// Error: the project meta-data key 'bugzilla/components' \"" . $bugzillakeys[$i][1] . "\"
// is not a valid Component name in the \"" . $bugzillakeys[$i][0] . "\" Product name
// in <a href='http://bugs.eclipse.org/'>bugzilla</a>;
// use <a href='http://portal.eclipse.org/'>the portal</a>
// \"[maintain] project info meta-data\" to enter the correct
// bugzilla Component name(s) for $projectid";
// }
// }
// }
// /*
// * Step 3:
// * Query bugzilla to find all the iplog flagged attachments to closed bugs
// */
// $ors = array();
// foreach( $bugzillakeys as $each ) {
// $ands = array();
// if($each[2] != ""){
// $ands[] = "product_id = " . $each[2];
// if( isset($each[3]) ){
// $ands[] = "component_id = " . $each[3];
// }
// $ors[] = "(" . implode( " AND ", $ands ) . ")";
// }
// }
// if( count($ors) == 0 ){
// $ors[] = "FALSE";
// }
// $sql = "
// SELECT profiles.login_name,
// profiles.realname,
// bugs.bug_id,
// attachments.attach_id,
// attachments.description,
// UNIX_TIMESTAMP(attachments.creation_ts) AS created,
// LENGTH(attach_data.thedata) AS size,
// bugs.short_desc
// FROM attachments, attach_data, bugs, profiles, flags, flagtypes
// WHERE flagtypes.name = 'iplog'
// AND flags.status = '+'
// AND bug_status IN ( 'RESOLVED', 'VERIFIED', 'CLOSED' )
// AND resolution IN ( 'FIXED' )
// AND flagtypes.target_type = 'a'
// AND flags.bug_id = bugs.bug_id
// AND flags.attach_id = attachments.attach_id
// AND flagtypes.id = flags.type_id
// AND attachments.bug_id = bugs.bug_id
// AND attachments.attach_id = attach_data.id
// AND profiles.userid = attachments.submitter_id
// AND (" . implode( " OR ", $ors ) . ")
// ORDER BY bugs.bug_id
// ";
// if (isset($_GET['test'])) echo $sql;
// $result = $App->bugzilla_sql( $sql );
// $contributors = array();
// $contributors_excluded = array();
// while( $row = mysql_fetch_assoc($result) ) {
// $contributors[$row['login_name']]['realname'] = $row['realname'];
// $contributors[$row['login_name']]['login_name'] = $row['login_name'];
// $contributors[$row['login_name']]['bugs'][] = array(
// 'bug_id' => $row['bug_id'],
// 'type' => 'A',
// 'attach_id' => $row['attach_id'],
// 'size' => $row['size'],
// 'created' => $row['created'],
// 'bug_desc' => $row['short_desc'],
// 'attach_desc' => $row['description'] );
// }
// /*
// * Step 4:
// * Query bugzilla to find all the comments to iplog flagged closed bugs
// */
// $sql = "
// SELECT profiles.login_name,
// profiles.realname,
// bugs.bug_id,
// longdescs.comment_id,
// UNIX_TIMESTAMP(longdescs.bug_when) AS created,
// LENGTH(longdescs.thetext) AS size,
// bugs.short_desc
// FROM longdescs, bugs, profiles, flags, flagtypes
// WHERE flagtypes.name = 'iplog'
// AND flags.status = '+'
// AND bug_status IN ( 'RESOLVED', 'VERIFIED', 'CLOSED' )
// AND resolution IN ( 'FIXED' )
// AND flagtypes.target_type = 'b'
// AND flags.bug_id = bugs.bug_id
// AND flagtypes.id = flags.type_id
// AND longdescs.bug_id = bugs.bug_id
// AND profiles.userid = longdescs.who
// AND (" . implode( " OR ", $ors ) . ")
// ORDER BY bugs.bug_id, longdescs.comment_id
// ";
// $result = $App->bugzilla_sql( $sql );
// $lastbug = 0;
// $commentnumber = 0;
// while( $row = mysql_fetch_assoc($result) ) {
// if( $row['bug_id'] == $lastbug ) {
// $commentnumber += 1;
// } else {
// $commentnumber = 0;
// $lastbug = $row['bug_id'];
// }
// $contributors[$row['login_name']]['realname'] = $row['realname'];
// $contributors[$row['login_name']]['login_name'] = $row['login_name'];
// $contributors[$row['login_name']]['bugs'][] = array(
// 'bug_id' => $row['bug_id'],
// 'type' => 'C',
// 'attach_id' => $row['comment_id'],
// 'size' => $row['size'],
// 'created' => $row['created'],
// 'bug_desc' => $row['short_desc'],
// 'attach_desc' => 'comment #' . $commentnumber );
// }
// /*
// * Step 5:
// * Find Foundation database ids for contributors (if they have ids)
// */
// // WTB Bug 343596 - Need to escape email addresses before using them in query.
// $emails = array();
// foreach (array_keys( $contributors ) as $email) {
// $emails[] = mysql_real_escape_string($email);
// }
// $personids = array();
// $sql = "SELECT PersonID, Email FROM People
// WHERE Email IN ( '" . implode( "','", $emails ) . "' )
// ";
// $result = $App->foundation_sql( $sql );
// while( $row = mysql_fetch_array($result) ) {
// $contributors[$row[1]]['personid'] = $row[0];
// $personids[$row[0]] = 1;
// }
// $sql = "SELECT PersonID, Email FROM PeopleEmails
// WHERE Email IN ( '" . implode( "','", $emails ) . "' )
// ";
// $result = $App->foundation_sql( $sql );
// while( $row = mysql_fetch_array($result) ) {
// $contributors[$row[1]]['personid'] = $row[0];
// $personids[$row[0]] = 1;
// }
// /*
// * Step 6:
// * Find out when each of the PersonIDs is/was a committer (if they ever were)
// */
// $sql = "
// SELECT PersonID, UNIX_TIMESTAMP(ActiveDate) AS start, UNIX_TIMESTAMP(InactiveDate) AS end FROM PeopleProjects
// WHERE Relation = 'CM'
// AND ProjectID IN ( '" . implode( "','", $projectids ) . "' )
// AND PersonID IN ( '" . implode( "','", array_keys($personids) ) . "' )
// ";
// $result = $App->foundation_sql( $sql );
// $activedates = array();
// while( $row = mysql_fetch_assoc($result) ) {
// $activedates[$row['PersonID']][] = $row;
// }
// /*
// * Step 7:
// * Filter out the attachments that were contributed by a committer
// */
// foreach( $contributors as $key => $rec ) {
// if( isset($rec['personid']) ) {
// $filtered = array();
// foreach( $rec['bugs'] as $bug ) {
// $found = false;
// foreach( $activedates[$rec['personid']] as $each ) {
// if( $bug['created'] >= $each['start']
// && ($each['end'] == null
// || $bug['created'] <= $each['end']) ) {
// $found = true;
// break;
// }
// }
// if( !$found ) {
// $filtered[] = $bug;
// }
// }
// $contributors[$key]['bugs'] = $filtered;
// }
// }
// /*
// * Step 8:
// * Get the corrections ItemType = CONTRIB, Action = ?
// */
// $sql = "
// SELECT * FROM IPLogCorrections
// WHERE ProjectID IN ( '" . implode( "','", $projectids ) . "' )
// AND ItemType = 'CONTRIB'
// ";
// $result = $App->foundation_sql( $sql );
// $contributor_corrections = array();
// while( $row = mysql_fetch_assoc( $result ) ) {
// $contributor_corrections[$row['Action']][$row['ItemID']] = $row;
// }
// /*
// * Step 9:
// * Move the corrected/removed contributions to the excluded array
// */
// $contributors2 = array();
// foreach( $contributors as $loginname => $rec ) {
// $rec2 = array();
// $rec2['realname'] = $rec['realname'];
// $rec2['login_name'] = $rec['login_name'];
// $rec2['bugs'] = array();
// $rec2x = array();
// $rec2x['realname'] = $rec['realname'];
// $rec2x['login_name'] = $rec['login_name'];
// $rec2x['bugs'] = array();
// foreach( $rec['bugs'] as $bug ) {
// $bug2 = array();
// $bug2['bug_id'] = $bug['bug_id'];
// $bug2['attach_id'] = $bug['attach_id'];
// $bug2['size'] = $bug['size'];
// $bug2['bug_desc'] = $bug['bug_desc'];
// $bug2['attach_desc'] = $bug['attach_desc'];
// $bug2['type'] = $bug['type'];
// if( isset($contributor_corrections['RM' . $bug['type']][$bug['attach_id']]) ) {
// $rec2x['bugs'][] = $bug2;
// } else {
// $rec2['bugs'][] = $bug2;
// }
// }
// if( count($rec2x['bugs']) > 0 ) {
// $contributors_excluded[$rec2x['login_name']] = $rec2x;
// }
// $contributors2[$rec2['login_name']] = $rec2;
// }
// $contributors = $contributors2;
// /*
// * Step 9:
// * Clean out the empty records
// */
// $x = array();
// foreach( $contributors as $key => $value ) {
// if( count($value['bugs']) > 0 )
// $x[$key] = $value;
// }
// $contributors = $x;
// /*
// * Step 8:
// * Sort the results
// */
// uasort( $contributors, 'cmpcontributors' );
// uasort( $contributors_excluded, 'cmpcontributors' );
return array(
$errors,
$activecqs,
$unusedcqs,
$pendingcqs,
$prereqcqs,
$committers_at_least_once,
$committers_never,
$committers_excluded,
// $contributors,
// $contributors_excluded
);
}
function cmpcontributors( $a, $b ) {
$ar = $a['realname'];
$br = $b['realname'];
if( $ar && $br ) {
preg_match( "/(\w+)\s*$/", $ar, $ma );
preg_match( "/(\w+)\s*$/", $br, $mb );
if( $ma[1] < $mb[1] ) return -1;
if( $ma[1] > $mb[1] ) return 1;
}
if( $a['login_name'] < $b['login_name'] ) return -1;
if( $a['login_name'] > $b['login_name'] ) return 1;
return 0;
}
function sortcms( $a, $b ) {
if( $a['LName'] > $b['LName'] ) return 1;
if( $a['LName'] < $b['LName'] ) return -1;
if( $a['FName'] > $b['FName'] ) return 1;
if( $a['FName'] < $b['FName'] ) return -1;
return 0;
}
function pretty_size($bytes)
{
$sufs= array (
"B",
"K",
"M",
"G",
"T",
"P"
); //we shouldn't be larger than 999.9 petabytes any time soon, hopefully
$suf= 0;
while ($bytes >= 1000)
{
$bytes /= 1024;
$suf++;
}
$rtrn = sprintf("%3.1f%s", $bytes, $sufs[$suf]);
if( substr( $rtrn, -3 ) == ".0B" ) $rtrn = substr( $rtrn, 0, -3 );
return $rtrn;
}
function check_if_show_edit_form( $projectids, $Session, $Friend, $only_one_project, &$show_edit_form, &$reason_no_edit_form, &$logged_in_email_address ) {
global $App;
$reason_no_edit_form = '';
$show_edit_form = 0;
if( count($projectids) > 1 && $only_one_project ) {
$reason_no_edit_form = 'To modify an ip log you must <a href="ip_log_selector.php?projectid='
. implode( ',', $projectids ) . '">select a single project</a>.';
if( $Session->getBugzillaID() == 0 ) {
$reason_no_edit_form .= ' and be <a href="http://dev.eclipse.org/site_login/">logged in</a> as a committer on that project.';
}
} else {
if( $Session->getBugzillaID() == 0 ) {
$reason_no_edit_form = 'To modify an ip log you must be <a href="http://dev.eclipse.org/site_login/">logged in</a> as a committer.';
} else {
$bugzilla_userid = $Session->getBugzillaID();
$sql = "select login_name from profiles where userid = " . $bugzilla_userid;
$result = $App->bugzilla_sql( $sql );
$row = mysql_fetch_array( $result );
if( $row ) {
$logged_in_email_address = $row[0];
$sql = "select People.PersonID from People, PeopleProjects
where People.PersonID = PeopleProjects.PersonID
and EMail = '" . $row[0] . "'
and ProjectID IN ('" . implode('\',\'',$projectids) . "')
and Relation IN ( 'CM', 'PL', 'PM', 'PD' )
";
if (isset($_GET['test'])) echo $sql;
$result = $App->foundation_sql( $sql );
$row = mysql_fetch_array( $result );
if( $row ) {
$show_edit_form = $row[0];
} else {
$reason_no_edit_form = 'To modify an ip log you must be <a href="http://dev.eclipse.org/site_login/">logged in</a> as a committer on the project.';
}
} else {
$reason_no_edit_form = 'Internal error 1: no login_name for userid (' . $bugzilla_userid . ')';
}
}
}
}
/*
* drop any CQs that are under the EPL and without keyword nonepl
* drop any CQs with the keyword EPL
*/
function remove_EPL_CQs($cqs){
foreach($cqs as $bug_id => $bug){
if( (preg_match('/Eclipse Public License|EPL/i',$bug['cf_license']) and $bug["keyword_thirdparty"] == 0) or $bug["keyword_projectcode"] == 1 ){
unset($cqs[$bug_id]);
}
}
return $cqs;
}
/**
* This function returns a simple array containing the descriptive text
* for all of the licenses included in the projects ("Eclipse Public License, 1.0",
* for example). This information is harvested from the Foundation database.
*
* @param $projectids an array of string values: the ids of the projects of interest.
* @return an array containing the descriptive text of the licenses.
*/
function gather_project_licenses(&$projectids) {
global $App;
$sql = "SELECT distinct l.Description as License FROM ProjectLicenses as p join (SYS_Licenses as l) on (p.LicenseId = l.LicenseId) where p.ProjectId IN ( '" . implode( "','", $projectids ) . "')";
$result = $App->foundation_sql( $sql );
mysql_error_check();
$licenses = array();
while( $row = mysql_fetch_assoc($result) ) {
$license = $row['License'];
if (in_array($license, $licenses)) continue;
$licenses[] = $license;
}
return $licenses;
}
?>