| <?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; |
| } |
| ?> |
| |