[Fusionforge-commits] FusionForge branch master updated. v6.0.5-1885-gd5019eb

Franck Villaume nerville at libremir.placard.fr.eu.org
Tue May 30 15:13:10 CEST 2017


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  d5019eb8511917a50bf5fcf622597b72593c3001 (commit)
      from  f737f582ed96ef2d325f2428a93ecbe383b1faaf (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=d5019eb8511917a50bf5fcf622597b72593c3001

commit d5019eb8511917a50bf5fcf622597b72593c3001
Author: St├ęphane-Eymeric Bredthauer <sebredthauer at gmail.com>
Date:   Tue May 30 15:08:55 2017 +0200

    Tracker: Artifacts dependencies, part 4

diff --git a/src/common/tracker/Artifact.class.php b/src/common/tracker/Artifact.class.php
index 25097a5..08a178c 100644
--- a/src/common/tracker/Artifact.class.php
+++ b/src/common/tracker/Artifact.class.php
@@ -1466,6 +1466,7 @@ class Artifact extends FFObject {
 				$this->setError(sprintf(_("Field %s doesn't match the pattern."), $ef[$efid]['field_name']));
 				return false;
 			}
+
 //
 //	Force each field to have some value if it is a numeric field
 //	text fields will just be purged and skipped
@@ -1563,18 +1564,26 @@ class Artifact extends FFObject {
 				$new = '';
 				foreach (explode(' ',$value) as $id) {
 					if (preg_match('/^(\d+)$/', $id)) {
+						if ($id == $this->getID) {
+							$this->setError('Illegal id '.$id.', self reference for field: '.$ef[$efid]['field_name'].'.'); // @todo: lang
+							return false;
+						}
 						// Control that the id is present in the db
-
 						$res = db_query_params ('SELECT artifact_id FROM artifact WHERE artifact_id=$1',
 									array($id));
 						if (db_numrows($res) == 1) {
 							$new .= $id.' ';
 						} else {
-							$this->setError('Illegal id '.$id.', it\'s not a valid tracker id for field: '.$ef[$efid]['field_name'].'.'); // @todo: lang
+							$this->setError('Illegal id '.$id.', it\'s not a valid artifact id for field: '.$ef[$efid]['field_name'].'.'); // @todo: lang
+							return false;
+						}
+						$progeny = $this->getProgeny();
+						if (in_array($id, $progeny)) {
+							$this->setError('Illegal id '.$id.', circular dependency for field: '.$ef[$efid]['field_name'].'.'); // @todo: lang
 							return false;
 						}
 					} else {
-						$this->setError('Illegal value '.$id.', only trackers id are allowed for field: '.$ef[$efid]['field_name'].'.'); // @todo: lang
+						$this->setError('Illegal value '.$id.', only artifact id are allowed for field: '.$ef[$efid]['field_name'].'.'); // @todo: lang
 						return false;
 					}
 				}
@@ -2263,7 +2272,7 @@ class Artifact extends FFObject {
 		if (!isset($this->parent)) {
 			$res = db_query_params ('SELECT field_data FROM
 										artifact_extra_field_data
-										NATURAL INNER JOIN artifact_extra_field_list
+										INNER JOIN artifact_extra_field_list USING (extra_field_id)
 									WHERE
 										field_type = $1
 											AND artifact_id = $2',
@@ -2280,6 +2289,22 @@ class Artifact extends FFObject {
 		return $this->parent;
 	}
 
+	function getProgeny() {
+		$return = array();
+		$childrenArr = $this->getChildren();
+		if (is_array($childrenArr)) {
+			$at = $this->ArtifactType;
+			foreach ($childrenArr as $child) {
+				$return[] = $child['artifact_id'];
+				$childObj = new Artifact($at,$child['artifact_id']);
+				$childProgenyArr = $childObj->getProgeny();
+				if (is_array($childProgenyArr)) {
+					$return = array_merge($return, $childProgenyArr);
+				}
+			}
+		}
+		return $return;
+	}
 
 	function getPermalink() {
 		return '/tracker/a_follow.php/'.$this->getID();
diff --git a/src/common/tracker/ArtifactExtraField.class.php b/src/common/tracker/ArtifactExtraField.class.php
index 47615f9..e0d9fbe 100644
--- a/src/common/tracker/ArtifactExtraField.class.php
+++ b/src/common/tracker/ArtifactExtraField.class.php
@@ -848,7 +848,8 @@ class ArtifactExtraField extends FFError {
 		if ($parentId=='100') {
 			return false;
 		}
-		if ($this->getType() != ARTIFACT_EXTRAFIELDTYPE_SELECT &&
+		if ($this->getType() != ARTIFACT_EXTRAFIELDTYPE_STATUS &&
+				$this->getType() != ARTIFACT_EXTRAFIELDTYPE_SELECT &&
 				$this->getType() != ARTIFACT_EXTRAFIELDTYPE_MULTISELECT &&
 				$this->getType() != ARTIFACT_EXTRAFIELDTYPE_RADIO &&
 				$this->getType() != ARTIFACT_EXTRAFIELDTYPE_CHECKBOX) {
@@ -1279,23 +1280,22 @@ class ArtifactExtraField extends FFError {
 	 * @return	array	rules.
 	 */
 	function getAvailableAggregationRules() {
-		$return= array(ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_NO_AGGREGATION => _('Parent value is not depending on children\'s values'));
+		$return = array();
+		$return[ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_NO_AGGREGATION] = _('Parent value is not depending on children\'s values');
 		$type = $this->getType();
 
 		if ($type == ARTIFACT_EXTRAFIELDTYPE_EFFORT) {
-			$return = array_merge($return, array(ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_SUM => _('Parent value is the sum of children\'s values')));
+			$return[ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_SUM] = _('Parent value is the sum of children\'s values');
 		}
 
 		if ($type == ARTIFACT_EXTRAFIELDTYPE_INTEGER) {
-			$return = array_merge($return, array(ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_SUM => _('Parent value is the sum of children\'s values')));
+			$return[ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_SUM] = _('Parent value is the sum of children\'s values');
 		}
 
-// 		if ($type == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
-// 			$return = array_merge($return, array(
-// 													ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_STATUS_CLOSE_RESTRICTED => _('Deny closing the parent, as long as not all children have been closed'),
-// 													ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_STATUS_CLOSE_UPWARDS => _('Close the parent, after the last child has been closed')
-// 								));
-// 		}
+		if ($type == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
+			$return[ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_STATUS_CLOSE_RESTRICTED] = _('Deny closing the parent, as long as not all children have been closed');
+			//$return[ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_STATUS_CLOSE_UPWARDS] = _('Close the parent, after the last child has been closed');
+		}
 
 		if (count($return)==1) {
 			$return = array();
@@ -1313,11 +1313,12 @@ class ArtifactExtraField extends FFError {
 	* @return	array	rules.
 	*/
 	function getAvailableDistributionRules() {
-		$return= array(ARTIFACT_EXTRAFIELD_DISTRIBUTION_RULE_NO_DISTRIBUTION => _('Parent value is not depending on children\'s values'));
+		$return = array();
+		$return[ARTIFACT_EXTRAFIELD_DISTRIBUTION_RULE_NO_DISTRIBUTION] = _('Parent value is not depending on children\'s values');
 		$type = $this->getType();
 
 		if ($type == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
-			$return = array_merge($return, array(ARTIFACT_EXTRAFIELD_DISTRIBUTION_RULE_STATUS_CLOSE_RECURSIVELY => _('Closure of parent involves recursive closure of children')));
+			$return[ARTIFACT_EXTRAFIELD_DISTRIBUTION_RULE_STATUS_CLOSE_RECURSIVELY] = _('Closure of parent involves recursive closure of children');
 		}
 
 		if (count($return)==1) {
diff --git a/src/common/tracker/actions/detail.php b/src/common/tracker/actions/detail.php
index eec9623..ea38857 100644
--- a/src/common/tracker/actions/detail.php
+++ b/src/common/tracker/actions/detail.php
@@ -165,10 +165,11 @@ $nbh = $count? ' ('.$count.')' : '';
 	<li><a href="#tabber-relations"><?php echo _('Relations').$nbr; ?></a></li>
 	<?php } ?>
 	<?php if (forge_get_config('use_artefacts_dependencies')) {
-		$count=$ah->hasChildren();
-		$nbc = $count? ' ('.$count.')' : '';
+		$countC=$ah->hasChildren()?$ah->hasChildren():0;
+		$countP=$ah->hasParent()?1:0;
+		$nbd = $countC+$countP? ' ('.$countP.'/'.$countC.')' : '';
 	?>
-	<li><a href="#tabber-children"><?php echo _('Children').$nbc; ?></a></li>
+	<li><a href="#tabber-dependencies"><?php echo _('Dependencies').$nbd; ?></a></li>
 	<?php } ?>
 	<?php if (forge_get_config('use_object_associations')) {
 		$anf = '';
@@ -250,8 +251,13 @@ if ($group->usesPM()) {
 	<?php echo $ah->showRelations(); ?>
 	</div><?php
 	if (forge_get_config('use_artefacts_dependencies')) { ?>
-		<div id="tabber-children" class="tabbertab">
-			<?php echo $ah->showChildren(); ?>
+		<div id="tabber-dependencies" class="tabbertab">
+			<?php
+				echo '<strong>'._('Parent').'</strong><br>';
+				echo $ah->showParent().'<br>';
+				echo '<strong>'._('Children').'</strong><br>';
+				echo $ah->showChildren();
+			?>
 		</div><?php
 	}
 	if (forge_get_config('use_object_associations')) { ?>
diff --git a/src/common/tracker/actions/mod-limited.php b/src/common/tracker/actions/mod-limited.php
index 7437b01..ec68ede 100644
--- a/src/common/tracker/actions/mod-limited.php
+++ b/src/common/tracker/actions/mod-limited.php
@@ -204,10 +204,11 @@ $nbh = $count? ' ('.$count.')' : '';
 	<li><a href="#tabber-relations"><?php echo _('Relations').$nbr; ?></a></li>
 	<?php } ?>
 	<?php if (forge_get_config('use_artefacts_dependencies')) {
-		$count=$ah->hasChildren();
-		$nbc = $count? ' ('.$count.')' : '';
+		$countC=$ah->hasChildren()?$ah->hasChildren():0;
+		$countP=$ah->hasParent()?1:0;
+		$nbd = $countC+$countP? ' ('.$countP.'/'.$countC.')' : '';
 	?>
-	<li><a href="#tabber-children"><?php echo _('Children').$nbc; ?></a></li>
+	<li><a href="#tabber-dependencies"><?php echo _('Dependencies').$nbd; ?></a></li>
 	<?php } ?>
 	<?php if (forge_get_config('use_object_associations')) {
 		$anf = '';
@@ -275,8 +276,13 @@ echo $ath->renderFiles($group_id, $ah);
 	<?php echo $ah->showRelations(); ?>
 </div><?php
 if (forge_get_config('use_artefacts_dependencies')) { ?>
-	<div id="tabber-children" class="tabbertab">
-		<?php echo $ah->showChildren(); ?>
+	<div id="tabber-dependencies" class="tabbertab">
+		<?php
+			echo '<strong>'._('Parent').'</strong><br>';
+			echo $ah->showParent().'<br>';
+			echo '<strong>'._('Children').'</strong><br>';
+			echo $ah->showChildren();
+		?>
 	</div><?php
 }
 if (forge_get_config('use_object_associations')) { ?>
diff --git a/src/common/tracker/actions/mod.php b/src/common/tracker/actions/mod.php
index 31e2ffd..637b9d4 100644
--- a/src/common/tracker/actions/mod.php
+++ b/src/common/tracker/actions/mod.php
@@ -261,10 +261,11 @@ $nbh = $count? ' ('.$count.')' : '';
 	<li><a href="#tabber-relations"><?php echo _('Relations').$nbr; ?></a></li>
 	<?php } ?>
 	<?php if (forge_get_config('use_artefacts_dependencies')) {
-		$count=$ah->hasChildren();
-		$nbc = $count? ' ('.$count.')' : '';
+		$countC=$ah->hasChildren()?$ah->hasChildren():0;
+		$countP=$ah->hasParent()?1:0;
+		$nbd = $countC+$countP? ' ('.$countP.'/'.$countC.')' : '';
 	?>
-	<li><a href="#tabber-children"><?php echo _('Children').$nbc; ?></a></li>
+	<li><a href="#tabber-dependencies"><?php echo _('Dependencies').$nbd; ?></a></li>
 	<?php } ?>
 	<?php if (forge_get_config('use_object_associations')) {
 		$anf = '';
@@ -353,8 +354,13 @@ echo $ath->renderFiles($group_id, $ah);
 	<?php echo $ah->showRelations(); ?>
 </div><?php
 if (forge_get_config('use_artefacts_dependencies')) { ?>
-	<div id="tabber-children" class="tabbertab">
-		<?php echo $ah->showChildren(); ?>
+	<div id="tabber-dependencies" class="tabbertab">
+		<?php
+			echo '<strong>'._('Parent').'</strong><br>';
+			echo $ah->showParent().'<br>';
+			echo '<strong>'._('Children').'</strong><br>';
+			echo $ah->showChildren();
+		?>
 	</div><?php
 }
 if (forge_get_config('use_object_associations')) { ?>
diff --git a/src/common/tracker/include/ArtifactHtml.class.php b/src/common/tracker/include/ArtifactHtml.class.php
index c5813b7..6bc9c67 100644
--- a/src/common/tracker/include/ArtifactHtml.class.php
+++ b/src/common/tracker/include/ArtifactHtml.class.php
@@ -249,7 +249,7 @@ function hide_edit_button(id) {
 						$arg['class'] = 'artifact_closed';
 					}
 					$return .= '<br/>   ';
-					$return .= util_make_link($url, $text, $arg).' '.util_make_link($url, $arr['summary']).' <i>('._('Parent')._(': ').$arr['field_name'].')</i>';
+					$return .= util_make_link($url, $text, $arg).' '.util_make_link($url, $arr['summary']);
 				}
 			}
 			$return .= '</td>
@@ -258,6 +258,36 @@ function hide_edit_button(id) {
 		}
 		return $return;
 	}
+
+	function showParent() {
+		$parentId = $this->getParent();
+		$return = '';
+		if ($parentId){
+			$parent = artifact_get_object($parentId);
+			$return = '	<table class="fullwidth">
+							<tr>
+								<td colspan="2">';
+			$parentAt = $parent->getArtifactType();
+			if (forge_check_perm('tracker', $parentAt->getID(), 'read')) {
+				$parentG = $parentAt->getGroup();
+				$title = $parentG->getPublicName()._(': ').$parentAt->getName();
+				$return .= '<strong>'.$title.'</strong>';
+				$text = '[#'.$parent->getID().']';
+				$url = '/tracker/?func=detail&aid='.$parent->getID().'&group_id='.$parentG->getID().'&atid='.$parentAt->getID();
+				$arg['title'] = util_html_secure($parent->getSummary());
+				if ($parent->getStatusID() == 2) {
+					$arg['class'] = 'artifact_closed';
+				}
+				$return .= '<br/>   ';
+				$return .= util_make_link($url, $text, $arg).' '.util_make_link($url, $parent->getSummary());
+			}
+			$return .= '</td>
+				</tr>
+				</table>';
+		}
+		return $return;
+	}
+
 }
 
 // Local Variables:
diff --git a/src/common/tracker/include/ArtifactTypeHtml.class.php b/src/common/tracker/include/ArtifactTypeHtml.class.php
index 352f3ff..517e747 100644
--- a/src/common/tracker/include/ArtifactTypeHtml.class.php
+++ b/src/common/tracker/include/ArtifactTypeHtml.class.php
@@ -156,14 +156,14 @@ class ArtifactTypeHtml extends ArtifactType {
 	/**
 	 * renderExtraFields - ???
 	 *
-	 * @param	array	$selected
-	 * @param	bool	$show_100		Display the specific '100' value. Default is false.
-	 * @param	string	$text_100		Label displayed for the '100' value. Default is 'none'
-	 * @param	bool	$show_any
-	 * @param	string	$text_any
-	 * @param	array	$types
-	 * @param	bool	$status_show_100	Force display of the '100' value if needed. Default is false.
-	 * @param	string	$mode			QUERY, DISPLAY, UPDATE, NEW
+	 * @param	array			$selected
+	 * @param	bool			$show_100			Display the specific '100' value. Default is false.
+	 * @param	string			$text_100			Label displayed for the '100' value. Default is 'none'
+	 * @param	bool			$show_any
+	 * @param	string			$text_any
+	 * @param	array			$types
+	 * @param	bool			$status_show_100	Force display of the '100' value if needed. Default is false.
+	 * @param	string			$mode				QUERY, DISPLAY, UPDATE, NEW
 	 */
 	function renderExtraFields($selected = array(),
                                $show_100 = false, $text_100 = 'none',
@@ -172,6 +172,8 @@ class ArtifactTypeHtml extends ArtifactType {
                                $status_show_100 = false,
                                $mode = '') {
 		global $HTML;
+		global $ah;
+
 		if ($mode == 'NEW') {
 			$efarr = $this->getExtraFields($types, false, false);
 		} else {
@@ -304,11 +306,12 @@ class ArtifactTypeHtml extends ArtifactType {
 				$efarr[$i]['show100'] = $status_show_100;
 			}
 
+			$allowed=false;
+
 			if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT ||
 					$efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX ||
 					$efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO ||
 					$efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
-				$allowed=false;
 				if (!is_null($efarr[$i]['parent']) && !empty($efarr[$i]['parent']) && $efarr[$i]['parent']!='100') {
 					$aefParentId = $efarr[$i]['parent'];
 					$selectedElmnts = (isset($selected[$aefParentId]) ? $selected[$aefParentId] : '');
@@ -355,6 +358,34 @@ class ArtifactTypeHtml extends ArtifactType {
 				$str = $this->renderMultiSelectBox($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $efarr[$i]['show100'], $efarr[$i]['show100label'], $allowed, $attrs);
 
 			} elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
+				// parent artifact can't be close if a child is still open
+				if ($mode == 'UPDATE' &&
+						$efarr[$i]['aggregation_rule'] == ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_STATUS_CLOSE_RESTRICTED &&
+						$ah->hasChildren()) {
+					$children = $ah->getChildren();
+					$childOpen = false;
+					foreach ($children as $child) {
+						if ($child['status_id'] == 1) {
+							$childOpen = true;
+							break;
+						}
+					}
+					if ($childOpen) {
+						$aef = new ArtifactExtraField($this, $efarr[$i]['extra_field_id']);
+						$statusArr = $aef->getAvailableValues();
+						$openStatus = array();
+						foreach ($statusArr as $status) {
+							if ($status['status_id']==1) {
+								$openStatus[] = $status['element_id'];
+							}
+						}
+						if ($allowed) {
+							$allowed = array_intersect($allowed, $openStatus);
+						} else {
+							$allowed = $openStatus;
+						}
+					}
+				}
 
 				// Get the allowed values from the workflow.
 				$atw = new ArtifactWorkflow($this, $efarr[$i]['extra_field_id']);
@@ -365,9 +396,15 @@ class ArtifactTypeHtml extends ArtifactType {
 					$selected_node = $selected[$efarr[$i]['extra_field_id']];
 				} else {
 					$selected_node = 100;
+
 				}
 
-				$allowed = $atw->getNextNodes($selected_node);
+				$allowedWF = $atw->getNextNodes($selected_node);
+				if ($allowed) {
+					$allowed = array_intersect($allowed, $allowedWF);
+				} else {
+					$allowed = $allowedWF;
+				}
 				$allowed[] = $selected_node;
 				$str = $this->renderSelect($efarr[$i]['extra_field_id'], $selected_node, $status_show_100, $text_100, $show_any, $text_any, $allowed, $attrs);
 
@@ -1093,7 +1130,6 @@ class ArtifactTypeHtml extends ArtifactType {
 			$keys[$i]=$arr[$i]['element_id'];
 			$vals[$i]=$arr[$i]['element_name'];
 		}
-		$attrs['pattern']='^\d+(\s+\d+)*$';
 		// Convert artifact id to links.
 		$html_contents = preg_replace_callback('/\b(\d+)\b/', create_function('$matches', 'return _artifactid2url($matches[1], \'title\');'), $contents);
 		$edit_contents = $this->renderTextField ($extra_field_id, $contents, $size, $maxlength);
@@ -1112,15 +1148,21 @@ class ArtifactTypeHtml extends ArtifactType {
 	 * @return	string	text area and data.
 	 */
 	function renderParentField($extra_field_id, $contents, $size, $maxlength, $attrs = array()) {
+		global $ah;
 		$arr = $this->getExtraFieldElements($extra_field_id);
 		for ($i=0; $i<count($arr); $i++) {
 			$keys[$i]=$arr[$i]['element_id'];
 			$vals[$i]=$arr[$i]['element_name'];
 		}
-		$attrs['pattern']='^\d*$';
+		$attrsTxt = array();
+		if (is_object($ah)) {
+			$attrsTxt['pattern']='^(?!'.$ah->getID().'$)\d*$';
+		} else {
+			$attrsTxt['pattern']='^\d*$';
+		}
 		// Convert artifact id to links.
 		$html_contents = preg_replace_callback('/\b(\d+)\b/', create_function('$matches', 'return _artifactid2url($matches[1], \'title\');'), $contents);
-		$edit_contents = $this->renderTextField ($extra_field_id, $contents, $size, $maxlength);
+		$edit_contents = $this->renderTextField ($extra_field_id, $contents, $size, $maxlength, $attrsTxt);
 		return html_e('div',array_merge(array('id'=>'edit'.$extra_field_id, 'style'=>'display: none', 'title'=>_('Tip: Enter a space-separated list of artifact ids ([#NNN] also accepted)')), $attrs), $edit_contents)
 		.html_e('div',array_merge(array('id'=>'show'.$extra_field_id, 'style'=>'display: block'), $attrs), $html_contents);
 	}
diff --git a/src/common/widget/Widget_TrackerComment.class.php b/src/common/widget/Widget_TrackerComment.class.php
index 6f4ebbb..ad11ddc 100644
--- a/src/common/widget/Widget_TrackerComment.class.php
+++ b/src/common/widget/Widget_TrackerComment.class.php
@@ -96,12 +96,13 @@ class Widget_TrackerComment extends Widget {
 				$elementsLi[] = array('content' => util_make_link('#tabber-relations', _('Relations').$nbr, false, true));
 			}
 			if (forge_get_config('use_artefacts_dependencies')) {
-				$tabTitle = _('Children');
-				$nbChildren = $ah->hasChildren();
-				if ($nbChildren) {
-					$tabTitle .= ' ('.$nbChildren.')';
+				$tabTitle = _('Dependencies');
+				$nbChildren = $ah->hasChildren()?$ah->hasChildren():0;
+				$nbParent = $ah->hasParent()?1:0;
+				if ($nbChildren+$nbParent) {
+					$tabTitle .= ' ('.$nbParent.'/'.$nbChildren.')';
 				}
-				$elementsLi[] = array('content' => util_make_link('#tabber-children', $tabTitle, false, true));
+				$elementsLi[] = array('content' => util_make_link('#tabber-dependencies', $tabTitle, false, true));
 			}
 			if (forge_get_config('use_object_associations')) {
 				$tabTitle = _('Associations');
@@ -170,7 +171,10 @@ class Widget_TrackerComment extends Widget {
 			$tabberContent .= html_e('div', array('id' => 'tabber-relations', 'class' => 'tabbertab'),
 						$ah->showRelations());
 			if (forge_get_config('use_artefacts_dependencies')) {
-				$tabberContent .= html_e('div', array('id' => 'tabber-children', 'class' => 'tabbertab'),
+				$tabberContent .= html_e('div', array('id' => 'tabber-dependencies', 'class' => 'tabbertab'),
+						html_e('strong',array(),_('Parent')).html_e('br').
+						$ah->showParent().html_e('br').
+						html_e('strong',array(),_('Children')).html_e('br').
 						$ah->showChildren());
 			}
 			if (forge_get_config('use_object_associations')) {
diff --git a/src/common/widget/Widget_TrackerContent.class.php b/src/common/widget/Widget_TrackerContent.class.php
index ef0203e..b3cf017 100644
--- a/src/common/widget/Widget_TrackerContent.class.php
+++ b/src/common/widget/Widget_TrackerContent.class.php
@@ -523,13 +523,47 @@ EOS;
 										}
 										$cellContent .= $value;
 									} else {
+										// parent artifact can't be close if a child is still open
+										if ( $func != "add" &&
+												$extrafieldObject->getAggregationRule() == ARTIFACT_EXTRAFIELD_AGGREGATION_RULE_STATUS_CLOSE_RESTRICTED &&
+												$ah->hasChildren()) {
+											$children = $ah->getChildren();
+											$childOpen = false;
+											foreach ($children as $child) {
+												if ($child['status_id'] == 1) {
+													$childOpen = true;
+													break;
+												}
+											}
+											if ($childOpen) {
+												$extrafieldObject = new ArtifactExtraField($ath, $keys[0]);
+												//$aef = new ArtifactExtraField($this, $efarr[$i]['extra_field_id']);
+												$statusArr = $extrafieldObject->getAvailableValues();
+												$openStatus = array();
+												foreach ($statusArr as $status) {
+													if ($child['status_id'] == 1) {
+														$openStatus[] = $status['element_id'];
+													}
+												}
+												if ($allowed) {
+													$allowed = array_intersect($allowed, $openStatus);
+												} else {
+													$allowed = $openStatus;
+												}
+											}
+										}
 										$atw = new ArtifactWorkflow($ath, $keys[0]);
 										// Special treatment for the initial step (Submit). In this case, the initial value is the first value.
 										if (!$value) {
 											$value = 100;
 										}
-										$allowed = $atw->getNextNodes($value);
-										$allowed[] = $value;
+										$allowedWF = $atw->getNextNodes($value);
+										if ($allowed) {
+											$allowed = array_intersect($allowed, $allowedWF);
+										} else {
+											$allowed = $allowedWF;
+										}
+										$allowed[] = $selected_node;
 										$cellContent .= $ath->renderSelect($keys[0], $value, false, $extrafieldObject->getShow100label(), false, false, $allowed, $attrs);
 									}
 									break;

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

Summary of changes:
 src/common/tracker/Artifact.class.php              | 33 +++++++++--
 src/common/tracker/ArtifactExtraField.class.php    | 25 ++++----
 src/common/tracker/actions/detail.php              | 16 +++--
 src/common/tracker/actions/mod-limited.php         | 16 +++--
 src/common/tracker/actions/mod.php                 | 16 +++--
 src/common/tracker/include/ArtifactHtml.class.php  | 32 +++++++++-
 .../tracker/include/ArtifactTypeHtml.class.php     | 68 +++++++++++++++++-----
 src/common/widget/Widget_TrackerComment.class.php  | 16 +++--
 src/common/widget/Widget_TrackerContent.class.php  | 38 +++++++++++-
 9 files changed, 207 insertions(+), 53 deletions(-)


hooks/post-receive
-- 
FusionForge



More information about the Fusionforge-commits mailing list