--- rat/lonratedt.pm 2006/09/12 22:13:12 1.83 +++ rat/lonratedt.pm 2006/11/02 21:03:28 1.84 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Edit Handler for RAT Maps # -# $Id: lonratedt.pm,v 1.83 2006/09/12 22:13:12 albertel Exp $ +# $Id: lonratedt.pm,v 1.84 2006/11/02 21:03:28 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -171,239 +171,12 @@ use Apache::lonratsrv; use Apache::lonsequence; use Apache::loncommon; use Apache::lonlocal; +use LONCAPA::map(); use File::Copy; use lib '/home/httpd/lib/perl/'; use LONCAPA; -use vars qw(@order @resources @resparms @zombies); - - -# Mapread read maps into global arrays @links and @resources, determines status -# sets @order - pointer to resources in right order -# sets @resources - array with the resources with correct idx -# -sub mapread { - my $fn=shift; - - my @links; - undef @links; - undef @resources; - undef @order; - undef @resparms; - undef @zombies; - - @resources=(''); - @order=(); - @resparms=(); - @zombies=(); - - my ($outtext,$errtext)=&Apache::lonratsrv::loadmap($fn,''); - if ($errtext) { return ($errtext,2); } - -# -------------------------------------------------------------------- Read map - foreach (split(/\<\&\>/,$outtext)) { - my ($command,$number,$content)=split(/\<\:\>/,$_); - if ($command eq 'objcont') { - my ($title,$src,$ext,$type)=split(/\:/,$content); - if ($ext eq 'cond') { next; } - if ($type ne 'zombie') { - $resources[$number]=$content; - } else { - $zombies[$number]=$content; - } - } - if ($command eq 'objlinks') { - $links[$number]=$content; - } - if ($command eq 'objparms') { - if ($resparms[$number]) { - $resparms[$number].='&&&'.$content; - } else { - $resparms[$number]=$content; - } - } - } -# ------------------------------------------------------- Is this a linear map? - my @starters=(); - my @endings=(); - undef @starters; - undef @endings; - - foreach (@links) { - if (defined($_)) { - my ($start,$end,$cond)=split(/\:/,$_); - if ((defined($starters[$start])) || (defined($endings[$end]))) { - return - (&mt('Map has branchings. Use advanced editor.'),1); - } - $starters[$start]=1; - $endings[$end]=1; - if ($cond) { - return - (&mt('Map has conditions. Use advanced editor.'),1); - } - } - - } - for (my $i=1; $i<=$#resources; $i++) { - if (defined($resources[$i])) { - unless (($starters[$i]) || ($endings[$i])) { - return - (&mt('Map has unconnected resources. Use advanced editor.'),1); - } - } - } -# ---------------------------------------------- Did we just read an empty map? - if ($#resources<1) { - undef $resources[0]; - $resources[1]=':::start'; - $resources[2]=':::finish'; - } -# -------------------------------------------------- This is a linear map, sort - - my $startidx=0; - my $endidx=0; - for (my $i=0; $i<=$#resources; $i++) { - if (defined($resources[$i])) { - my ($title,$url,$ext,$type)=split(/\:/,$resources[$i]); - if ($type eq 'start') { $startidx=$i; } - if ($type eq 'finish') { $endidx=$i; } - } - } - my $k=0; - my $currentidx=$startidx; - $order[$k]=$currentidx; - for (my $i=0; $i<=$#resources; $i++) { - foreach (@links) { - my ($start,$end)=split(/\:/,$_); - if ($start==$currentidx) { - $currentidx=$end; - $k++; - $order[$k]=$currentidx; - last; - } - } - if ($currentidx==$endidx) { last; } - } - return $errtext; -} - -# ---------------------------------------------- Read a map as well as possible -# Also used by the sequence handler -# Call lonsequence::attemptread to read from resource space -# -sub attemptread { - my $fn=shift; - - my @links; - undef @links; - my @theseres; - undef @theseres; - - my ($outtext,$errtext)=&Apache::lonratsrv::loadmap($fn,''); - if ($errtext) { return @theseres } - -# -------------------------------------------------------------------- Read map - foreach (split(/\<\&\>/,$outtext)) { - my ($command,$number,$content)=split(/\<\:\>/,$_); - if ($command eq 'objcont') { - my ($title,$src,$ext,$type)=split(/\:/,$content); - unless ($type eq 'zombie') { - $theseres[$number]=$content; - } - } - if ($command eq 'objlinks') { - $links[$number]=$content; - } - } - -# --------------------------------------------------------------- Sort, sort of - - my @objsort=(); - undef @objsort; - - my @data1=(); - my @data2=(); - undef @data1; - undef @data2; - - my $k; - my $kj; - my $j; - my $ij; - - for ($k=1;$k<=$#theseres;$k++) { - if (defined($theseres[$k])) { - $objsort[$#objsort+1]=$k; - } - } - - for ($k=1;$k<=$#links;$k++) { - if (defined($links[$k])) { - @data1=split(/\:/,$links[$k]); - $kj=-1; - for (my $j=0;$j<=$#objsort;$j++) { - if ((split(/\:/,$objsort[$j]))[0]==$data1[0]) { - $kj=$j; - } - } - if ($kj!=-1) { $objsort[$kj].=':'.$data1[1]; } - } - } - for ($k=0;$k<=$#objsort;$k++) { - for ($j=0;$j<=$#objsort;$j++) { - if ($k!=$j) { - @data1=split(/\:/,$objsort[$k]); - @data2=split(/\:/,$objsort[$j]); - my $dol=$#data1+1; - my $dtl=$#data2+1; - if ($dol+$dtl<1000) { - for ($kj=1;$kj<$dol;$kj++) { - if ($data1[$kj]==$data2[0]) { - for ($ij=1;$ij<$dtl;$ij++) { - $data1[$#data1+1]=$data2[$ij]; - } - } - } - for ($kj=1;$kj<$dtl;$kj++) { - if ($data2[$kj]==$data1[0]) { - for ($ij=1;$ij<$dol;$ij++) { - $data2[$#data2+1]=$data1[$ij]; - } - } - } - $objsort[$k]=join(':',@data1); - $objsort[$j]=join(':',@data2); - } - } - } - } -# ---------------------------------------------------------------- Now sort out - - @objsort=sort { - my @data1=split(/\:/,$a); - my @data2=split(/\:/,$b); - my $rvalue=0; - my $k; - for ($k=1;$k<=$#data1;$k++) { - if ($data1[$k]==$data2[0]) { $rvalue--; } - } - for ($k=1;$k<=$#data2;$k++) { - if ($data2[$k]==$data1[0]) { $rvalue++; } - } - if ($rvalue==0) { $rvalue=$#data2-$#data1; } - $rvalue; - } @objsort; - - my @outres=(); - undef @outres; - - for ($k=0;$k<=$#objsort;$k++) { - $outres[$k]=$theseres[(split(/\:/,$objsort[$k]))[0]]; - } - return @outres; -} # --------------------------------------------------------- Build up RAT screen sub ratedt { @@ -455,197 +228,6 @@ sub buttons { return $output.'
'; } -# ------------------------------------- Revive zombie idx or get unused number - -sub getresidx { - my $url=shift; - my $max=1+($#resources>$#zombies?$#resources:$#zombies); - unless ($url) { return $max; } - for (my $i=0; $i<=$#zombies; $i++) { - my ($title,$src,$ext,$type)=split(/\:/,$zombies[$i]); - if ($src eq $url) { - undef $zombies[$i]; - return $i; - } - } - return $max; -} - -# --------------------------------------------------------------- Make a zombie - -sub makezombie { - my $idx=shift; - my ($name,$url,$ext)=split(/\:/,$resources[$idx]); - my $now=time; - $zombies[$idx]=$name. - ' [('.$now.','.$env{'user.name'}.','.$env{'user.domain'}.')]:'. - $url.':'.$ext.':zombie'; -} - -# ----------------------------------------------------------- Paste into target -# modifies @order, @resources - -sub pastetarget { - my ($after,@which)=@_; - my @insertorder=(); - foreach (@which) { - if (defined($_)) { - my ($name,$url)=split(/\=/,$_); - $name=&unescape($name); - $url=&unescape($url); - if ($url) { - my $idx=&getresidx($url); - $insertorder[$#insertorder+1]=$idx; - my $ext='false'; - if ($url=~/^http\:\/\//) { $ext='true'; } - $url=~s/\:/\:/g; - $name=~s/\:/\:/g; - $resources[$idx]=$name.':'.$url.':'.$ext.':normal:res'; - } - } - } - my @oldorder=splice(@order,$after); - @order=(@order,@insertorder,@oldorder); -} - -# ------------------------------------------------ Get start and finish correct -# modifies @resources - -sub startfinish { -# Remove all start and finish - foreach (@order) { - my ($name,$url,$ext)=split(/\:/,$resources[$_]); - if ($url=~/http\&colon\:\/\//) { $ext='true'; } - $resources[$_]=$name.':'.$url.':'.$ext.':normal:res'; - } -# Garbage collection - my $stillchange=1; - while (($#order>1) && ($stillchange)) { - $stillchange=0; - for (my $i=0;$i<=$#order;$i++) { - my ($name,$url,$ext)=split(/\:/,$resources[$order[$i]]); - unless ($url) { -# Take out empty resource - for (my $j=$i+1;$j<=$#order;$j++) { - $order[$j-1]=$order[$j]; - } - $#order--; - $stillchange=1; - last; - } - } - } -# Put in a start resource - my ($name,$url,$ext)=split(/\:/,$resources[$order[0]]); - $resources[$order[0]]=$name.':'.$url.':'.$ext.':start:res'; -# Make sure this has at least start and finish - if ($#order==0) { - $resources[&getresidx()]='::false'; - $order[1]=$#resources; - } -# Make the last one a finish resource - ($name,$url,$ext)=split(/\:/,$resources[$order[$#order]]); - $resources[$order[$#order]]=$name.':'.$url.':'.$ext.':finish:res'; -} - -# ------------------------------------------------------------------- Store map - -sub storemap { - my $realfn=shift; - my $fn=$realfn; -# unless this is forced to work from the original file, use a temporary file -# instead - unless (shift) { - $fn=$realfn.'.tmp'; - unless (-e $fn) { - copy($realfn,$fn); - } - } -# store data either into tmp or real file - &startfinish(); - my $output='graphdef<:>no'; - my $k=1; - for (my $i=0; $i<=$#order; $i++) { - if (defined($resources[$order[$i]])) { - $output.='<&>objcont<:>'.$order[$i].'<:>'.$resources[$order[$i]]; - } - if (defined($resparms[$order[$i]])) { - foreach (split('&&&',$resparms[$order[$i]])) { - if ($_) { - $output.='<&>objparms<:>'.$order[$i].'<:>'.$_; - } - } - } - if (defined($order[$i+1])) { - if (defined($resources[$order[$i+1]])) { - $output.='<&>objlinks<:>'.$k.'<:>'. - $order[$i].':'.$order[$i+1].':0'; - $k++; - } - } - } - for (my $i=0; $i<=$#zombies; $i++) { - if (defined($zombies[$i])) { - $output.='<&>objcont<:>'.$i.'<:>'.$zombies[$i]; - } - } - $output=~s/http\&colon\;\/\///g; - $env{'form.output'}=$output; - return - &Apache::lonratsrv::loadmap($fn,&Apache::lonratsrv::savemap($fn,'')); -} - -# ------------------------------------------ Store and get parameters in global - -sub storeparameter { - my ($to,$name,$value,$ptype)=@_; - my $newentry=''; - my $nametype=''; - foreach (split('&&&',$resparms[$to])) { - my ($thistype,$thisname,$thisvalue)=split('___',$_); - if ($thisname) { - unless ($thisname eq $name) { - $newentry.=$_.'&&&'; - } else { - $nametype=$thistype; - } - } - } - unless ($ptype) { $ptype=$nametype; } - unless ($ptype) { $ptype='string'; } - $newentry.=$ptype.'___'.$name.'___'.$value; - $resparms[$to]=$newentry; -} - -sub delparameter { - my ($to,$name)=@_; - my $newentry=''; - my $nametype=''; - foreach (split('&&&',$resparms[$to])) { - my ($thistype,$thisname,$thisvalue)=split('___',$_); - if ($thisname) { - unless ($thisname eq $name) { - $newentry.=$_.'&&&'; - } - } - } - $resparms[$to]=$newentry; -} - -sub getparameter { - my ($to,$name)=@_; - my $value=undef; - my $ptype=undef; - foreach (split('&&&',$resparms[$to])) { - my ($thistype,$thisname,$thisvalue)=split('___',$_); - if ($thisname eq $name) { - $value=$thisvalue; - $ptype=$thistype; - } - } - return ($value,$ptype); -} - # ----------------------------------------------------------------- Edit script sub editscript { my $mode=shift; @@ -776,7 +358,7 @@ sub smpedt { copy($tmpfn,&Apache::lonnet::filelocation('',$url)); unlink($tmpfn); my ($errtext,$fatal)= - &mapread(&Apache::lonnet::filelocation('',$url),''); + &LONCAPA::map::mapread(&Apache::lonnet::filelocation('',$url),''); unless ($fatal) { $targetmsg=''.&mt('Saved.').'
'; } else { @@ -787,12 +369,12 @@ sub smpedt { $targetmsg=''.&mt('Reverted.').'
'; unlink($tmpfn); my ($errtext,$fatal)= - &mapread(&Apache::lonnet::filelocation('',$url),''); + &LONCAPA::map::mapread(&Apache::lonnet::filelocation('',$url),''); } if (-e $tmpfn) { $targetmsg= ''.&mt('You are working with an unsaved version of your map.').'
'; - my ($errtext,$fatal)=&mapread($tmpfn,''); + my ($errtext,$fatal)=&LONCAPA::map::mapread($tmpfn,''); } # ---------------------------------------------------------- Process form input @@ -895,10 +477,10 @@ sub smpedt { if (defined($targetselect[-1])) { $lastsel=$targetselect[-1]; } else { - $lastsel=$#order+1; + $lastsel=$#LONCAPA::map::order+1; } - &pastetarget($lastsel,split(/\&/,$env{'form.importdetail'})); - &storemap(&Apache::lonnet::filelocation('',$url)); + &LONCAPA::map::pastetarget($lastsel,split(/\&/,$env{'form.importdetail'})); + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); # ------------------------------------------------------------------------- Cut } elsif (($env{'form.cut'}) || ($env{'form.copy'})) { $importdetail=''; @@ -920,7 +502,7 @@ sub smpedt { } foreach (@targetselect) { - my ($name,$url)=split(/\:/,$resources[$order[$_-1]]); + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$LONCAPA::map::order[$_-1]]); if ($url) { $importdetail.='&'.&escape($name).'='. &escape($url); @@ -938,19 +520,19 @@ sub smpedt { if ($env{'form.cut'}) { my @neworder=(); - for (my $i=0;$i<=$#order;$i++) { + for (my $i=0;$i<=$#LONCAPA::map::order;$i++) { my $include=1; foreach (@targetselect) { if ($_-1==$i) { $include=0; } } if ($include) { - $neworder[$#neworder+1]=$order[$i]; + $neworder[$#neworder+1]=$LONCAPA::map::order[$i]; } else { - &makezombie($order[$i]); + &LONCAPA::map::makezombie($LONCAPA::map::order[$i]); } } - @order=@neworder; - &storemap(&Apache::lonnet::filelocation('',$url)); + @LONCAPA::map::order=@neworder; + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); } # ----------------------------------------------------------------------- Paste @@ -959,43 +541,43 @@ sub smpedt { if (defined($targetselect[-1])) { $lastsel=$targetselect[-1]; } else { - $lastsel=$#order+1; + $lastsel=$#LONCAPA::map::order+1; } my @newsequence; my @curimport=split(/\&/,$env{'form.curimpdetail'}); foreach (@importselect) { $newsequence[$#newsequence+1]=$curimport[$_]; } - &pastetarget($lastsel,@newsequence); - &storemap(&Apache::lonnet::filelocation('',$url)); + &LONCAPA::map::pastetarget($lastsel,@newsequence); + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); # -------------------------------------------------------------------- Move up } elsif ($env{'form.moveup'}) { foreach (sort @targetselect) { if ($_-1>0) { - my $movethis=$order[$_-1]; - $order[$_-1]=$order[$_-2]; - $order[$_-2]=$movethis; + my $movethis=$LONCAPA::map::order[$_-1]; + $LONCAPA::map::order[$_-1]=$LONCAPA::map::order[$_-2]; + $LONCAPA::map::order[$_-2]=$movethis; } } - &storemap(&Apache::lonnet::filelocation('',$url)); + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); # ------------------------------------------------------------------ Move down } elsif ($env{'form.movedown'}) { foreach (reverse sort @targetselect) { - if ($_-1<$#order) { - my $movethis=$order[$_-1]; - $order[$_-1]=$order[$_]; - $order[$_]=$movethis; + if ($_-1<$#LONCAPA::map::order) { + my $movethis=$LONCAPA::map::order[$_-1]; + $LONCAPA::map::order[$_-1]=$LONCAPA::map::order[$_]; + $LONCAPA::map::order[$_]=$movethis; } } - &storemap(&Apache::lonnet::filelocation('',$url)); + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); # --------------------------------------------------------------------- Rename } elsif ($env{'form.renameres'}) { - my $residx=$Apache::lonratedt::order[$env{'form.renameidx'}-1]; - my ($name,@resrest)=split(/\:/,$Apache::lonratedt::resources[$residx]); + my $residx=$LONCAPA::map::order[$env{'form.renameidx'}-1]; + my ($name,@resrest)=split(/\:/,$LONCAPA::map::resources[$residx]); $name=$env{'form.renametitle'}; $name=~s/\:/\&colon\;/g; - $Apache::lonratedt::resources[$residx]=$name.':'.join(':',@resrest); - &storemap(&Apache::lonnet::filelocation('',$url)); + $LONCAPA::map::resources[$residx]=$name.':'.join(':',@resrest); + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); } # ------------------------------------------------------------ Assemble windows @@ -1020,7 +602,7 @@ sub smpedt { my $targetwindow= ''. join("\n",map { - my ($name,$url)=split(/\:/,$resources[$_]); + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$_]); unless ($name) { $name=(split(/\//,$url))[-1]; } unless ($name) { $name='EMPTY'; } $targetdetail.='&'.&escape($name).'='. @@ -1028,7 +610,7 @@ sub smpedt { $idx++; $name=~s/\:/\:/g; ''; - } @order); + } @LONCAPA::map::order); # ----------------------------------------------------- Start simple RAT screen my $editscript=&editscript('simple'); @@ -1216,7 +798,7 @@ sub viewmap { ''.&mt('Link to resource in Construction Space').''. ''); my @backgroundColors = ("#FFFFFF", "#F6F6F6"); - foreach (&attemptread(&Apache::lonnet::filelocation('',$url))) { + foreach (&LONCAPA::map::attemptread(&Apache::lonnet::filelocation('',$url))) { if (defined($_)) { $idx++; my ($title,$url,$cond)=split(/\:/,$_); @@ -1293,7 +875,7 @@ sub handler { my $fatal=0; # -------------------------------------------------------------------- Load map - ($errtext,$fatal)=&mapread($fn,$errtext); + ($errtext,$fatal)=&LONCAPA::map::mapread($fn,$errtext); if ($fatal==1) { $adv=1; }