* Copyright 1999-2000, Tim Perdue/Sourceforge
* Copyright 2002, Tim Perdue/GForge, LLC
* Copyright 2009, Roland Mas
+ * Copyright 2010, Alain Peyrat - Alcatel-Lucent
+ * Copyright 2011, Thorsten Glaser <t.glaser@tarent.de>
*
- * This file is part of FusionForge.
+ * This file is part of FusionForge. FusionForge is free software;
+ * you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the Licence, or (at your option)
+ * any later version.
*
- * FusionForge is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License,
- * or (at your option) any later version.
- *
- * FusionForge is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
+ * FusionForge is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with FusionForge; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * You should have received a copy of the GNU General Public License along
+ * with FusionForge; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
require_once $gfcommon.'include/Error.class.php';
require_once $gfcommon.'include/Validator.class.php';
-function &projecttask_get_object($project_task_id,$data=false) {
+function projecttask_get_object($project_task_id,$data=false) {
global $PROJECTTASK_OBJ;
if (!isset($PROJECTTASK_OBJ["_".$project_task_id."_"])) {
if ($data) {
function ProjectTask(&$ProjectGroup, $project_task_id=false, $arr=false) {
$this->Error();
if (!$ProjectGroup || !is_object($ProjectGroup)) {
- $this->setError('ProjectTask:: No Valid ProjectGroup Object');
+ $this->setError('No Valid ProjectGroup Object');
return false;
}
if ($ProjectGroup->isError()) {
- $this->setError('ProjectTask:: '.$ProjectGroup->getErrorMessage());
+ $this->setError($ProjectGroup->getErrorMessage());
return false;
}
$this->ProjectGroup =& $ProjectGroup;
* @param array An array of project_task_id's that this task depends on.
* @param int The duration of the task in days.
* @param int The id of the parent task, if any.
+ * @param array An array ('user' => user_id)
* @return boolean success.
*/
function create($summary,$details,$priority,$hours,$start_date,$end_date,
- $category_id,$percent_complete,&$assigned_arr,&$depend_arr,$duration=0,$parent_id=0) {
+ $category_id,$percent_complete,&$assigned_arr,&$depend_arr,$duration=0,$parent_id=0, $importData = array()) {
$v = new Validator();
- $v->check($summary, "summary");
- $v->check($details, "details");
- $v->check($priority, "priority");
- $v->check($hours, "hours");
- $v->check($start_date, "start date");
- $v->check($end_date, "end date");
- $v->check($category_id, "category");
+ $v->check($summary, _("summary"));
+ $v->check($details, _("details"));
+ $v->check($priority, _("priority"));
+ $v->check($hours, _("hours"));
+ $v->check($start_date, _("start date"));
+ $v->check($end_date, _("end date"));
+ $v->check($category_id, _("category"));
if (!$v->isClean()) {
- $this->setError($v->formErrorMsg("Must include "));
+ $this->setError($v->formErrorMsg(_("Must include ")));
return false;
}
if (!$parent_id) {
return false;
}
+ if(array_key_exists('user', $importData)){
+ $uid = $importData['user'];
+ } else {
+ $uid = user_getid();
+ }
+
db_begin();
- $res = db_query_params ('SELECT nextval($1) AS id',
+ $res = db_query_params ('SELECT nextval($1) AS id',
array ('project_task_pk_seq'));
if (!$project_task_id=db_result($res,0,'id')) {
$this->setError( 'Could Not Get Next Project Task ID' );
db_rollback();
return false;
}
-
+
$this->data_array['project_task_id']=$project_task_id;
-
+
$result = db_query_params ('INSERT INTO project_task (project_task_id,group_project_id,created_by,summary,details,start_date,end_date,status_id,category_id,priority,percent_complete,hours,duration,parent_id) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)',
array ($project_task_id,
$this->ProjectGroup->getID(),
- user_getid(),
+ $uid,
htmlspecialchars($summary),
htmlspecialchars($details),
$start_date,
$hours,
$duration,
$parent_id)) ;
-
+
if (!$result || db_affected_rows($result) < 1) {
- $this->setError('ProjectTask::create() Posting Failed '.db_error());
+ $this->setError('Posting Failed '.db_error());
db_rollback();
return false;
}
db_rollback();
return false;
}
- $this->sendNotice(1);
+ $this->sendNotice(1);
db_commit();
return true;
- }
+ }
/**
* fetchData - re-fetch the data for this ProjectTask from the database.
array ($project_task_id,
$this->ProjectGroup->getID())) ;
if (!$res || db_numrows($res) < 1) {
- $this->setError('ProjectTask::fetchData() Invalid Task ID'.db_error());
+ $this->setError('Invalid Task ID'.db_error());
return false;
}
$this->data_array = db_fetch_array($res);
function getSubmittedRealName() {
return $this->data_array['realname'];
}
-
+
/**
* getDuration - the duration of the task.
*
function getDuration() {
return $this->data_array['duration'];
}
-
+
/**
* getParentID - the task_id of the parent task, if any.
*
function getParentID() {
return $this->data_array['parent_id'];
}
-
+
/**
* getSubmittedUnixName - get the unix name of the person who created this task.
*
function getLastModifiedDate() {
return $this->data_array['last_modified_date'];
}
-
+
/**
- * setExternalID - set a row in project_task_external_order which stores
+ * setExternalID - set a row in project_task_external_order which stores
* an id, for example an ID generated by MS Project, which needs to be restored later
*/
function setExternalID($id) {
array ($id,
$this->getID())) ;
if (db_affected_rows($res) < 1) {
- $res = db_query_params ('INSERT INTO project_task_external_order (project_task_id,external_id) VALUES ($1, $2)',
+ $res = db_query_params ('INSERT INTO project_task_external_order (project_task_id,external_id) VALUES ($1, $2)',
array ($this->getID(),
$id)) ;
}
function getRelatedArtifacts() {
if (!$this->relatedartifacts) {
$this->relatedartifacts=
- db_query_params ('SELECT agl.group_id,agl.name,agl.group_artifact_id,a.artifact_id,a.open_date,a.summary
- FROM artifact_group_list agl, artifact a
+ db_query_params ('SELECT agl.group_id,agl.name,agl.group_artifact_id,a.artifact_id,a.open_date,a.summary,ast.status_name
+ FROM artifact_group_list agl, artifact a, artifact_status ast
WHERE a.group_artifact_id=agl.group_artifact_id
- AND EXISTS (SELECT artifact_id FROM project_task_artifact
+ AND ast.id=a.status_id
+ AND EXISTS (SELECT artifact_id FROM project_task_artifact
WHERE artifact_id=a.artifact_id
AND project_task_id=$1)',
array ($this->getID())) ;
if ($art_array[$i] < 1) {
continue;
}
- $res = db_query_params ('INSERT INTO project_task_artifact (project_task_id,artifact_id) VALUES ($1,$2)',
+ $res = db_query_params ('INSERT INTO project_task_artifact (project_task_id,artifact_id) VALUES ($1,$2)',
array ($this->getID(),
$art_array[$i])) ;
if (!$res) {
*/
function delete($sure) {
if (!$sure) {
- $this->setMissingParamsError();
+ $this->setMissingParamsError(_('Please tick all checkboxes.'));
return false;
}
if (!forge_check_perm ('pm', $this->ProjectGroup->getID(), 'manager')) {
// May not yet have an ID, if we are creating a NEW task
//
if ($this->getID()) {
- return db_query_params ('SELECT project_task_id,summary
- FROM project_task
+ return db_query_params ('SELECT project_task_id,summary
+ FROM project_task
WHERE group_project_id=$1
AND project_task_id <> $2
ORDER BY project_task_id DESC',
array ($this->ProjectGroup->getID(),
$this->getID())) ;
} else {
- return db_query_params ('SELECT project_task_id,summary
- FROM project_task
+ return db_query_params ('SELECT project_task_id,summary
+ FROM project_task
WHERE group_project_id=$1
ORDER BY project_task_id DESC',
array ($this->ProjectGroup->getID())) ;
* @return database result set.
*/
function getHistory() {
- return db_query_params ('SELECT *
- FROM project_history_user_vw
+ return db_query_params ('SELECT *
+ FROM project_history_user_vw
WHERE project_task_id=$1
ORDER BY mod_date DESC',
array ($this->getID())) ;
*
* @return database result set.
*/
- function getMessages() {
- return db_query_params ('SELECT *
- FROM project_message_user_vw
+ function getMessages($asc=false) {
+ return db_query_params ('SELECT *
+ FROM project_message_user_vw
WHERE project_task_id=$1
- ORDER BY postdate DESC',
+ ORDER BY postdate ' . ($asc ? 'ASC' : 'DESC'),
array ($this->getID())) ;
}
/**
* addMessage - Handle the addition of a followup message to this task.
*
- * @param string The message.
+ * @param string The message.
+ * @param array Specific data for import (user id and time)
* @returns boolean success.
*/
- function addMessage($message) {
+ function addMessage($message, $importData = array()) {
//prevent posting the same message
if ($this->getDetails() == htmlspecialchars($message)) {
return true;
}
- $res = db_query_params ('SELECT * FROM project_messages
+ $res = db_query_params ('SELECT * FROM project_messages
WHERE project_task_id=$1
AND body=$2',
array ($this->getID(),
htmlspecialchars($message))) ;
if (!$res || db_numrows($res) < 1) {
+ //Uses importData
+ if(array_key_exists('user', $importData)){
+ $uid = $importData['user'];
+ } else {
+ $uid = user_getid();
+ }
+ if(array_key_exists('time', $importData)){
+ $time = $importData['time'];
+ } else {
+ $time = time();
+ }
$res = db_query_params ('INSERT INTO project_messages (project_task_id,body,posted_by,postdate) VALUES ($1,$2,$3,$4)',
array ($this->getID(),
htmlspecialchars($message),
- user_getid(),
- time())) ;
+ $uid,
+ $time)) ;
if (!$res || db_affected_rows($res) < 1) {
- $this->setError('AddMessage():: '.db_error());
+ $this->setError(db_error());
return false;
} else {
return true;
*
* @param string The field name.
* @param string The old value.
+ * @param array Specific data for import (user id and time)
* @returns boolean success.
*/
- function addHistory ($field_name,$old_value) {
+ function addHistory ($field_name,$old_value,$importData=array()) {
+ //Uses importData
+ if(array_key_exists('user', $importData)){
+ $uid = $importData['user'];
+ } else {
+ $uid = user_getid();
+ }
+ if(array_key_exists('time', $importData)){
+ $time = $importData['time'];
+ } else {
+ $time = time();
+ }
$result = db_query_params ('INSERT INTO project_history (project_task_id,field_name,old_value,mod_by,mod_date) VALUES ($1,$2,$3,$4,$5)',
array ($this->getID(),
$field_name,
$old_value,
- user_getid(),
- time())) ;
+ $uid,
+ $time)) ;
if (!$result) {
$this->setError('ERROR IN AUDIT TRAIL - '.db_error());
return false;
return false;
}
- $res = db_query_params ('SELECT is_dependent_on_task_id AS id
- FROM project_dependencies
+ $res = db_query_params ('SELECT is_dependent_on_task_id AS id
+ FROM project_dependencies
WHERE project_task_id=$1',
array ($depend_on_id)) ;
$rows=db_numrows($res);
function setDependentOn(&$arr_) {
//printr($arr_,'setDependentOn entry');
//
-// IMPORTANT - MUST VERIFY NO CIRCULAR DEPENDENCY!!
+// IMPORTANT - MUST VERIFY NO CIRCULAR DEPENDENCY!!
//
if (!$arr_ || empty($arr_)) {
$arr_=array('100'=>PM_LINK_DEFAULT);
$del_arr = array_values (array_diff ($arr2, $arr));
//echo "del arr: ".print_r($del_arr);
for ($i=0; $i<count($del_arr); $i++) {
- db_query_params ('DELETE FROM project_dependencies
+ db_query_params ('DELETE FROM project_dependencies
WHERE project_task_id=$1
AND is_dependent_on_task_id=$2',
array ($this->getID(),
$del_arr[$i])) ;
if (db_error()) {
- $this->setError('setDependentOn()-1:: '.db_error());
+ $this->setError(db_error());
return false;
}
}
$add_arr[$i],
$lnk)) ;
if (db_error()) {
- $this->setError('setDependentOn()-2:: '.db_error().$sql);
+ $this->setError(db_error());
return false;
}
}
}
/**
- * convertDependentOn - converts a regular array of dependencies, such
- * as from a multiple-select-box to an associative array with default
+ * convertDependentOn - converts a regular array of dependencies, such
+ * as from a multiple-select-box to an associative array with default
* link types. Should be called from web code as part of the create/update calls.
* Here we are converting an array like array(1,5,9,77) to array(1=>SS,5=>SF,9=>FS,77=>SS)
*/
} else {
//else create with default link type
$new[$arr[$i]]=PM_LINK_DEFAULT;
- }
+ }
}
return $new;
}
/**
* getDependentOn - get an array of project_task_id's that you are dependent on.
*
- * @return array The array of project_task_id's in this format:
+ * @return array The array of project_task_id's in this format:
* array($id=>$link_type,id2=>link_type2).
*/
function getDependentOn() {
array ($this->getID(),
$del_arr[$i])) ;
if (db_error()) {
- $this->setError('setAssignedTo()-1:: '.db_error());
+ $this->setError(db_error());
return false;
}
}
array ($this->getID(),
$add_arr[$i])) ;
if (db_error()) {
- $this->setError('setAssignedTo()-2:: '.db_error());
+ $this->setError(db_error());
return false;
}
}
$status_id,$category_id,$percent_complete,&$assigned_arr,&$depend_arr,
$new_group_project_id,$duration=0,$parent_id=0) {
$has_changes = false; // if any of the values passed is different from
-
- $arrChangedAndInNotice = array("details"=>"","summary"=>"",
- "complete"=>"","status"=>"","subproject"=>""); /* includes only
- entries that changed and will be sended by E-Mail (sendNotice()) */
-
+
+ $arrChangedAndInNotice = array(
+ 'details'=>'',
+ 'summary'=>'',
+ 'assigned'=>'',
+ 'complete'=>'',
+ 'status'=>'',
+ 'subproject'=>''
+ );
+
$v = new Validator();
- $v->check($summary, "summary");
- $v->check($priority, "priority");
- $v->check($hours, "hours");
- $v->check($start_date, "start date");
- $v->check($end_date, "end date");
- $v->check($status_id, "status");
- $v->check($category_id, "category");
+ $v->check($summary, _("summary"));
+ $v->check($priority, _("priority"));
+ $v->check($hours, _("hours"));
+ $v->check($start_date, _("start date"));
+ $v->check($end_date, _("end date"));
+ $v->check($status_id, _("status"));
+ $v->check($category_id, _("category"));
if (!$v->isClean()) {
- $this->setError($v->formErrorMsg("Must include "));
+ $this->setError($v->formErrorMsg(_("Must include ")));
return false;
}
if (!$parent_id) {
($this->getStartDate() != $start_date) || ($this->getEndDate() != $end_date) ||
($this->getStatusID() != $status_id) || ($this->getCategoryID() != $category_id) ||
($this->getPercentComplete() != $percent_complete) ) {
-
+
$has_changes = true;
}*/
-
-
+
+
db_begin();
//
return false;
}
}
- if ($this->getStatusID() != $status_id) {
+ if ($this->getStatusID() != $status_id) {
$this->addHistory ('status_id',$this->getStatusID());
$has_changes = true;
$arrChangedAndInNotice['status'] = ">";
}
$old_assigned = $this->getAssignedTo();
- $diff_assigned_array=array_diff($old_assigned, $assigned_arr);
- if (count($diff_assigned_array)>0) {
- for ($tmp=0;$tmp<count($old_assigned);$tmp++) {
- $this->addHistory('assigned_to_id',$old_assigned[$tmp]);
+ if ($assigned_arr == '' || !$assigned_arr) {
+ $assigned_arr = array();
+ $assigned_arr[0] = 100;
+ }
+ $removed=array_diff($old_assigned, $assigned_arr);
+ $added=array_diff($assigned_arr, $old_assigned);
+ if (count($removed)>0 || count($added)>0) {
+ $assigned = array();
+ foreach ($old_assigned as $user_id) {
+ $assigned[] = user_get_object($user_id)->getRealName();
}
+ $this->addHistory('assigned_to', join(', ', $assigned));
+ $arrChangedAndInNotice['assigned'] = ">";
$has_changes = true;
}
- $old_array = array_keys($this->getDependentOn());
- $diff_array=array_diff($old_array,array_keys($depend_arr));
- if (count($diff_array)>0) {
- for ($tmp=0;$tmp<count($old_array);$tmp++) {
- $this->addHistory('dependent_on_id', $old_array[$tmp]);
- }
+
+ $old_array = array_keys($this->getDependentOn());
+ $removed=array_diff($old_array,array_keys($depend_arr));
+ $added=array_diff(array_keys($depend_arr), $old_array);
+ if (count($removed)>0 || count($added)>0) {
+ $this->addHistory('dependent_on', join(', ', $old_array));
$has_changes = true;
}
-
+
if (!$this->setDependentOn($depend_arr)) {
db_rollback();
return false;
$parent_id,
$group_project_id,
$this->getID())) ;
- if (!$res) {
- $this->setError('Error On ProjectTask::update-5: '.db_error().$sql);
+ if (!$res || db_affected_rows($res) < 1) {
+ $this->setError(db_error());
db_rollback();
return false;
} else {
if (!$this->fetchData($this->getID())) {
- $this->setError('Error On ProjectTask::update-6: '.db_error());
+ $this->setError(db_error());
db_rollback();
return false;
} else {
return true;
}
- $body = "Task #". $this->getID() ." has been updated. ".
- "\n\nProject: ". $this->ProjectGroup->Group->getPublicName();
+ if (session_loggedin()) {
+ $user = session_get_user()->getRealName();
+ } else {
+ $user = '';
+ }
+
+ $body = "Task #". $this->getID() ." has been updated by $user.".
+ "\n\nProject: ". $this->ProjectGroup->Group->getPublicName();
+
if (isset($arrChangedAndInNotice['subproject']))
$body .= "\n". $arrChangedAndInNotice['subproject']."Subproject: ". $this->ProjectGroup->getName();
if (isset($arrChangedAndInNotice['status']))
$body .= "\n". $arrChangedAndInNotice['status']. "Status: ". $this->getStatusName();
+ if (isset($arrChangedAndInNotice['assigned'])) {
+ $assigned = array();
+ foreach ($this->getAssignedTo() as $user_id) {
+ $assigned[] = user_get_object($user_id)->getRealName();
+ }
+ $body .= "\n". $arrChangedAndInNotice['assigned']. "Assigned: ". join(', ', $assigned);
+ }
+
$body .= "\n\nDescription: ". util_unconvert_htmlspecialchars( $this->getDetails() );
/*