--- loncom/interface/londocs.pm	2006/11/30 23:34:38	1.262
+++ loncom/interface/londocs.pm	2007/05/02 01:33:48	1.272
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Documents
 #
-# $Id: londocs.pm,v 1.262 2006/11/30 23:34:38 banghart Exp $
+# $Id: londocs.pm,v 1.272 2007/05/02 01:33:48 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -42,7 +42,7 @@ use HTML::Entities;
 use GDBM_File;
 use Apache::lonlocal;
 use Cwd;
-use LONCAPA;
+use LONCAPA qw(:DEFAULT :match);
 
 my $iconpath;
 
@@ -99,7 +99,7 @@ sub authorhosts {
 		$ca=$env{'user.name'};
 		$cd=$env{'user.domain'};
 	    } else {
-		($cd,$ca)=($realm=~/^\/(\w+)\/(\w+)$/);
+		($cd,$ca)=($realm=~/^\/($match_domain)\/($match_username)$/);
 	    }
 	    my $allowed=0;
 	    my $myhome=&Apache::lonnet::homeserver($ca,$cd);
@@ -235,7 +235,6 @@ sub dumpcourse {
 	    my ($ext)=($_=~/\.(\w+)$/);
 	    my $title=$hash{'title_'.$hash{
 		'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$_}};
-	    $title=~s/:/:/g;
 	    $r->print('<td>'.($title?$title:'&nbsp;').'</td>');
 	    if (!$title) {
 		$title=$_;
@@ -366,7 +365,7 @@ sub exportcourse {
             if (ref($curRes)) {
                 my $symb = $curRes->symb();
                 my $ressymb = $symb;
-                if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) {
+                if ($ressymb =~ m|adm/($match_domain)/($match_username)/(\d+)/bulletinboard$|) {
                     unless ($ressymb =~ m|adm/wrapper/adm|) {
                         $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';
                     }
@@ -613,7 +612,7 @@ sub build_package {
                         if (grep/^$count$/,@$discussions) {
                             my $ressymb = $symb;
                             my $mode;
-                            if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) {
+                            if ($ressymb =~ m|adm/($match_domain)/($match_username)/(\d+)/bulletinboard$|) {
                                 unless ($ressymb =~ m|adm/wrapper/adm|) {
                                     $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';
                                 }
@@ -698,7 +697,7 @@ sub process_content {
         }
     } elsif ($symb =~ m-lib/templates/examupload\.problem$-) {
         $content_type = 'examupload';
-    } elsif ($symb =~ m-adm/(\w+)/(\w+)/(\d+)/bulletinboard$-) {
+    } elsif ($symb =~ m-adm/($match_domain)/($match_username)/(\d+)/bulletinboard$-) {
         $content_type = 'bulletinboard';
         my $contents =  &Apache::imsexport::templatedpage($content_type,$3,$count,\@uploads,$1,$2);
         if ($contents) {
@@ -913,7 +912,7 @@ sub group_import {
     while (@_) {
 	my $name = shift;
 	my $url = shift;
-        if (($url =~ m#^/uploaded/$coursedom/$coursenum/(default_\d+\.)(page|sequence)$#) && ($caller eq 'londocs')) {
+        if (($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) && ($caller eq 'londocs')) {
             my $errtext = '';
             my $fatal = 0;
             my $newmapstr = '<map>'."\n".
@@ -936,9 +935,9 @@ sub group_import {
 	    my $idx = &LONCAPA::map::getresidx($url);
 	    $LONCAPA::map::order[$#LONCAPA::map::order+1]=$idx;
 	    my $ext = 'false';
-	    if ($url=~/^http:\/\// || $url=~/^https:\/\//) { $ext = 'true'; }
-	    $url =~ s/:/\&colon;/g;
-	    $name =~ s/:/\&colon;/g;
+	    if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; }
+	    $url  =~ &LONCAPA::map::qtunescape($url);
+	    $name =~ &LONCAPA::map::qtunescape($name);
 	    $LONCAPA::map::resources[$idx] = 
 		join ':', ($name, $url, $ext, 'normal', 'res');
 	}
@@ -988,7 +987,8 @@ sub breadcrumbs {
 		      {'href'=>$url.$cpinfo,
 		       'title'=>$name,
 		       'text'=>'<font size="+1">'.
-			   $name.'</font>'
+			   $name.'</font>',
+		       'no_mt'=>1,
 		       });
 	$plain.=$name.' &gt; ';
     }
@@ -1309,18 +1309,16 @@ sub editor {
 		    $url=~/^(.+)\.(\w+)$/;
 		    my $newurl=$1.$newid.'.'.$2;
 		    my $storefn=$newurl;
-                    $storefn=~s/^\/\w+\/\w+\/\w+\///;
+                    $storefn=~s{^/\w+/$match_domain/$match_username/}{};
 		    &Apache::lonclonecourse::writefile
 			($env{'request.course.id'},$storefn,
 			 &Apache::lonnet::getfile($url));
 		    $url=$newurl;
 		}
-		$title=~s/\</\&lt\;/g;
-		$title=~s/\>/\&gt\;/g;
-		$title=~s/\:/\&colon;/g;
+		$title = &LONCAPA::map::qtunescape($title);
 		my $ext='false';
 		if ($url=~/^http\:\/\//) { $ext='true'; }
-		$url=~s/\:/\&colon;/g;
+		$url   = &LONCAPA::map::qtunescape($url);
 # Now insert the URL at the bottom
                 my $newidx=&LONCAPA::map::getresidx($url);
 		$LONCAPA::map::resources[$newidx]=
@@ -1372,19 +1370,14 @@ sub editor {
                     my $ratstr = $LONCAPA::map::resources[$LONCAPA::map::order[$idx]];
                     my ($rtitle,@rrest)=split(/\:/,
                        $LONCAPA::map::resources[$LONCAPA::map::order[$idx]]);
-                    my $comment=
-                     &HTML::Entities::decode($env{'form.title'});
-                    $comment=~s/\</\&lt\;/g;
-                    $comment=~s/\>/\&gt\;/g;
-                    $comment=~s/\:/\&colon;/g;
+                    my $comment=$env{'form.title'};
+                    $comment = &LONCAPA::map::qtunescape($comment);
 		    if ($comment=~/\S/) {
 			$LONCAPA::map::resources[$LONCAPA::map::order[$idx]]=
 			    $comment.':'.join(':',@rrest);
 		    }
 # Devalidate title cache
-                    my $renamed_url=$rrest[0];
-# Has the &colon;-escaping
-                    $renamed_url=~s/\&colon\;/\:/g;
+                    my $renamed_url=&LONCAPA::map::qtescape($rrest[0]);
 		    &Apache::lonnet::devalidate_title_cache($renamed_url);
                 }
 # Store the changed version
@@ -1538,11 +1531,9 @@ sub process_file_upload {
 						$codebase);
         my $ext='false';
         if ($url=~/^http\:\/\//) { $ext='true'; }
-        $url=~s/\:/\&colon;/g;
+	$url     = &LONCAPA::map::qtunescape($url);
         my $comment=$env{'form.comment'};
-        $comment=~s/\</\&lt\;/g;
-        $comment=~s/\>/\&gt\;/g;
-        $comment=~s/\:/\&colon;/g;
+	$comment = &LONCAPA::map::qtunescape($comment);
         if ($folder=~/^supplemental/) {
               $comment=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
                   $env{'user.domain'}.'___&&&___'.$comment;
@@ -1561,38 +1552,18 @@ sub process_file_upload {
                 my $total_embedded = keys(%{$allfiles});
                 if ($total_embedded > 0) {
                     my $num = 0;
-                    $$upload_output .= 'This file contains embedded multimedia objects, which need to be uploaded to LON-CAPA.<br />
-   <form name="upload_embedded" action="/adm/coursedocs"
-                  method="post" enctype="multipart/form-data">
-   <input type="hidden" name="folderpath" value="'.$env{'form.folderpath'}.'" />   <input type="hidden" name="cmd" value="upload_embedded" />
+		    my $state = '
+   <input type="hidden" name="folderpath" value="'.$env{'form.folderpath'}.'" />
+   <input type="hidden" name="cmd" value="upload_embedded" />
    <input type="hidden" name="newidx" value="'.$newidx.'" />
    <input type="hidden" name="primaryurl" value="'.&escape($url).'" />
    <input type="hidden" name="phasetwo" value="'.$total_embedded.'" />';
-                    $$upload_output .= '<b>Upload embedded files</b>:<br />
-   <table>';
-                    foreach my $embed_file (keys(%{$allfiles})) {
-                        $$upload_output .= '<tr><td>'.$embed_file.
-          '<input name="embedded_item_'.$num.'" type="file" />
-           <input name="embedded_orig_'.$num.'" type="hidden" value="'.&escape($embed_file).'" />';
-                        my $attrib;
-                        if (@{$$allfiles{$embed_file}} > 1) {
-                            $attrib = join(':',@{$$allfiles{$embed_file}});
-                        } else {
-                            $attrib = $$allfiles{$embed_file}[0];
-                        }
-                        $$upload_output .=
-           '<input name="embedded_attrib_'.$num.'" type="hidden" value="'.$attrib.'" />';
-                        if (exists($$codebase{$embed_file})) {
-                            $$upload_output .= 
-          '<input name="codebase_'.$num.'" type="hidden" value="'.&escape($$codebase{$embed_file}).'" />';
-                        }
-                        $$upload_output .= '</td></tr>';
-                        $num ++;
-                    }
-                    $phase_status = 'phasetwo';
-                    $$upload_output .= '</table><br />
-   <input type ="submit" value="Complete upload" />
-   </form>';
+		    $phase_status = 'phasetwo';
+
+                    $$upload_output .= 
+			'This file contains embedded multimedia objects, which need to be uploaded to LON-CAPA.<br />'.
+			&ask_for_embedded_content('/adm/coursedocs',
+						  $state,$allfiles,$codebase);
                 } else {
                     $$upload_output .= 'No embedded items identified<br />';
                 }
@@ -1602,6 +1573,49 @@ sub process_file_upload {
     return $phase_status;
 }
 
+sub ask_for_embedded_content {
+    my ($actionurl,$state,$allfiles,$codebase,$args)=@_;
+    my $upload_output = '
+   <form name="upload_embedded" action="'.$actionurl.'"
+                  method="post" enctype="multipart/form-data">';
+    $upload_output .= $state;
+    $upload_output .= '<b>Upload embedded files</b>:<br />'.
+	&Apache::loncommon::start_data_table();
+
+    my $num = 0;
+    foreach my $embed_file (keys(%{$allfiles})) {
+	$upload_output .= &Apache::loncommon::start_data_table_row().
+	    '<td>'.$embed_file.'</td><td>';
+	if ($args->{'error_on_invalid_names'}
+	    && $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) {
+	    
+	    $upload_output.='<span class="LC_warning">'.&mt("Invalid characters").'</span>';
+	} else {
+	    $upload_output .='
+           <input name="embedded_item_'.$num.'" type="file" value="bob" />
+           <input name="embedded_orig_'.$num.'" type="hidden" value="'.&escape($embed_file).'" />';
+	    my $attrib = join(':',@{$$allfiles{$embed_file}});
+	    $upload_output .=
+		"\n\t\t".
+		'<input name="embedded_attrib_'.$num.'" type="hidden" value="'.
+		$attrib.'" />';
+	    if (exists($$codebase{$embed_file})) {
+		$upload_output .= 
+		    "\n\t\t".
+		    '<input name="codebase_'.$num.'" type="hidden" value="'.
+		    &escape($$codebase{$embed_file}).'" />';
+	    }
+	}
+	$upload_output .= '</td>'.&Apache::loncommon::end_data_table_row();
+	$num++;
+    }
+    $upload_output .= &Apache::loncommon::end_data_table().'<br />
+   <input type ="hidden" name="number_embedded_items" value="'.$num.'" />
+   <input type ="submit" value="Complete upload" />
+   </form>';
+    return $upload_output;
+}
+
 sub process_secondary_uploads {
     my ($upload_output,$coursedom,$coursenum,$formname,$num,$newidx) = @_;
     my $folder=$env{'form.folder'};
@@ -1617,7 +1631,7 @@ sub process_secondary_uploads {
     $destination .= $newidx;
     my ($url,$filename);
     $url=&Apache::lonnet::userfileupload($formname.$num,1,$destination);
-    ($filename) = ($url =~ m-^/uploaded/$coursedom/$coursenum/$destination/(.+)$-);
+    ($filename) = ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/\Q$destination\E/(.+)$});
     return $filename;
 }
 
@@ -1625,14 +1639,12 @@ sub process_secondary_uploads {
 
 sub entryline {
     my ($index,$title,$url,$folder,$allowed,$residx,$coursenum)=@_;
-    $title=~s/\&colon\;/\:/g;
-    $title=&HTML::Entities::encode(&HTML::Entities::decode(
-     &unescape($title)),'"<>&\'');
+    $title=&HTML::Entities::encode($title,'"<>&\'');
     my $renametitle=$title;
     my $foldertitle=$title;
     my $pagetitle=$title;
     my $orderidx=$LONCAPA::map::order[$index];
-    if ($title=~ /^(\d+)___&amp;&amp;&amp;___(\w+)___&amp;&amp;&amp;___(\w+)___&amp;&amp;&amp;___(.*)$/	) { 
+    if ($title=~ /^(\d+)___&amp;&amp;&amp;___($match_username)___&amp;&amp;&amp;___($match_domain)___&amp;&amp;&amp;___(.*)$/	) { 
 	$foldertitle=&Apache::lontexconvert::msgtexconverted($4);
 	$renametitle=$4;
 	$title='<i>'.&Apache::lonlocal::locallocaltime($1).'</i> '.
@@ -1694,6 +1706,7 @@ sub entryline {
 		'rn' => 'Rename',
 		'cp' => 'Copy');
 	my $nocopy=0;
+        my $nocut=0;
         if ($url=~/\.(page|sequence)$/) {
 	    foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$url))) {
 		my ($title,$url,$ext,$type)=split(/\:/,$_);
@@ -1703,13 +1716,24 @@ sub entryline {
 		}
 	    }
 	}
+        if ($url=~/^\/res\/lib\/templates\//) { 
+           $nocopy=1; 
+           $nocut=1;
+        }
         my $copylink='&nbsp;';
+        my $cutlink='&nbsp;';
         if ($env{'form.pagepath'}) {
-           unless ($nocopy) {
+           if (!$nocopy) {
                $copylink=(<<ENDCOPY);
 <a href='javascript:markcopy("$pagepath","$index","$renametitle","page","$pagesymb");'>
 <font size="-2" color="#000099">$lt{'cp'}</font></a></td>
 ENDCOPY
+           }
+           if (!$nocut) {
+               $cutlink=(<<ENDCUT);
+<a href='javascript:cutres("$pagepath","$index","$renametitle","page","$pagesymb");'>
+<font size="-2" color="#550044">$lt{'ct'}</font></a>
+ENDCUT
             }
             $line.=(<<END);
 <form name="entry_$index" action="/adm/coursedocs" method="post">
@@ -1731,19 +1755,24 @@ ENDCOPY
 </td><td bgcolor="#DDDDDD">
 <a href='javascript:removeres("$pagepath","$index","$renametitle","page","$pagesymb");'>
 <font size="-2" color="#990000">$lt{'rm'}</font></a>
-<a href='javascript:cutres("$pagepath","$index","$renametitle","page","$pagesymb");'>
-<font size="-2" color="#550044">$lt{'ct'}</font></a>
+$cutlink
 <a href='javascript:changename("$pagepath","$index","$renametitle","page","$pagesymb");'>
 <font size="-2" color="#009900">$lt{'rn'}</font></a>
 $copylink
 END
         } else {
-           unless ($nocopy) {
+           if (!$nocopy) {
                $copylink=(<<ENDCOPY);
 <a href='javascript:markcopy("$folderpath","$index","$renametitle","sequence");'>
 <font size="-2" color="#000099">$lt{'cp'}</font></a></td>
 ENDCOPY
             }
+            if (!$nocut) {
+               $cutlink=(<<ENDCUT);
+<a href='javascript:cutres("$folderpath","$index","$renametitle","sequence");'>
+<font size="-2" color="#550044">$lt{'ct'}</font></a>
+ENDCUT
+            }
             $line.=(<<END); 
 <form name="entry_$index" action="/adm/coursedocs" method="post">
 <input type="hidden" name="folderpath" value="$env{'form.folderpath'}" />
@@ -1763,8 +1792,7 @@ ENDCOPY
 </td><td bgcolor="#DDDDDD">
 <a href='javascript:removeres("$folderpath","$index","$renametitle","sequence");'>
 <font size="-2" color="#990000">$lt{'rm'}</font></a>
-<a href='javascript:cutres("$folderpath","$index","$renametitle","sequence");'>
-<font size="-2" color="#550044">$lt{'ct'}</font></a>
+$cutlink
 <a href='javascript:changename("$folderpath","$index","$renametitle","sequence");'>
 <font size="-2" color="#009900">$lt{'rn'}</font></a>
 $copylink
@@ -1783,13 +1811,13 @@ END
     if ($uploaded) {
 	if ($extension eq 'sequence') {
 	    $icon=$iconpath.'/folder_closed.gif';
-	    $url=~/$coursenum\/([\/\w]+)\.sequence$/;
+	    $url=~/\Q$coursenum\E\/([\/\w]+)\.sequence$/;
 	    $url='/adm/coursedocs?';
 	    $folderarg=$1;
 	    $isfolder=1;
         } elsif ($extension eq 'page') {
             $icon=$iconpath.'/page.gif';
-            $url=~/$coursenum\/([\/\w]+)\.page$/;
+            $url=~/\Q$coursenum\E\/([\/\w]+)\.page$/;
             $pagearg=$1;
             $url='/adm/coursedocs?';
             $ispage=1;
@@ -1852,7 +1880,7 @@ END
 	    (&LONCAPA::map::getparameter($orderidx,
                                               'parameter_randompick'))[0].
                                               '" />'.
-'<font size="-2"><a href="javascript:void(0)">'.&mt('Store').'</a></font></label>';
+'<font size="-2"><a href="javascript:void(0)">'.&mt('Save').'</a></font></label>';
        
     }
     if ($ispage) {
@@ -2111,9 +2139,9 @@ sub checkversions {
         if (&Apache::lonnet::put('resourceversions',\%newsetversions,
 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
 			  $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') {		
-	    $r->print('<h1>'.&mt('Your Version Settings have been Stored').'</h1>');
+	    $r->print('<h1>'.&mt('Your Version Settings have been Saved').'</h1>');
 	} else {
-	    $r->print('<h1><font color="red">'.&mt('An Error Occured while Attempting to Store your Version Settings').'</font></h1>');
+	    $r->print('<h1><font color="red">'.&mt('An Error Occured while Attempting to Save your Version Settings').'</font></h1>');
 	}
 	&mark_hash_old();
     }
@@ -2490,7 +2518,8 @@ sub handler {
   my %codebase = ();
   my ($upload_result,$upload_output);
   if ($allowed) {
-      if (($env{'form.uploaddoc.filename'}) &&                                               ($env{'form.cmd'}=~/^upload_(\w+)/)) {
+      if (($env{'form.uploaddoc.filename'}) &&
+	  ($env{'form.cmd'}=~/^upload_(\w+)/)) {
 # Process file upload - phase one - upload and parse primary file.  
           $upload_result = &process_file_upload(\$upload_output,$coursenum,
 						$coursedom,\%allfiles,