[Fusionforge-commits] FusionForge branch master updated. 6.0.4-1115-gea54eb0

Franck Villaume nerville at libremir.placard.fr.eu.org
Fri Oct 28 11:30:17 CEST 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".

The branch, master has been updated
       via  ea54eb06250b8f716d6e9294ef9277f06091078f (commit)
       via  cc3496c417c4625a31d4ec1b39c3cf08d2227faa (commit)
      from  acb23524b2af53245ce07a8639f042133f72fe2c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=ea54eb06250b8f716d6e9294ef9277f06091078f

commit ea54eb06250b8f716d6e9294ef9277f06091078f
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Fri Oct 28 11:23:47 2016 +0200

    fix SQL syntax

diff --git a/src/db/20161025-tracker-internal-artifact-fields.sql b/src/db/20161025-tracker-internal-artifact-fields.sql
index 4143184..f7d8e59 100644
--- a/src/db/20161025-tracker-internal-artifact-fields.sql
+++ b/src/db/20161025-tracker-internal-artifact-fields.sql
@@ -5,7 +5,7 @@ ALTER TABLE artifact
    ADD COLUMN is_deleted integer NOT NULL DEFAULT 0,
    ADD CONSTRAINT artifact_last_modified_by_fk FOREIGN KEY (last_modified_by)
       REFERENCES users (user_id) MATCH FULL
-      ON UPDATE NO ACTION ON DELETE NO ACTION
+      ON UPDATE NO ACTION ON DELETE NO ACTION;
 
 CREATE OR REPLACE VIEW artifact_vw AS 
  SELECT

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=cc3496c417c4625a31d4ec1b39c3cf08d2227faa

commit cc3496c417c4625a31d4ec1b39c3cf08d2227faa
Author: Stéphane-Eymeric Bredthauer <sebredthauer at gmail.com>
Date:   Thu Oct 27 20:16:06 2016 +0200

    Tracker: internal artifact fields (lastModifiedBy, isDeleted)

diff --git a/src/common/tracker/Artifact.class.php b/src/common/tracker/Artifact.class.php
index 7dab996..6767754 100644
--- a/src/common/tracker/Artifact.class.php
+++ b/src/common/tracker/Artifact.class.php
@@ -494,6 +494,42 @@ class Artifact extends FFObject {
 		return $this->data_array['last_modified_date'];
 	}
 
+		/**
+	 * getLastModifiedBy - get ID of last modifier.
+	 *
+	 * @return	int	user_id of modifier.
+	 */
+	function getLastModifiedBy() {
+		return $this->data_array['last_modified_by'];
+	}
+
+	/**
+	 * getLastModifiedEmail - get email of modifier.
+	 *
+	 * @return	string	The email of modifier.
+	 */
+	function getLastModifiedEmail() {
+		return $this->data_array['last_modified_email'];
+	}
+
+	/**
+	 * getLastModifiedRealName - get real name of modifier.
+	 *
+	 * @return	string	The real name of modifier.
+	 */
+	function getLastModifiedRealName() {
+		return $this->data_array['last_modified_realname'];
+	}
+
+	/**
+	 * getLastModifiedUnixName - get login name of modifier.
+	 *
+	 * @return	string	The unix name of modifier.
+	 */
+	function getLastModifiedUnixName() {
+		return $this->data_array['last_modified_unixname'];
+	}
+
 	/**
 	 * getSummary - get text summary of artifact.
 	 *
@@ -513,7 +549,7 @@ class Artifact extends FFObject {
 	}
 
 	/**
-	 * delete - delete this tracker and all its related data.
+	 * delete - "delete" this artifact and all its related data, artifact is taged deleted
 	 *
 	 * @param	bool	$sure I'm Sure.
 	 * @return	bool	true/false;
@@ -528,88 +564,51 @@ class Artifact extends FFObject {
 			return false;
 		}
 		db_begin();
-		$res = db_query_params ('DELETE FROM artifact_extra_field_data WHERE artifact_id=$1',
-					array ($this->getID())) ;
-		if (!$res) {
-			$this->setError(_('Error deleting extra field data')._(': ').db_error());
-			db_rollback();
-			return false;
-		}
 
-		ArtifactStorage::instance()->deleteFromQuery('SELECT id FROM artifact_file WHERE artifact_id=$1',
-					array ($this->getID())) ;
-
-		$res = db_query_params ('DELETE FROM artifact_file WHERE artifact_id=$1',
-					array ($this->getID())) ;
-		if (!$res) {
-			$this->setError(_('Error deleting file from db')._(': ').db_error());
-			db_rollback();
-			ArtifactStorage::instance()->rollback();
-			return false;
-		}
-		$res = db_query_params ('DELETE FROM artifact_message WHERE artifact_id=$1',
-					array ($this->getID())) ;
-		if (!$res) {
-			$this->setError(_('Error deleting message')._(': ').db_error());
-			db_rollback();
-			ArtifactStorage::instance()->rollback();
-			return false;
-		}
-		$res = db_query_params ('DELETE FROM artifact_history WHERE artifact_id=$1',
-					array ($this->getID())) ;
-		if (!$res) {
-			$this->setError(_('Error deleting history')._(': ').db_error());
-			db_rollback();
-			ArtifactStorage::instance()->rollback();
-			return false;
-		}
 		$MonitorElementObject = new MonitorElement('artifact');
 		if (!$MonitorElementObject->clearMonitor($this->getID())) {
 			$this->setError(_('Error deleting monitor')._(': ').db_error());
 			db_rollback();
-			ArtifactStorage::instance()->rollback();
 			return false;
 		}
-		$res = db_query_params ('DELETE FROM artifact WHERE artifact_id=$1',
+
+		$res = db_query_params ('UPDATE artifact SET is_deleted=1 WHERE artifact_id=$1',
 					array ($this->getID())) ;
 		if (!$res) {
 			$this->setError(_('Error deleting artifact')._(': ').db_error());
 			db_rollback();
-			ArtifactStorage::instance()->rollback();
 			return false;
 		}
 
 		if (!$this->removeAllAssociations()) {
 			// error message already set by FFObject class.
 			db_rollback();
-			ArtifactStorage::instance()->rollback();
 			return false;
 		}
 
+		// update counts: /!\ counts is also update by a trigger artifactgroup_update_trig
+		// and 2 rules artifact_delete_agg (for real delete), artifact_insert_agg
 		if ($this->getStatusID() == 1) {
 			$res = db_query_params ('UPDATE artifact_counts_agg SET count=count-1,open_count=open_count-1
 				WHERE group_artifact_id=$1',
-						array ($this->getID())) ;
+						array ($this->getArtifactType()->getID())) ;
+			var_dump($res1);
 			if (!$res) {
 				$this->setError(_('Error updating artifact counts')._(': ').db_error());
 				db_rollback();
-				ArtifactStorage::instance()->rollback();
 				return false;
 			}
 		} elseif ($this->getStatusID() == 2) {
 			$res = db_query_params ('UPDATE artifact_counts_agg SET count=count-1
 				WHERE group_artifact_id=$1',
-						array ($this->getID())) ;
+						array ($this->getArtifactType()->getID())) ;
 			if (!$res) {
 				$this->setError(_('Error updating artifact counts')._(': ').db_error());
 				db_rollback();
-				ArtifactStorage::instance()->rollback();
 				return false;
 			}
 		}
-
 		db_commit();
-		ArtifactStorage::instance()->commit();
 		return true;
 	}
 
@@ -839,7 +838,7 @@ class Artifact extends FFObject {
 					       $time,
 					       htmlspecialchars($body))) ;
 
-		$this->updateLastModifiedDate($importData);
+		$this->updateLastModified($importData);
 
 		if ($send_followup && $sendNotice) {
 			$this->mailFollowupEx($time, 2, false);
@@ -1273,20 +1272,26 @@ class Artifact extends FFObject {
 	}
 
 	/**
-	 * updateLastModifiedDate - update the last_modified_date attribute of this artifact.
+	 * updateLastModified - update last_modified_date & last_modified_by attribute of this artifact.
 	 * @param	array	$importData	Array of data to change submitter and time of submit like:
 	 *						array('user' => 127, 'time' => 1234556789)
 	 *
 	 * @return	bool	true on success / false on failure
 	 */
-	function updateLastModifiedDate($importData = array()) {
+	function updateLastModified($importData = array()) {
 		if (array_key_exists('time',$importData)){
 			$time = $importData['time'];
 		} else {
 			$time = time();
 		}
-		$res = db_query_params ('UPDATE artifact SET last_modified_date=$1 WHERE artifact_id=$2',
-			array ($time, $this->getID()));
+		if (array_key_exists('user',$importData)){
+			$user = $importData['user'];
+		} else {
+			$user = ((session_loggedin()) ? user_getid() : 100);
+		}
+
+		$res = db_query_params ('UPDATE artifact SET last_modified_date=$1, last_modified_by=$2 WHERE artifact_id=$3',
+			array ($time, $user, $this->getID()));
 		return (!$res);
 	}
 
@@ -1647,7 +1652,7 @@ class Artifact extends FFObject {
 		unset($this->extra_field_data);
 
 		if ($update)
-			$this->updateLastModifiedDate($importData);
+			$this->updateLastModified($importData);
 
 		return true;
 	}
@@ -2054,15 +2059,19 @@ class ArtifactComparator {
 			}
 			break ;
 		case 'assigned_to':
-			$namecmp = strcoll (user_get_object($a->getAssignedTo())->getRealName(),
-					    user_get_object($b->getAssignedTo())->getRealName()) ;
+			$namecmp = strcoll ($a->getAssignedRealName(),$b->getAssignedRealName()) ;
 			if ($namecmp != 0) {
 				return $namecmp ;
 			}
 			break ;
 		case 'submitted_by':
-			$namecmp = strcoll (user_get_object($a->getSubmittedBy())->getRealName(),
-					    user_get_object($b->getSubmittedBy())->getRealName()) ;
+			$namecmp = strcoll ($a->getSubmittedRealName(),$b->getSubmittedRealName()) ;
+			if ($namecmp != 0) {
+				return $namecmp ;
+			}
+			break ;
+		case 'last_modified_by':
+			$namecmp = strcoll ($a->getLastModifiedRealName(),$b->getLastModifiedRealName()) ;
 			if ($namecmp != 0) {
 				return $namecmp ;
 			}
diff --git a/src/common/tracker/ArtifactFactory.class.php b/src/common/tracker/ArtifactFactory.class.php
index 1f3c2e3..d897708 100644
--- a/src/common/tracker/ArtifactFactory.class.php
+++ b/src/common/tracker/ArtifactFactory.class.php
@@ -5,6 +5,7 @@
  * Copyright 2002, GForge, LLC
  * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
  * Copyright 2014, Franck Villaume - TrivialDev
+ * Copyright 2016, Stéphane-Eymeric Bredthauer - TrivialDev
  *
  * This file is part of FusionForge. FusionForge is free software;
  * you can redistribute it and/or modify it under the terms of the
@@ -49,6 +50,7 @@ class ArtifactFactory extends FFError {
 	var $last_changed;
 	var $submitted_by;
 	var $assigned_to;
+	var $last_modified_by;
 	var $offset;
 	var $max_rows;
 	var $fetched_rows;
@@ -178,6 +180,7 @@ class ArtifactFactory extends FFError {
 				$aq = new ArtifactQuery($this->ArtifactType, $this->query_id);
 				$this->submitted_by=$aq->getSubmitter();
 				$_assigned_to=$aq->getAssignee();
+				$this->last_modified_by=$aq->getLastModifier();
 				$_status=$aq->getStatus();
 				$_extra_fields=$aq->getExtraFields();
 				$this->moddaterange = $aq->getModDateRange();
@@ -203,6 +206,7 @@ class ArtifactFactory extends FFError {
 					   'submitted_by',
 					   'priority',
 					   'last_modified_date',
+					   'last_modified_by',
 					   '_votes',
 					   '_voters',
 					   '_votage') ;
@@ -318,7 +322,7 @@ class ArtifactFactory extends FFError {
 				$res = db_query_params ('SELECT field_type FROM artifact_extra_field_list WHERE extra_field_id=$1',
 							array($keys[$i])) ;
 				$type = db_result($res,0,'field_type');
-				if ($type == 4 or $type == 6) {
+				if ($type == ARTIFACT_EXTRAFIELDTYPE_TEXT or $type == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
 					$wheresql .= ' AND aefd'.$i.'.field_data LIKE $'.$paramcount++ ;
 					$params[] = $vals[$i];
 				} else {
@@ -365,6 +369,18 @@ class ArtifactFactory extends FFError {
 			}
 		}
 
+		//if assigned to selected, and more to where clause
+		if ($this->last_modified_by) {
+			if (is_array($this->last_modified_by)) {
+				$wheresql .= ' AND last_modified_by = ANY ($'.$paramcount++ ;
+				$params[] = db_int_array_to_any_clause ($this->last_modified_by) ;
+				$wheresql .= ')' ;
+			} else {
+				$wheresql .= ' AND last_modified_by = $'.$paramcount++ ;
+				$params[] = $this->last_modified_by ;
+			}
+		}
+
 		if ($this->last_changed > 0) {
 			$wheresql .= ' AND last_modified_date > $'.$paramcount++ ;
 			$params[] = $this->last_changed ;
@@ -432,17 +448,28 @@ class ArtifactFactory extends FFError {
 							    'close_date',
 							    'assigned_to',
 							    'submitted_by',
+							    'last_modified_by',
 							    'priority',
 							    '_votage',
 							    '_voters',
 							    '_votes'));
 
 		if ($sortcol != 'extra' && $sortcol != '_votes' && $sortcol != '_voters' && $sortcol != '_votage' ) {
+			switch ($sortcol) {
+				case 'assigned_to':
+					$sortcol = 'assigned_realname';
+					break;
+				case 'submitted_by':
+					$sortcol = 'submitted_realname';
+					break;
+				case 'last_modified_by':
+					$sortcol = 'assigned_realname';
+					break;
+			}
 			$ordersql = " ORDER BY Artifacts.group_artifact_id $sortorder, Artifacts.$sortcol $sortorder" ;
 		} else {
 			$ordersql = ''  ;
 		}
-
 		$result = db_query_params ('SELECT * FROM (' . $selectsql . $wheresql . ') AS Artifacts' . $ordersql,
 					   $params) ;
 		$rows = db_numrows($result);
diff --git a/src/common/tracker/ArtifactFile.class.php b/src/common/tracker/ArtifactFile.class.php
index fd0540b..236aa32 100644
--- a/src/common/tracker/ArtifactFile.class.php
+++ b/src/common/tracker/ArtifactFile.class.php
@@ -4,6 +4,7 @@
  *
  * Copyright 1999-2001, VA Linux Systems, Inc.
  * Copyright 2009, Roland Mas
+ * Copyright 2016, Stéphane-Eymeric Bredthauer - TrivialDev
  *
  * This file is part of FusionForge. FusionForge is free software;
  * you can redistribute it and/or modify it under the terms of the
@@ -178,7 +179,7 @@ class ArtifactFile extends FFError {
 			if (!array_key_exists('time', $importData)){
 				$this->Artifact->addHistory('File Added',$id.': '.$filename);
 			}
-			$this->Artifact->updateLastModifiedDate();
+			$this->Artifact->updateLastModified();
 			$this->clearError();
 			return $id;
 		}
diff --git a/src/common/tracker/ArtifactQuery.class.php b/src/common/tracker/ArtifactQuery.class.php
index 1574ce8..61f5a74 100644
--- a/src/common/tracker/ArtifactQuery.class.php
+++ b/src/common/tracker/ArtifactQuery.class.php
@@ -6,6 +6,7 @@
  * Copyright 2005, GForge, LLC
  * Copyright 2009, Roland Mas
  * Copyright 2009, Alcatel-Lucent
+ * Copyright 2016, Stéphane-Eymeric Bredthauer - TrivialDev
  *
  * This file is part of FusionForge. FusionForge is free software;
  * you can redistribute it and/or modify it under the terms of the
@@ -59,6 +60,7 @@ define('ARTIFACT_QUERY_SUMMARY',9);
 define('ARTIFACT_QUERY_DESCRIPTION',10);
 define('ARTIFACT_QUERY_FOLLOWUPS',11);
 define('ARTIFACT_QUERY_SUBMITTER',12);
+define('ARTIFACT_QUERY_LAST_MODIFIER',13);
 
 require_once $gfcommon.'tracker/ArtifactType.class.php';
 
@@ -134,7 +136,7 @@ class ArtifactQuery extends FFError {
 	 * @return	bool		true on success / false on failure.
 	 */
 	function create($name,$status,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange=0,$closedaterange=0,
-		$summary='',$description='',$followups='',$query_type=0,$query_options=array(),$submitter='') {
+		$summary='',$description='',$followups='',$query_type=0,$query_options=array(),$submitter='',$last_modifier='') {
 		//
 		//	data validation
 		//
@@ -181,7 +183,7 @@ class ArtifactQuery extends FFError {
 				db_rollback();
 				return false;
 			} else {
-				if (!$this->insertElements($id,$status,$submitter,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange,$closedaterange,$summary,$description,$followups)) {
+				if (!$this->insertElements($id,$status,$submitter,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange,$closedaterange,$summary,$description,$followups,$last_modifier)) {
 					db_rollback();
 					return false;
 				}
@@ -261,7 +263,7 @@ class ArtifactQuery extends FFError {
 	 * @param	$followups
 	 * @return	boolean		True/false on success or not.
 	 */
-	function insertElements($id,$status,$submitter,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange,$closedaterange,$summary,$description,$followups) {
+	function insertElements($id,$status,$submitter,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange,$closedaterange,$summary,$description,$followups,$last_modifier) {
 		$res = db_query_params ('DELETE FROM artifact_query_fields WHERE artifact_query_id=$1',
 					array ($id)) ;
 		if (!$res) {
@@ -297,6 +299,15 @@ class ArtifactQuery extends FFError {
 			$assignee = intval($assignee);
 		}
 
+		if (is_array($last_modifier)) {
+			for($e=0; $e<count($last_modifier); $e++) {
+				$last_modifier[$e]=intval($last_modifier[$e]);
+			}
+			$last_modifier=implode(',',$last_modifier);
+		} else {
+			$last_modifier = intval($last_modifier);
+		}
+
 		if (preg_match("/[^[:alnum:]_]/", $sort_col)) {
 			$this->setError('ArtifactQuery: not valid sort_col');
 			return false;
@@ -321,6 +332,20 @@ class ArtifactQuery extends FFError {
 			}
 		}
 
+		//CSV LIST OF SUBMITTERS
+		if ($last_modifier) {
+			$res = db_query_params ('INSERT INTO artifact_query_fields
+									(artifact_query_id,query_field_type,query_field_id,query_field_values)
+									VALUES ($1,$2,0,$3)',
+					array ($id,
+							ARTIFACT_QUERY_LAST_MODIFIER,
+							$last_modifier)) ;
+			if (!$res) {
+				$this->setError('Setting Last Modifier: '.db_error());
+				return false;
+			}
+		}
+
 		//CSV LIST OF ASSIGNEES
 		if ($assignee) {
 			$res = db_query_params ('INSERT INTO artifact_query_fields
@@ -663,6 +688,17 @@ class ArtifactQuery extends FFError {
 	}
 
 	/**
+	 * getLastModifier
+	 *
+	 * @return	string	Last Modifier ID
+	 */
+	function getLastModifier() {
+		if (!isset($this->element_array[ARTIFACT_QUERY_LAST_MODIFIER]))
+			return false;
+			return $this->element_array[ARTIFACT_QUERY_LAST_MODIFIER][0];
+	}
+
+	/**
 	 * getStatus
 	 *
 	 * @return	string	Status ID
@@ -731,7 +767,7 @@ class ArtifactQuery extends FFError {
 	 * @return	bool		success.
 	 */
 	function update($name,$status,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange='',$closedaterange='',
-		$summary,$description,$followups,$query_type=0,$query_options=array(),$submitter='') {
+		$summary,$description,$followups,$query_type=0,$query_options=array(),$submitter='',$last_modifier='') {
 		if (!$name) {
 			$this->setMissingParamsError();
 			return false;
@@ -765,7 +801,7 @@ class ArtifactQuery extends FFError {
 						  join('|', $query_options),
 						  $this->getID())) ;
 		if ($result && db_affected_rows($result) > 0) {
-			if (!$this->insertElements($this->getID(),$status,$submitter,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange,$closedaterange,$summary,$description,$followups)) {
+			if (!$this->insertElements($this->getID(),$status,$submitter,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange,$closedaterange,$summary,$description,$followups,$last_modifier)) {
 				db_rollback();
 				return false;
 			} else {
diff --git a/src/common/tracker/ArtifactType.class.php b/src/common/tracker/ArtifactType.class.php
index 7cb2198..db3ed55 100644
--- a/src/common/tracker/ArtifactType.class.php
+++ b/src/common/tracker/ArtifactType.class.php
@@ -111,6 +111,13 @@ class ArtifactType extends FFError {
 	var $submitters_res;
 
 	/**
+	 * Last Modifiers db resource ID.
+	 *
+	 * @var	int	$last_modifiers_res.
+	 */
+	var $last_modifiers_res;
+
+	/**
 	 * Status db resource ID.
 	 *
 	 * @var	int	$status_res.
@@ -134,14 +141,14 @@ class ArtifactType extends FFError {
 	/**
 	 * Array of element names so they only have to be fetched once from db.
 	 *
-	 * @var	array	 $data_array.
+	 * @var	array	 $element_name.
 	 */
 	var $element_name;
 
 	/**
 	 * Array of element status so they only have to be fetched once from db.
 	 *
-	 * @var	array	$data_array.
+	 * @var	array	$element_status.
 	 */
 	var $element_status;
 
@@ -1110,6 +1117,22 @@ class ArtifactType extends FFError {
 	}
 
 	/**
+	 * getLastModifiers - returns a result set of last modifiers.
+	 *
+	 * @return	resource	database result set.
+	 */
+	function getLastModifiers() {
+		if (!isset($this->last_modifiers_res)) {
+			$this->last_modifiers_res = db_query_params('SELECT DISTINCT last_modified_by, last_modified_realname
+				FROM artifact_vw
+				WHERE group_artifact_id=$1
+				ORDER BY last_modified_realname',
+					array($this->getID()));
+		}
+		return $this->last_modifiers_res;
+	}
+
+	/**
 	 * getCannedResponses - returns a result set of canned responses.
 	 *
 	 * @return	resource	database result set.
diff --git a/src/common/tracker/actions/browse.php b/src/common/tracker/actions/browse.php
index c9dea49..5f8ace9 100644
--- a/src/common/tracker/actions/browse.php
+++ b/src/common/tracker/actions/browse.php
@@ -9,6 +9,7 @@
  * Copyright 2011, Iñigo Martinez
  * Copyright 2012, Thorsten “mirabilos” Glaser <t.glaser at tarent.de>
  * Copyright 2014, Stéphane-Eymeric Bredthauer
+ * Copyright 2016, Stéphane-Eymeric Bredthauer - TrivialDev
  * http://fusionforge.org
  *
  * This file is part of FusionForge. FusionForge is free software;
@@ -203,6 +204,7 @@ $order_name_arr[]=_('Priority');
 $order_name_arr[]=_('Summary');
 $order_name_arr[]=_('Open Date');
 $order_name_arr[]=_('Last Modified Date');
+$order_name_arr[]=_('Last Modifier');
 $order_name_arr[]=_('Close Date');
 $order_name_arr[]=_('Submitter');
 $order_name_arr[]=_('Assignee');
@@ -216,6 +218,7 @@ $order_arr[]='priority';
 $order_arr[]='summary';
 $order_arr[]='open_date';
 $order_arr[]='last_modified_date';
+$order_arr[]='last_modified_by';
 $order_arr[]='close_date';
 $order_arr[]='submitted_by';
 $order_arr[]='assigned_to';
@@ -547,40 +550,63 @@ if ($art_arr && $art_cnt > 0) {
 	$pager = '';
 
 	$browse_fields = explode(',', "id,".$ath->getBrowseList());
+	if (!in_array($_sort_col,$browse_fields)) {
+		$browse_fields[] = $_sort_col;
+	}
+
 	$title_arr=array();
 	foreach ($browse_fields as $f) {
 		$title=$f;
-		if (intval($f) > 0) {
-			$title = $ath->getExtraFieldName($f);
-		} else {
-			if ($f == 'id')
+		switch ($f) {
+			case 'id':
 				$title=_('Id');
-			if ($f == 'summary')
+				break;
+			case 'summary':
 				$title=_('Summary');
-			if ($f == 'details')
+				break;
+			case 'details':
 				$title=_('Description');
-			if ($f == 'open_date')
+				break;
+			case 'open_date':
 				$title=_('Open Date');
-			if ($f == 'close_date')
+				break;
+			case 'close_date':
 				$title=_('Close Date');
-			if ($f == 'status_id')
+				break;
+			case 'status_id':
 				$title=_('State');
-			if ($f == 'priority')
+				break;
+			case 'priority':
 				$title=_('Priority');
-			if ($f == 'assigned_to')
+				break;
+			case'assigned_to':
 				$title=_('Assigned to');
-			if ($f == 'submitted_by')
+				break;
+			case'submitted_by':
 				$title=_('Submitted by');
-			if ($f == 'related_tasks')
+				break;
+			case 'related_tasks':
 				$title=_('Related Tasks');
-			if ($f == 'last_modified_date')
+				break;
+			case 'last_modified_date':
 				$title=_('Last Modified Date');
-			if ($f == '_votes')
+				break;
+			case 'last_modified_by':
+				$title=_('Last Modifier');
+				break;
+			case '_votes':
 				$title = _('# Votes');
-			if ($f == '_voters')
+				break;
+			case '_voters':
 				$title = _('# Voters');
-			if ($f == '_votage')
+				break;
+			case '_votage':
 				$title = _('% Voted');
+				break;
+			default:
+				if (intval($f) > 0) {
+					$title = $ath->getExtraFieldName($f);
+				}
 		}
 		$title_arr[] = $title;
 	}
@@ -597,81 +623,100 @@ if ($art_arr && $art_cnt > 0) {
 		echo '
 		<tr class=priority'. $art_arr[$i]->getPriority().'>';
 		foreach ($browse_fields as $f) {
-			if ($f == 'id') {
-				echo '<td style="white-space: nowrap;">'.
-				($IS_ADMIN?'<input type="checkbox" name="artifact_id_list[]" value="'.
-				$art_arr[$i]->getID() .'" /> ':'').
-				util_make_link('/tracker/?func=detail&aid='.
-				$art_arr[$i]->getID().
-				'&group_id='. $group_id .'&atid='.
-				$ath->getID(),
-				$art_arr[$i]->getID()).
-				'</td>';
-			} elseif ($f == 'summary') {
-		 		echo '<td>'.
-				util_make_link('/tracker/?func=detail&aid='.
-				$art_arr[$i]->getID() .
-				'&group_id='. $group_id .'&atid='.
-				$ath->getID(),
-				$art_arr[$i]->getSummary()).
-				'</td>';
-			} elseif ($f == 'open_date') {
-				echo '<td>'. (($set != 'closed' && $art_arr[$i]->getOpenDate() < $then)?'* ':'  ') .
-				date(_('Y-m-d H:i'),$art_arr[$i]->getOpenDate()) .'</td>';
-			} elseif ($f == 'status_id') {
-				echo '<td>'. $art_arr[$i]->getStatusName() .'</td>';
-			} elseif ($f == 'priority') {
-				echo '<td class="priority'.$art_arr[$i]->getPriority()  .'">'. $art_arr[$i]->getPriority() .'</td>';
-			} elseif ($f == 'assigned_to') {
-				echo '<td>'. $art_arr[$i]->getAssignedRealName() .'</td>';
-			} elseif ($f == 'submitted_by') {
-				echo '<td>'. $art_arr[$i]->getSubmittedRealName() .'</td>';
-			} elseif ($f == 'close_date') {
-				echo '<td>'. ($art_arr[$i]->getCloseDate() ?
-				date(_('Y-m-d H:i'),$art_arr[$i]->getCloseDate()) :'  ') .'</td>';
-			} elseif ($f == 'details') {
-				echo '<td>'. $art_arr[$i]->getDetails() .'</td>';
-			} elseif ($f == 'related_tasks') {
-				echo '<td>';
-				$tasks_res = $art_arr[$i]->getRelatedTasks();
-				$s ='';
-				while ($rest = db_fetch_array($tasks_res)) {
-					$link = '/pm/task.php?func=detailtask&project_task_id='.$rest['project_task_id'].
-						'&group_id='.$group_id.'&group_project_id='.$rest['group_project_id'];
-					$title = '[T'.$rest['project_task_id'].']';
-					if ($rest['status_id'] == 2) {
-						$title = '<span class="strike">'.$title.'</span>';
+			switch ($f) {
+				case 'id':
+					echo '<td style="white-space: nowrap;">'.
+						($IS_ADMIN?'<input type="checkbox" name="artifact_id_list[]" value="'.
+						$art_arr[$i]->getID() .'" /> ':'').
+						util_make_link('/tracker/?func=detail&aid='.
+						$art_arr[$i]->getID().
+						'&group_id='. $group_id .'&atid='.
+						$ath->getID(),
+						$art_arr[$i]->getID()).
+						'</td>';
+					break;
+				case 'summary':
+					echo '<td>'.
+						util_make_link('/tracker/?func=detail&aid='.
+						$art_arr[$i]->getID() .
+						'&group_id='. $group_id .'&atid='.
+						$ath->getID(),
+						$art_arr[$i]->getSummary()).
+						'</td>';
+					break;
+				case 'open_date':
+					echo '<td>'. (($set != 'closed' && $art_arr[$i]->getOpenDate() < $then)?'* ':'  ') .
+						date(_('Y-m-d H:i'),$art_arr[$i]->getOpenDate()) .'</td>';
+					break;
+				case 'status_id':
+					echo '<td>'. $art_arr[$i]->getStatusName() .'</td>';
+					break;
+				case 'priority':
+					echo '<td class="priority'.$art_arr[$i]->getPriority()  .'">'. $art_arr[$i]->getPriority() .'</td>';
+					break;
+				case 'assigned_to':
+					echo '<td>'. $art_arr[$i]->getAssignedRealName() .'</td>';
+					break;
+				case'submitted_by':
+					echo '<td>'. $art_arr[$i]->getSubmittedRealName() .'</td>';
+					break;
+				case 'last_modified_by':
+					echo '<td>'. $art_arr[$i]->getLastModifiedRealName() .'</td>';
+					break;
+				case 'close_date':
+					echo '<td>'. ($art_arr[$i]->getCloseDate() ?
+						date(_('Y-m-d H:i'),$art_arr[$i]->getCloseDate()) :'  ') .'</td>';
+					break;
+				case 'details':
+					echo '<td>'. $art_arr[$i]->getDetails() .'</td>';
+					break;
+				case 'related_tasks':
+					echo '<td>';
+					$tasks_res = $art_arr[$i]->getRelatedTasks();
+					$s ='';
+					while ($rest = db_fetch_array($tasks_res)) {
+						$link = '/pm/task.php?func=detailtask&project_task_id='.$rest['project_task_id'].
+							'&group_id='.$group_id.'&group_project_id='.$rest['group_project_id'];
+						$title = '[T'.$rest['project_task_id'].']';
+						if ($rest['status_id'] == 2) {
+							$title = '<span class="strike">'.$title.'</span>';
+						}
+						echo $s.util_make_link($link, $title, array( 'title' => util_html_secure($rest['summary'])));
+						$s = ' ';
 					}
-					echo $s.util_make_link($link, $title, array( 'title' => util_html_secure($rest['summary'])));
-					$s = ' ';
-				}
-				echo '</td>';
-			} elseif ($f == 'last_modified_date') {
-				echo '<td>'. ($art_arr[$i]->getLastModifiedDate() ?
-				date(_('Y-m-d H:i'),$art_arr[$i]->getLastModifiedDate()) :'  ') .'</td>';
-			} elseif (intval($f) > 0) {
-				// Now display extra-fields (fields are numbers).
-				$value = $extra_data[$f]['value'];
-				if ($extra_data[$f]['type'] == 9) {
-					$value = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1')", $value);
-				} elseif ($extra_data[$f]['type'] == 7) {
-					if ($art_arr[$i]->getStatusID() == 2) {
-						$value = '<span class="strike">'.$value.'</span>';
+					echo '</td>';
+					break;
+				case 'last_modified_date':
+					echo '<td>'. ($art_arr[$i]->getLastModifiedDate() ?
+						date(_('Y-m-d H:i'),$art_arr[$i]->getLastModifiedDate()) :'  ') .'</td>';
+					break;
+				case '_votes':
+					$v = $art_arr[$i]->getVotes();
+					echo html_e('td', array(), $v[0], false);
+					break;
+				case '_voters':
+					echo html_e('td', array(), $voters, false);
+					break;
+				case '_votage':
+					$v = $art_arr[$i]->getVotes();
+					echo html_e('td', array(), $v[2], false);
+					break;
+				default:
+					if (intval($f) > 0) {
+						// Now display extra-fields (fields are numbers).
+						$value = $extra_data[$f]['value'];
+						if ($extra_data[$f]['type'] == 9) {
+							$value = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1')", $value);
+						} elseif ($extra_data[$f]['type'] == 7) {
+							if ($art_arr[$i]->getStatusID() == 2) {
+								$value = '<span class="strike">'.$value.'</span>';
+							}
+						}
+						echo '<td>' . $value .'</td>';
+					} else {
+						// Display ? for unknown values.
+						echo '<td>?</td>';
 					}
-
-				}
-				echo '<td>' . $value .'</td>';
-			} elseif ($f == '_votes') {
-				$v = $art_arr[$i]->getVotes();
-				echo html_e('td', array(), $v[0], false);
-			} elseif ($f == '_voters') {
-				echo html_e('td', array(), $voters, false);
-			} elseif ($f == '_votage') {
-				$v = $art_arr[$i]->getVotes();
-				echo html_e('td', array(), $v[2], false);
-			} else {
-				// Display ? for unknown values.
-				echo '<td>?</td>';
 			}
 		}
 		echo '</tr>';
diff --git a/src/common/tracker/actions/query.php b/src/common/tracker/actions/query.php
index 1496b98..d8071ff 100644
--- a/src/common/tracker/actions/query.php
+++ b/src/common/tracker/actions/query.php
@@ -4,6 +4,7 @@
  * Copyright 2010 (c) Fusionforge Team
  * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
  * Copyright 2012-2015, Franck Villaume - TrivialDev
+ * Copyright 2016, Stéphane-Eymeric Bredthauer - TrivialDev
  * http://fusionforge.org
  *
  * This file is part of FusionForge. FusionForge is free software;
@@ -56,6 +57,7 @@ if (getStringFromRequest('submit')) {
 		$_status = getStringFromRequest('_status');
 		$_submitted_by = getStringFromRequest('_submitted_by');
 		$_assigned_to = getStringFromRequest('_assigned_to');
+		$_last_modified_by = getStringFromRequest('_last_modified_by');
 		$_sort_col = getStringFromRequest('_sort_col');
 		$_sort_ord = getStringFromRequest('_sort_ord');
 		$extra_fields = getStringFromRequest('extra_fields');
@@ -67,7 +69,7 @@ if (getStringFromRequest('submit')) {
 		$_followups = getStringFromRequest('_followups');
 		$query_options = array_keys(getArrayFromRequest('query_options'));
 		if (!$aq->create($query_name,$_status,$_assigned_to,$_moddaterange,$_sort_col,$_sort_ord,$extra_fields,$_opendaterange,$_closedaterange,
-			$_summary,$_description,$_followups,$query_type, $query_options, $_submitted_by)) {
+			$_summary,$_description,$_followups,$query_type, $query_options, $_submitted_by, $_last_modified_by)) {
 			form_release_key(getStringFromRequest('form_key'));
 			exit_error($aq->getErrorMessage(),'tracker');
 		} else {
@@ -106,6 +108,7 @@ if (getStringFromRequest('submit')) {
 		$_status = getStringFromRequest('_status');
 		$_submitted_by = getStringFromRequest('_submitted_by');
 		$_assigned_to = getStringFromRequest('_assigned_to');
+		$_last_modified_by = getStringFromRequest('_last_modified_by');
 		$_sort_col = getStringFromRequest('_sort_col');
 		$_sort_ord = getStringFromRequest('_sort_ord');
 		$_moddaterange = getStringFromRequest('_moddaterange');
@@ -117,7 +120,7 @@ if (getStringFromRequest('submit')) {
 		$extra_fields = getStringFromRequest('extra_fields');
 		$query_options = array_keys(getArrayFromRequest('query_options'));
 		if (!$aq->update($query_name,$_status,$_assigned_to,$_moddaterange,$_sort_col,$_sort_ord,$extra_fields,$_opendaterange,$_closedaterange,
-			$_summary,$_description,$_followups,$query_type, $query_options, $_submitted_by)) {
+			$_summary,$_description,$_followups,$query_type, $query_options, $_submitted_by,$_last_modified_by)) {
 			exit_error($aq->getErrorMessage(),'tracker');
 		} else {
 			$feedback .= _('Query Updated');
@@ -170,6 +173,7 @@ if (getStringFromRequest('submit')) {
 //
 $_submitted_by=$aq->getSubmitter();
 $_assigned_to=$aq->getAssignee();
+$_last_modified_by=$aq->getLastModifier();
 $_status=$aq->getStatus();
 $extra_fields=$aq->getExtraFields();
 $_sort_col=$aq->getSortCol();
@@ -185,7 +189,10 @@ $query_type=$aq->getQueryType();
 //	creating a submitter box
 $submitter_box = $ath->submitterBox('_submitted_by[]',$_submitted_by,true,'none','-1',false,true);
 //	creating a custom technician box which includes "any" and "unassigned"
-$tech_box=$ath->technicianBox('_assigned_to[]',$_assigned_to,true,'none','-1',false,true);
+$tech_box = $ath->technicianBox('_assigned_to[]',$_assigned_to,true,'none','-1',false,true);
+//	creating a last modifier box
+$last_modifier_box = $ath->lastModifierBox('_last_modified_by[]',$_last_modified_by,true,'none','-1',false,true);
+
 
 //
 //	custom order by arrays to build a pop-up box
@@ -199,6 +206,7 @@ $order_name_arr[]=_('Last Modified Date');
 $order_name_arr[]=_('Close Date');
 $order_name_arr[]=_('Submitter');
 $order_name_arr[]=_('Assignee');
+$order_name_arr[]=_('Last Modifier');
 
 $order_arr=array();
 $order_arr[]='artifact_id';
@@ -209,6 +217,7 @@ $order_arr[]='last_modified_date';
 $order_arr[]='close_date';
 $order_arr[]='submitted_by';
 $order_arr[]='assigned_to';
+$order_arr[]='last_modified_by';
 
 //
 //	custom sort arrays to build pop-up box
@@ -343,6 +352,9 @@ if (forge_check_perm ('tracker', $ath->getID(), 'manager')) {
 	echo '<tr>
 		<td class="top"><strong>'._('Submitter')._(': ').'</strong><br />'. $submitter_box .'</td>
 		<td class="top"><strong>'._('Assignee')._(': ').'</strong><br />'. $tech_box .'</td>
+	</tr>
+	<tr>
+		<td class="top"><strong>'._('Last Modifier')._(': ').'</strong><br />'. $last_modifier_box .'</td>
 	</tr>';
 	$ath->renderExtraFields($extra_fields,true,'none',true,'Any',array(),false,'QUERY');
 
diff --git a/src/common/tracker/include/ArtifactHtml.class.php b/src/common/tracker/include/ArtifactHtml.class.php
index 2e37338..63dac15 100644
--- a/src/common/tracker/include/ArtifactHtml.class.php
+++ b/src/common/tracker/include/ArtifactHtml.class.php
@@ -6,6 +6,7 @@
  * Copyright (C) 2011-2012 Alain Peyrat - Alcatel-Lucent
  * Copyright 2011, Franck Villaume - Capgemini
  * Copyright 2015-2016, Franck Villaume - TrivialDev
+ * Copyright 2016, Stéphane-Eymeric Bredthauer - TrivialDev
  * http://fusionforge.org
  *
  * This file is part of FusionForge. FusionForge is free software;
@@ -200,6 +201,7 @@ function hide_edit_button(id) {
 		AND artifact.artifact_id = artifact_extra_field_data.artifact_id
 		AND groups.group_id = artifact_group_list.group_id
 		AND (field_data = $1 OR field_data LIKE $2 OR field_data LIKE $3 OR field_data LIKE $4)
+		AND artifact.is_deleted = 0
 		ORDER BY artifact_group_list.group_id ASC, name ASC, artifact.artifact_id ASC',
 					array($aid,
 					      "$aid %",
diff --git a/src/common/tracker/include/ArtifactTypeHtml.class.php b/src/common/tracker/include/ArtifactTypeHtml.class.php
index c03ef5c..8cac2bb 100644
--- a/src/common/tracker/include/ArtifactTypeHtml.class.php
+++ b/src/common/tracker/include/ArtifactTypeHtml.class.php
@@ -252,7 +252,7 @@ class ArtifactTypeHtml extends ArtifactType {
 			if (!empty($efarr[$i]['description'])) {
 				$attrs['title'] = $efarr[$i]['description'];
 			}
-			if ($efarr[$i]['is_required'] == 1) {
+			if ($efarr[$i]['is_required'] == 1 && $mode != 'QUERY') {
 				$attrs['required'] = 'required';
 			}
 
@@ -1056,6 +1056,29 @@ EOS;
 		}
 	}
 
+	function lastModifierBox ($name='last_modified_by[]',$checked='xzxz',$show_100=true,$text_100='none',$extra_id='-1',$extra_name='',$multiple=false) {
+		if ($text_100=='none'){
+			$text_100=_('Nobody');
+		}
+		$result = $this->getLastModifiers();
+		$ids =& util_result_column_to_array($result,0);
+		$names =& util_result_column_to_array($result,1);
+		if ($extra_id != '-1') {
+			$ids[]=$extra_id;
+			$names[]=$extra_name;
+		}
+
+		if ($multiple) {
+			if (!is_array($checked)) {
+				$checked = explode(',',$checked);
+			}
+			$size = min( count($ids)+1, 15);
+			return html_build_multiple_select_box_from_arrays ($ids,$names,$name,$checked,$size,$show_100,$text_100);
+		} else {
+			return html_build_select_box_from_arrays ($ids,$names,$name,$checked,$show_100,$text_100);
+		}
+	}
+
 	function cannedResponseBox ($name='canned_response',$checked='xzxz') {
 		return html_build_select_box ($this->getCannedResponses(),$name,$checked);
 	}
diff --git a/src/common/tracker/views/form-customizelist.php b/src/common/tracker/views/form-customizelist.php
index 49db547..3da5256 100644
--- a/src/common/tracker/views/form-customizelist.php
+++ b/src/common/tracker/views/form-customizelist.php
@@ -6,6 +6,7 @@
  * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
  * Copyright 2012, Thorsten “mirabilos” Glaser <t.glaser at tarent.de>
  * Copyright 2015-2016, Franck Villaume - TrivialDev
+ * Copyright 2016, Stéphane-Eymeric Bredthauer - TrivialDev
  *
  * This file is part of FusionForge. FusionForge is free software;
  * you can redistribute it and/or modify it under the terms of the
@@ -45,6 +46,7 @@ $fields = array (
 	'priority'  => _('Priority'),
 	'assigned_to' => _('Assigned to'),
 	'submitted_by' => _('Submitted by'),
+	'last_modified_by' => _('Last Modified by'),
 	'close_date' => _('Close Date'),
 	'details' => _('Detailed description'),
 	'related_tasks' => _('Related Tasks'),
diff --git a/src/db/20161025-tracker-internal-artifact-fields.sql b/src/db/20161025-tracker-internal-artifact-fields.sql
new file mode 100644
index 0000000..4143184
--- /dev/null
+++ b/src/db/20161025-tracker-internal-artifact-fields.sql
@@ -0,0 +1,41 @@
+DROP TRIGGER artifact_update_last_modified_date ON artifact;
+
+ALTER TABLE artifact
+   ADD COLUMN last_modified_by integer NOT NULL DEFAULT 100,
+   ADD COLUMN is_deleted integer NOT NULL DEFAULT 0,
+   ADD CONSTRAINT artifact_last_modified_by_fk FOREIGN KEY (last_modified_by)
+      REFERENCES users (user_id) MATCH FULL
+      ON UPDATE NO ACTION ON DELETE NO ACTION
+
+CREATE OR REPLACE VIEW artifact_vw AS 
+ SELECT
+    artifact.artifact_id,
+    artifact.group_artifact_id,
+    artifact.status_id, 
+    artifact.priority,
+    artifact.submitted_by,
+    artifact.assigned_to,
+    artifact.open_date,
+    artifact.close_date,
+    artifact.summary,
+    artifact.details,
+    u.user_name AS assigned_unixname,
+    u.realname AS assigned_realname, 
+    u.email AS assigned_email,
+    u2.user_name AS submitted_unixname, 
+    u2.realname AS submitted_realname,
+    u2.email AS submitted_email, 
+    artifact_status.status_name,
+    artifact.last_modified_date,
+    artifact.last_modified_by,
+    u3.user_name AS last_modified_unixname,
+    u3.realname AS last_modified_realname,
+    u3.email AS last_modified_email
+   FROM
+    artifact 
+    INNER JOIN users AS u ON (artifact.assigned_to = u.user_id)
+    INNER JOIN users AS u2 ON (artifact.submitted_by = u2.user_id)
+    INNER JOIN users AS u3 ON (artifact.last_modified_by = u3.user_id)
+    INNER JOIN artifact_status ON (artifact.status_id = artifact_status.id)
+  WHERE
+    artifact.is_deleted = 0;

-----------------------------------------------------------------------

Summary of changes:
 src/common/tracker/Artifact.class.php              | 119 ++++++-----
 src/common/tracker/ArtifactFactory.class.php       |  31 ++-
 src/common/tracker/ArtifactFile.class.php          |   3 +-
 src/common/tracker/ArtifactQuery.class.php         |  46 ++++-
 src/common/tracker/ArtifactType.class.php          |  27 ++-
 src/common/tracker/actions/browse.php              | 225 ++++++++++++---------
 src/common/tracker/actions/query.php               |  18 +-
 src/common/tracker/include/ArtifactHtml.class.php  |   2 +
 .../tracker/include/ArtifactTypeHtml.class.php     |  25 ++-
 src/common/tracker/views/form-customizelist.php    |   2 +
 .../20161025-tracker-internal-artifact-fields.sql  |  41 ++++
 11 files changed, 380 insertions(+), 159 deletions(-)
 create mode 100644 src/db/20161025-tracker-internal-artifact-fields.sql


hooks/post-receive
-- 
FusionForge



More information about the Fusionforge-commits mailing list