52a53
> our %seen;
121a123
> 			$seen{"$web.$form"} = 1; # can't include/isa itself
153a156
> 	%seen = ();
262,274c265,300
<             my $fieldDef = $this->createField(
<                 $type,
<                 name          => $name,
<                 title         => $title,
<                 size          => $size,
<                 value         => $vals,
<                 tooltip       => $tooltip,
<                 attributes    => $attributes,
<                 definingTopic => $definingTopic,
<                 web           => $this->web(),
<                 topic         => $this->topic()
<             );
<             push( @fields, $fieldDef );
---
>             if ($type =~ /isa/) {
> 				$this->{isa} = $vals; # only the last isa declaration is valid
> 			} elsif ($type =~ /include/) {
> 				my ($t, $w);
> 				my $web = $this->{web};
> 				foreach my $include (split(/\s*,\s*/,$vals)) {
> 					if ($include =~ m#^(.*)[\./](.*?)$#) { # allow to pull a form from a specific web
> 						$t = $2;
> 						$w = $1;
> 					} else {
> 						$t = $include;
> 						$w = $web;
> 					}
> 					# can't isa/include itself
> 					next if $seen{"$w.$t"};
> 					$seen{"$w.$t"} = 1;
> 					my $form = new Foswiki::Form($this->session(), $w, $t);
> 					next unless $form;
> 					push( @fields, @{$form->{fields}} );
> 					
> 					$this->{mandatoryFieldsPresent} ||= $form->{mandatoryFieldsPresent};
> 				}
> 			} else {
> 				my $fieldDef = $this->createField(
> 					$type,
> 					name          => $name,
> 					title         => $title,
> 					size          => $size,
> 					value         => $vals,
> 					tooltip       => $tooltip,
> 					attributes    => $attributes,
> 					definingTopic => $definingTopic,
> 					web           => $this->web(),
> 					topic         => $this->topic()
> 				);
> 				push( @fields, $fieldDef );
276c302,303
<             $this->{mandatoryFieldsPresent} ||= $fieldDef->isMandatory();
---
> 				$this->{mandatoryFieldsPresent} ||= $fieldDef->isMandatory();
> 			}
281a309,346
> 	if ($this->{isa}) {
> 		my ($t, $w);
> 		my @isarray = ();
> 		# left-to-right defines the structure of the resulting form
> 		# right-to-left defines the priority of the entries
> 		foreach my $isa (reverse split(/\s*,\s*/,$this->{isa})) {
> 			if ($isa =~ m#^(.*)[\./](.*?)$#) { # allow to pull a form from a specific web
> 				$t = $2;
> 				$w = $1;
> 			} else {
> 				$t = $isa;
> 				$w = $this->web();
> 			}
> 			# can't isa/include itself
> 			next if $seen{"$w.$t"};
> 			$seen{"$w.$t"} = 1;
> 			my $form = new Foswiki::Form($this->session(), $w, $t);
> 			next unless $form;
> 			my @f = @{$form->{fields}};
> 			# merge like this...
> 			foreach my $fieldDef (@fields) {
> 				putKeyedOrPush(\@f, $fieldDef);
> 			}
> 			@fields = @f;
> 			unless ($this->{mandatoryFieldsPresent}) {
> 				foreach my $fieldDef (@{$form->{fields}}) {
> 					if ($fieldDef->isMandatory()) {
> 						$this->{mandatoryFieldsPresent} = 1;
> 						last;
> 					}
> 				}
> 			}
> 			# keep a record of the expanded isa path
> 			$isa .= ','.$form->{isa} if $form->{isa};
> 			push (@isarray, $isa);
> 		}
> 		$this->{isa} = join(',',@isarray);
> 	}
285a351,366
> sub putKeyedOrPush {
>     my( $data, $args ) = @_;
> 
>     if( $data ) {
>         my $keyName = $args->{name};
>         my $i = scalar( @$data );
>         while( $keyName && $i-- ) {
>             if( $data->[$i]->{name} eq $keyName ) {
>                 $data->[$i] = $args;
> 				return;
> 			}
>         }
>         push @$data, $args;
>     }
> }
> 
