| <?php |
| require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/common/shared_functions.php"); |
| require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/classes/projects/projectInfoData.class.php"); |
| require_once("/home/data/httpd/eclipse-php-classes/system/dbconnection_bugs_ro.class.php"); |
| $dbc_bugs = new DBConnectionBugs(); |
| $dbh_bugs = $dbc_bugs->connect(); |
| function bugzilla_sql( $sql ) { |
| global $dbh_bugs; |
| return mysql_query( $sql, $dbh_bugs ); |
| } |
| require_once("/home/data/httpd/eclipse-php-classes/system/dbconnection_ipzilla_ro.class.php"); |
| $dbc_ipz = new DBConnectionIPZillaRO(); |
| $dbh_ipz = $dbc_ipz->connect(); |
| function ipzilla_sql( $sql ) { |
| global $dbh_ipz; |
| return mysql_query( $sql, $dbh_ipz ); |
| } |
| require_once("/home/data/httpd/eclipse-php-classes/system/dbconnection.class.php"); |
| $dbc_e = new DBConnection(); |
| $dbh_e = $dbc_e->connect(); |
| function eclipse_sql( $sql ) { |
| global $dbh_e; |
| return mysql_query( $sql, $dbh_e ); |
| } |
| require_once("/home/data/httpd/eclipse-php-classes/system/testing.class.php"); |
| $dbc_f = new DBConnectionRWtest(); |
| $dbh_f = $dbc_f->connect(); |
| function foundation_sql( $sql ) { |
| global $dbh_f; |
| return mysql_query( $sql, $dbh_f ); |
| } |
| require_once("/home/data/httpd/eclipse-php-classes/system/dbconnection_portal_rw.class.php"); |
| $dbc_p = new DBConnectionPortalRW(); |
| $dbh_p = $dbc_p->connect(); |
| function portal_sql( $sql ) { |
| global $dbh_p; |
| return mysql_query( $sql, $dbh_p ); |
| } |
| |
| /*------------------------------------------------------------------------------ |
| 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 ) { |
| $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 = ipzilla_sql( $sql ); |
| if( ($row = mysql_fetch_array($result)) ) { |
| $componentids[] = $row[0]; |
| } else { |
| $errors[] = "Error: $projectid does not exist in ipzilla; contact the EMO."; |
| } |
| } |
| /* |
| * Step 2: |
| * Get all the CQs for the projects |
| */ |
| $sql = "SELECT * FROM bugs |
| WHERE component_id IN ( " . implode( ',', $componentids ) . ") |
| "; |
| $result = ipzilla_sql( $sql ); |
| $activecqs = array(); |
| $unusedcqs = array(); |
| $pendingcqs = array(); |
| $prereqcqs = array(); |
| $bugids = array(); |
| $keywords = array( 'modified', 'unmodified', 'source', 'binary', 'sourceandbinary', |
| 'obsolete', 'unused', 'withdrawn', 'nonepl' ); |
| 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 |
| */ |
| $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' ) |
| AND bug_id IN ( " . implode( ",", $bugids ) . " ) |
| "; |
| $result = 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; |
| } |
| /* |
| * 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 |
| 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) |
| ) |
| "; |
| $result = 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 |
| $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 = 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]) ) { |
| $committers_at_least_once[$key] = $row; |
| } else { |
| if( isset($cm_counts[$key]) ) { |
| $committers_at_least_once[$key] = $row; |
| } else { |
| $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' => '???', |
| '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' => '???', |
| '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'] ); |
| } |
| } |
| /* |
| * Step 5: |
| * Sort the lists |
| */ |
| uasort( $committers_at_least_once, 'sortcms' ); |
| uasort( $committers_never, 'sortcms' ); |
| uasort( $committers_excluded, 'sortcms' ); |
| |
| /*================================================= |
| * 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 = 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 = 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(); |
| $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 |
| "; |
| $result = 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 = 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) |
| */ |
| $emails = array_keys( $contributors ); |
| $personids = array(); |
| $sql = "SELECT PersonID, Email FROM People |
| WHERE Email IN ( '" . implode( "','", $emails ) . "' ) |
| "; |
| $result = 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 = 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 = 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 = 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 ) { |
| $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 = 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' ) |
| "; |
| $result = 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 . ')'; |
| } |
| } |
| } |
| } |
| ?> |
| |