blob: f0a3df79bb8ca81253784a279f218e3b5ae13846 [file] [log] [blame]
<?php
/*******************************************************************************
* Copyright (c) 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:
* Wayne Beaton (Eclipse Foundation)- initial API and implementation
*******************************************************************************/
require_once(dirname(__FILE__) . "/common.php");
require_once(dirname(__FILE__) . "/debug.php");
trace_file_info(__FILE__);
function getLoggedInCommitter() {
global $_loggedInCommitter;
if (isset($_loggedInCommitter)) return $_loggedInCommitter;
$_loggedInCommitter = null;
global $App;
$Session = $App->useSession("optional");
$friend = $Session->getFriend();
if (!$friend->getBugzillaID()) return null;
if (!$friend->getIsCommitter()) return null;
$committer = new Committer();
$email = $friend->getEmail();
$sql = "select
p.PersonID,
p.LName,
p.FName,
p.Email,
p.Comments,
pp.ProjectID,
pp.Relation,
pp.ActiveDate,
pp.InactiveDate
from People as p
left join PeopleProjects as pp on (p.PersonID = pp.PersonID)
where EMail = '$email'";
$result = $App->foundation_sql($sql);
while ($row = mysql_fetch_assoc($result)) {
$committer->id = $row['PersonID'];
if (!isset($row['ProjectID'])) continue;
$committer->projectRelations[] = new ProjectRelation($row);
}
$_loggedInCommitter = $committer;
return $committer;
}
function getCommittersForProject($id, $preloadCommits = true) {
mustBeValidProjectId($id);
trace("Loading committers for $id");
$sql = "
select distinct
p.PersonID,
p.FName,
p.LName,
p.Email,
p.Comments,
pp.ProjectID,
pp.Relation,
pp.ActiveDate,
pp.InactiveDate,
o.OrganizationID as CompanyId,
o.Name1 as Company
from People as p
join PeopleProjects as pp on (p.PersonID = pp.PersonID)
left join OrganizationContacts as oc on (p.PersonId = oc.PersonId)
left join Organizations as o on (oc.OrganizationId = o.OrganizationId)
where
pp.ProjectID = '$id'";
$committers = _loadCommitters($sql);
return $committers;
}
function getCommitters() {
$sql = "
select distinct
p.PersonID,
p.FName,
p.LName,
p.Email,
p.Comments,
pp.ProjectID,
pp.Relation,
pp.ActiveDate,
pp.InactiveDate,
o.OrganizationID as CompanyId,
o.Name1 as Company
from People as p
join PeopleProjects as pp on (p.PersonID = pp.PersonID)
left join OrganizationContacts as oc on (p.PersonId = oc.PersonId)
left join Organizations as o on (oc.OrganizationId = o.OrganizationId)";
return _loadCommitters($sql);
}
/**
* Answer an array mapping committer Id to full name (first + last) for
* each of the provided committer Ids.
*/
function getCommitterNames($ids) {
global $App;
$committers = array();
$values = implode("','", $ids);
$result = $App->foundation_sql("select distinct PersonId, concat(FName, ' ', LName) as Name from People where PersonId in ('$values')");
while ($row = mysql_fetch_assoc($result)) {
$id = $row['PersonId'];
$name = $row['Name'];
$committers[$id] = $name;
}
return $committers;
}
/**
* Current implementation does not guarantee uniqueness. i.e. if you
* call this function more than once, subsequent calls will return
* different objects.
*/
/* private */ function _loadCommitters($sql) {
global $App;
$committers = array();
$result = $App->foundation_sql($sql);
while ($row = mysql_fetch_assoc($result)) {
$id = $row['PersonID'];
if (!isset($committers[$id])) {
$committer = new Committer();
$committer->id = $id;
$committer->firstName = $row['FName'];
$committer->lastName = $row['LName'];
$committer->email = $row['Email'];
$committer->companyId = $row['CompanyId'];
$committer->company = $row['Company'];
$committer->comments = $row['Comments'];
$committers[$id] = $committer;
} else {
$committer = $committers[$id];
}
$committer->projectRelations[] = new ProjectRelation($row);
}
return $committers;
}
class Committer {
/**
* Committer ID from the Foundation Database.
* @var string
*/
var $id;
/**
* First name. Duh.
* @var string
*/
var $firstName;
/**
* Last name. Duh.
* @var string
*/
var $lastName;
var $email;
var $companyId;
var $company;
/**
* Array of project relations.
* @var ProjectRelation[]
*/
var $projectRelations = array();
var $commits = array();
var $comments;
function getName() {
return "$this->firstName $this->lastName";
}
function isCommitter($id, $when='now') {
return $this->hasProjectRelation($id, 'CM', $when);
}
function isMentor($id, $when='now') {
return $this->hasProjectRelation($id, 'ME', $when);
}
function isEmeritus($id, $when='now') {
return $this->hasProjectRelation($id, 'CE', $when);
}
function isProjectLead($id, $when='now') {
return $this->hasProjectRelation($id, 'PL', $when);
}
function isPmcMember($id, $when='now') {
return $this->hasProjectRelation($id, 'PM', $when);
}
function isPmcLead($id, $when='now') {
return $this->hasProjectRelation($id, 'PD', $when);
}
function hasCommits($id, $when='now') {
return $this->getCommitSummary($id) ? true : false;
}
/**
* Get the commit summary for this user for a particular
* project from the commits index database.
*
* @param string $id a project id, e.g. 'rt.gyrex'
*/
function getCommitSummary($projectId) {
mustBeValidProjectId($projectId);
if (isset($this->_commitSummary[$projectId])) return $this->_commitSummary[$projectId];
global $App;
$result = $App->dashboard_sql("select count, period from commits_index where login='$this->id' and project ='$projectId' order by count desc;");
$this->_commitSummary[$projectId] = array();
while($row = mysql_fetch_assoc($result)) {
$this->_commitSummary[$projectId][$row['period']] = $row['count'];
}
return $this->_commitSummary[$projectId];
}
function isActive($id, $when='now') {
if (!$summary = $this->getCommitSummary($id)) return false;
return isset($summary['3']);
}
/**
* This method answers true if the committer represented by the instance
* has the right credentials to submit an IP Log for all of the projects
* specified in the parameter.
*
* Note that this method is a little specialized, but it is useful in a couple
* of different contexts, so having it here sort of makes sense.
*
* @param string[] $ids An array of project ids.
*/
function canSubmitIPLogForAllProjects($ids, $when='now') {
if ($this->isCommitterOnAllProjects($ids, $when)) return true;
if ($this->isPMCRepresentativeForAllProjects($ids, $when)) return true;
return false;
}
function isPMCRepresentativeForAllProjects($ids, $when='now') {
foreach($ids as $id) {
if (!$this->isPMCRepresentativeForProject($id, $when)) return false;
}
return true;
}
function isPMCRepresentativeForProject($id, $when='now') {
require_once dirname(__FILE__) . '/Project.class.php';
$top = getProject($id)->getTopLevelProject()->getId();
foreach($this->projectRelations as $relation) {
if (!$relation->isActive($when)) continue;
if ($top != $relation->projectId) continue;
if ($relation->relation == 'PD') return true; // PMC Lead
if ($relation->relation == 'PM') return true; // PMC Member
}
return false;
}
/**
* Answers true if the receiver is a committer on all of the projects
* in the provided list, or false otherwise.
*
* Enter description here ...
* @param string[] $ids Array of project ids.
* @param string $date Optional date to check in string format. Default: current date
* @return bool
*/
function isCommitterOnAllProjects($ids, $when) {
foreach($ids as $id) {
if (!$this->isCommitterOnProject($id, $when)) return false;
}
return true;
}
function isCommitterOnProject($id, $when = 'now') {
return $this->hasProjectRelation($id, 'CM', $when);
}
/* private */ function hasProjectRelation($id, $relationCode, $when = 'now') {
foreach($this->projectRelations as $relation) {
if (!$relation->isActive($when)) continue;
if ($id != $relation->projectId) continue;
if ($relation->relation == $relationCode) return true;
}
return false;
}
/**
* This function extract the email addresses from the comment and returns
* them--along with the provided primary email address--in an array.
*
* This is a stop-gap solution for the need to represent multiple email addresses
* for some users in some contexts. Alternative email addresses are represented in
* the comment field in the form 'alt-email:somebody@someplace.com'. Multiple
* alternative addresses can be provided. The tag can occur anywhere in the comment
* and--while it is not always required--it is good practice to leave a space
* between multiple entries.
*
* WTB Bug 355885
*/
function getAltEmails() {
preg_match_all('/alt-email:([A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4})/i', $this->comments, $matches);
$emails = array();
foreach($matches[1] as $email) {
$emails[] = $email;
}
return $emails;
}
function hasEmailAddress($address) {
if (strcasecmp($this->email, $address) == 0) return true;
foreach($this->getAltEmails() as $email) {
if (strcasecmp($email, $address) == 0) return true;
}
return false;
}
function getOrganization() {
if (!$this->companyId) return null;
require_once(dirname(__FILE__)) . '/Organization.class.php';
return getOrganization($this->companyId);
}
function getAllAddresses() {
global $App;
$sql = "select
AddressId,
Address1, Address2, Address3,
City, ProvStateRegion,PostalCode, CCode
from PeopleAddresses
where PersonID='$this->id'
order by AddressId";
$addresses = array();
$result = $App->foundation_sql($sql);
while ($row = mysql_fetch_assoc($result)) {
$addresses[] = $row;
}
return $addresses;
}
}
class ProjectRelation {
var $projectId;
var $relation;
var $activeDate;
var $inactiveDate;
function __construct($row) {
$this->projectId = $row['ProjectID'];
$this->relation = $row['Relation'];
$this->activeDate = $row['ActiveDate'] ? strtotime($row['ActiveDate']) : null;
$this->inactiveDate = $row['InactiveDate'] ? strtotime($row['InactiveDate']) : null;
}
function isActive($when = 'now') {
if (!$this->activeDate) return false;
$date = strtotime($when);
if ($date < $this->activeDate) return false;
if (!$this->inactiveDate) return true;
if ($date > $this->inactiveDate) return false;
return true;
}
}
?>