Diff for /loncom/interface/londocs.pm between versions 1.484.2.93.2.17 and 1.484.2.94

version 1.484.2.93.2.17, 2023/12/30 05:25:31 version 1.484.2.94, 2024/07/01 18:29:41
Line 43  use Apache::lonnavdisplay(); Line 43  use Apache::lonnavdisplay();
 use Apache::lonextresedit();  use Apache::lonextresedit();
 use Apache::lontemplate();  use Apache::lontemplate();
 use Apache::lonsimplepage();  use Apache::lonsimplepage();
 use Apache::loncourserespicker();  
 use HTML::Entities;  use HTML::Entities;
 use HTML::TokeParser;  use HTML::TokeParser;
 use GDBM_File;  use GDBM_File;
 use File::MMagic;  use File::MMagic;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Cwd;  use Cwd;
 use UUID::Tiny ':std';  
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
   
 my $iconpath;  my $iconpath;
Line 87  sub storemap { Line 85  sub storemap {
   
     if ($map =~ /^default/) {      if ($map =~ /^default/) {
         $hadchanges=1;          $hadchanges=1;
     } elsif ($contentchg) {      } else {
         $suppchanges=1;          $suppchanges=1;
     }      }
     return ($errtext,0);      return ($errtext,0);
Line 179  sub default_folderpath { Line 177  sub default_folderpath {
     }      }
 }  }
   
 sub validate_supppath {  sub validate_folderpath {
     my ($coursenum,$coursedom) = @_;      my ($supplementalflag) = @_;
     my $backto;      if ($env{'form.folderpath'} ne '') {
           my @items = split(/\&/,$env{'form.folderpath'});
           my $badpath;
           for (my $i=0; $i<@items; $i++) {
               my $odd = $i%2;
               if (($odd) && (!$supplementalflag) && ($items[$i] !~ /^[^:]*:(|\d+):(|1):(|1):(|1):(|1)$/)) {
                   $badpath = 1;
               } elsif ((!$odd) && ($items[$i] !~ /^(default|supplemental)(|_\d+)$/)) {
                   $badpath = 1;
               }
               last if ($badpath);
           }
           if ($badpath) {
               delete($env{'form.folderpath'});
           }
       }
       return;
   }
   
   sub validate_suppath {
     if ($env{'form.supppath'} ne '') {      if ($env{'form.supppath'} ne '') {
         my @items = split(/\&/,$env{'form.supppath'});          my @items = split(/\&/,$env{'form.supppath'});
         my ($badpath,$got_supp,$supppath,%supphidden,%suppids);          my $badpath;
         for (my $i=0; $i<@items; $i++) {          for (my $i=0; $i<@items; $i++) {
             my $odd = $i%2;              my $odd = $i%2;
             if ((!$odd) && ($items[$i] !~ /^supplemental(|_\d+)$/)) {              if ((!$odd) && ($items[$i] !~ /^supplemental(|_\d+)$/)) {
                 $badpath = 1;                  $badpath = 1;
                 last;  
             } elsif ($odd) {  
                 my $suffix;  
                 my $idx = $i-1;  
                 if ($items[$i] =~ /^([^:]*)::(|1):::$/) {  
                     $backto .= '&'.$1;  
                 } elsif ($items[$idx] eq 'supplemental') {  
                     $backto .= '&'.$items[$i];  
                 } else {  
                     $backto .= '&'.$items[$i];  
                     my $is_hidden;  
                     unless ($got_supp) {  
                         my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);  
                         if (ref($supplemental) eq 'HASH') {  
                             if (ref($supplemental->{'hidden'}) eq 'HASH') {  
                                 %supphidden = %{$supplemental->{'hidden'}};  
                             }  
                             if (ref($supplemental->{'ids'}) eq 'HASH') {  
                                 %suppids = %{$supplemental->{'ids'}};  
                             }  
                         }  
                         $got_supp = 1;  
                     }  
                     if (ref($suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}) eq 'ARRAY') {  
                         my $mapid = $suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}->[0];  
                         if ($supphidden{$mapid}) {  
                             $is_hidden = 1;  
                         }  
                     }  
                     $suffix = '::'.$is_hidden.':::';  
                 }  
                 $supppath .= '&'.$items[$i].$suffix;  
             } else {  
                 $supppath .= '&'.$items[$i];  
                 $backto .= '&'.$items[$i];  
             }              }
               last if ($badpath);
         }          }
         if ($badpath) {          if ($badpath) {
             delete($env{'form.supppath'});              delete($env{'form.supppath'});
         } else {  
             $supppath =~ s/^\&//;  
             $backto =~ s/^\&//;  
             $env{'form.supppath'} = $supppath;  
         }          }
     }      }
     return $backto;      return;
 }  }
   
 sub dumpcourse {  sub dumpcourse {
Line 682  sub recurse_html { Line 661  sub recurse_html {
 }  }
   
 sub group_import {  sub group_import {
     my ($coursenum, $coursedom, $folder, $container, $caller, $ltitoolsref, @files) = @_;      my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_;
     my ($donechk,$allmaps,%hierarchy,%titles,%addedmaps,%removefrommap,      my ($donechk,$allmaps,%hierarchy,%titles,%addedmaps,%removefrommap,
         %removeparam,$importuploaded,$fixuperrors);          %removeparam,$importuploaded,$fixuperrors);
     $allmaps = {};      $allmaps = {};
Line 711  sub group_import { Line 690  sub group_import {
             }              }
         }          }
  if ($url) {   if ($url) {
             if ($url =~ m{^(/adm/$coursedom/$coursenum/(\d+)/ext\.tool)\:?(.*)$}) {  
                 $url = $1;  
                 my $marker = $2;  
                 my $info = $3;  
                 my ($toolid,$toolprefix,$tooltype,%toolhash,%toolsettings);  
                 my @extras = ('linktext','explanation','crslabel','crstitle','crsappend');  
                 my @toolinfo = split(/:/,$info);  
                 if ($residx) {  
                     %toolsettings=&Apache::lonnet::dump('exttool_'.$marker,$coursedom,$coursenum);  
                     $toolid = $toolsettings{'id'};  
                 } else {  
                     $toolid = shift(@toolinfo);  
                 }  
                 if ($toolid =~ /^c/) {  
                     $tooltype = 'crs';  
                     $toolprefix = 'c';  
                 } else {  
                     $tooltype = 'dom';  
                 }  
                 $toolid =~ s/\D//g;  
                 ($toolhash{'target'},$toolhash{'width'},$toolhash{'height'},  
                  $toolhash{'linktext'},$toolhash{'explanation'},$toolhash{'crslabel'},  
                  $toolhash{'crstitle'},$toolhash{'crsappend'},$toolhash{'gradable'}) = @toolinfo;  
                 foreach my $item (@extras) {  
                     $toolhash{$item} = &unescape($toolhash{$item});  
                 }  
                 if ($folder =~ /^supplemental/) {  
                     delete($toolhash{'gradable'});  
                 } else {  
                     $toolhash{'gradable'} =~ s/\D+//g;  
                 }  
                 if (ref($ltitoolsref) eq 'HASH') {  
                     if (ref($ltitoolsref->{$tooltype}) eq 'HASH') {  
                         if (ref($ltitoolsref->{$tooltype}->{$toolid}) eq 'HASH') {  
                             my %tools = %{$ltitoolsref->{$tooltype}->{$toolid}};  
                             my @deleted;  
                             $toolhash{'id'} = $toolprefix.$toolid;  
                             if (($toolhash{'target'} eq 'iframe') || ($toolhash{'target'} eq 'tab') ||  
                                 ($toolhash{'target'} eq 'window')) {  
                                 if ($toolhash{'target'} eq 'window') {  
                                     foreach my $item ('width','height') {  
                                         $toolhash{$item} =~ s/^\s+//;  
                                         $toolhash{$item} =~ s/\s+$//;  
                                         if ($toolhash{$item} =~ /\D/) {  
                                             delete($toolhash{$item});  
                                             if ($residx) {  
                                                 if ($toolsettings{$item}) {  
                                                     push(@deleted,$item);  
                                                 }  
                                             }  
                                         }  
                                     }  
                                 }  
                             } elsif ($residx) {  
                                 $toolhash{'target'} = $toolsettings{'target'};  
                                 if ($toolhash{'target'} eq 'window') {  
                                     foreach my $item ('width','height') {  
                                         $toolhash{$item} = $toolsettings{$item};  
                                     }  
                                 }  
                             } elsif (ref($tools{'display'}) eq 'HASH') {  
                                 $toolhash{'target'} = $tools{'display'}{'target'};  
                                 if ($toolhash{'target'} eq 'window') {  
                                     $toolhash{'width'} = $tools{'display'}{'width'};  
                                     $toolhash{'height'} = $tools{'display'}{'height'};  
                                 }  
                             }  
                             if ($toolhash{'target'} eq 'iframe') {  
                                 foreach my $item ('width','height','linktext','explanation') {  
                                     delete($toolhash{$item});  
                                     if ($residx) {  
                                         if ($toolsettings{$item}) {  
                                             push(@deleted,$item);  
                                         }  
                                     }  
                                 }  
                             } elsif ($toolhash{'target'} eq 'tab') {  
                                 foreach my $item ('width','height') {  
                                     delete($toolhash{$item});  
                                     if ($residx) {  
                                         if ($toolsettings{$item}) {  
                                             push(@deleted,$item);  
                                         }  
                                     }  
                                 }  
                             }  
                             if (ref($tools{'crsconf'}) eq 'HASH') {  
                                 foreach my $item ('label','title','linktext','explanation') {  
                                     my $crsitem;  
                                     if (($item eq 'label') || ($item eq 'title')) {  
                                         $crsitem = 'crs'.$item;  
                                     } else {  
                                         $crsitem = $item;  
                                     }  
                                     if ($tools{'crsconf'}{$item}) {  
                                         $toolhash{$crsitem} =~ s/^\s+//;  
                                         $toolhash{$crsitem} =~ s/\s+$//;  
                                         if ($toolhash{$crsitem} eq '') {  
                                             delete($toolhash{$crsitem});  
                                         }  
                                     } else {  
                                         delete($toolhash{$crsitem});  
                                     }  
                                     if (($residx) && (exists($toolsettings{$crsitem}))) {  
                                         unless (exists($toolhash{$crsitem})) {  
                                             push(@deleted,$crsitem);  
                                         }  
                                     }  
                                 }  
                             }  
                             if ($toolhash{'passback'}) {  
                                 my $gradesecret = UUID::Tiny::create_uuid_as_string(UUID_V4);  
                                 $toolhash{'gradesecret'} = $gradesecret;  
                                 $toolhash{'gradesecretdate'} = time;  
                             }  
                             if ($toolhash{'roster'}) {  
                                 my $rostersecret = UUID::Tiny::create_uuid_as_string(UUID_V4);  
                                 $toolhash{'rostersecret'} = $rostersecret;  
                                 $toolhash{'rostersecretdate'} = time;  
                             }  
                             my $changegradable;  
                             if (($residx) && ($folder =~ /^default/)) {  
                                 if ($toolsettings{'gradable'}) {  
                                     unless (($toolhash{'gradable'}) || (defined($LONCAPA::map::zombies[$residx]))) {  
                                         push(@deleted,'gradable');  
                                         $changegradable = 1;  
                                     }  
                                 } elsif ($toolhash{'gradable'}) {  
                                     $changegradable = 1;  
                                 }  
                                 if (($caller eq 'londocs') && (defined($LONCAPA::map::zombies[$residx]))) {  
                                     $changegradable = 1;  
                                     if ($toolsettings{'gradable'}) {  
                                         $toolhash{'gradable'} = 1;  
                                     }  
                                 }  
                             }  
                             my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum);  
                             if ($putres eq 'ok') {  
                                 if (@deleted) {  
                                     &Apache::lonnet::del('exttool_'.$marker,\@deleted,$coursedom,$coursenum);  
                                 }  
                                 if (($changegradable) && ($folder =~ /^default/)) {  
                                     my $val;  
                                     if ($toolhash{'gradable'}) {  
                                         $val = 'yes';  
                                     } else {  
                                         $val = 'no';  
                                     }  
                                     &LONCAPA::map::storeparameter($residx,'parameter_0_gradable',$val,  
                                                                   'string_yesno');  
                                     &remember_parms($residx,'gradable','set',$val);  
                                 }  
                             } else {  
                                 return (&mt('Failed to save update to external tool.'),1);  
                             }  
                         }  
                     }  
                 }  
             }  
             if (($caller eq 'londocs') &&              if (($caller eq 'londocs') &&
                 ($folder =~ /^default/)) {                  ($folder =~ /^default/)) {
                 if (($url =~ /\.(page|sequence)$/) && (!$donechk)) {                  if (($url =~ /\.(page|sequence)$/) && (!$donechk)) {
Line 882  sub group_import { Line 701  sub group_import {
                     $donechk = 1;                      $donechk = 1;
                 }                  }
                 if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) {                  if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) {
                     &contained_map_check($url,$folder,$coursenum,$coursedom,\%removefrommap,                      &contained_map_check($url,$folder,\%removefrommap,\%removeparam,
                                          \%removeparam,\%addedmaps,\%hierarchy,\%titles,$allmaps);                                           \%addedmaps,\%hierarchy,\%titles,$allmaps);
                     $importuploaded = 1;                      $importuploaded = 1;
                 } elsif ($url =~ m{^/res/.+\.(page|sequence)$}) {                  } elsif ($url =~ m{^/res/.+\.(page|sequence)$}) {
                     next if ($allmaps->{$url});                      next if ($allmaps->{$url});
Line 979  END Line 798  END
         &storemap($coursenum, $coursedom, $folder.'.'.$container,1);          &storemap($coursenum, $coursedom, $folder.'.'.$container,1);
     unless ($fatal) {      unless ($fatal) {
         if ($folder =~ /^supplemental/) {          if ($folder =~ /^supplemental/) {
               &Apache::lonnet::get_numsuppfiles($coursenum,$coursedom,1);
             my ($errtext,$fatal) = &mapread($coursenum,$coursedom,              my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
                                             $folder.'.'.$container);                                              $folder.'.'.$container);
         }          }
Line 1055  sub docs_change_log { Line 875  sub docs_change_log {
              '// <![CDATA['."\n".               '// <![CDATA['."\n".
              &Apache::loncommon::display_filter_js('docslog')."\n".               &Apache::loncommon::display_filter_js('docslog')."\n".
              &editing_js($env{'user.domain'},$env{'user.name'},$supplementalflag,               &editing_js($env{'user.domain'},$env{'user.name'},$supplementalflag,
                          $coursedom,$coursenum,'','',$canedit,'',\$navmap)."\n".                           $coursedom,$coursenum,$canedit,'',\$navmap)."\n".
              &history_tab_js()."\n".               &history_tab_js()."\n".
              &Apache::lonratedt::editscript('simple')."\n".               &Apache::lonratedt::editscript('simple')."\n".
              '// ]]>'."\n".               '// ]]>'."\n".
Line 1105  sub docs_change_log { Line 925  sub docs_change_log {
     'encrypturl'     => 'URL hidden',      'encrypturl'     => 'URL hidden',
     'randompick'     => 'Randomly pick',      'randompick'     => 'Randomly pick',
     'randomorder'    => 'Randomly ordered',      'randomorder'    => 'Randomly ordered',
             'gradable'       => 'Grade can be assigned to External Tool',  
     'set'            => 'set to',      'set'            => 'set to',
     'del'            => 'deleted');      'del'            => 'deleted');
     my $filter = &Apache::loncommon::display_filter('docslog')."\n".      my $filter = &Apache::loncommon::display_filter('docslog')."\n".
Line 1212  sub docs_change_log { Line 1031  sub docs_change_log {
  }   }
  $r->print('</ul>');   $r->print('</ul>');
  if ($docslog{$id}{'logentry'}{'parameter_res'}) {   if ($docslog{$id}{'logentry'}{'parameter_res'}) {
             my ($title,$url) = split(/\:/,$docslog{$id}{'logentry'}{'parameter_res'},3);      $r->print(&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'parameter_res'}))[0]).':<ul>');
             if ($title eq '') {      foreach my $parameter ('randompick','hiddenresource','encrypturl','randomorder') {
                 ($title) = ($url =~ m{/([^/]+)$});  
             } elsif ($is_supp) {  
                 $title = &Apache::loncommon::parse_supplemental_title($title);  
             }  
             $r->print(&LONCAPA::map::qtescape($title).':<ul>');  
     foreach my $parameter ('randompick','hiddenresource','encrypturl','randomorder','gradable') {  
  if ($docslog{$id}{'logentry'}{'parameter_action_'.$parameter}) {   if ($docslog{$id}{'logentry'}{'parameter_action_'.$parameter}) {
 # FIXME: internationalization seems wrong here  # FIXME: internationalization seems wrong here
     $r->print('<li>'.      $r->print('<li>'.
Line 1354  sub update_paste_buffer { Line 1167  sub update_paste_buffer {
                 $subdir = $prefix;                  $subdir = $prefix;
             }              }
             my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps);              my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps);
             &contained_map_check($url,$folder,$coursenum,$coursedom,\%removefrommap,              &contained_map_check($url,$folder,\%removefrommap,\%removeparam,\%addedmaps,
                                  \%removeparam,\%addedmaps,\%hierarchy,\%titles,\%allmaps);                                   \%hierarchy,\%titles,\%allmaps);
             if (ref($hierarchy{$url}) eq 'HASH') {              if (ref($hierarchy{$url}) eq 'HASH') {
                 my ($nested,$nestednames);                  my ($nested,$nestednames);
                 &recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames);                  &recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames);
Line 1416  sub print_paste_buffer { Line 1229  sub print_paste_buffer {
     }      }
   
     my @currpaste = split(/,/,$env{'docs.markedcopies'});      my @currpaste = split(/,/,$env{'docs.markedcopies'});
     my ($pasteitems,@pasteable,$same_institution,$checkedsameinst);      my ($pasteitems,@pasteable);
     my $clipboardcount = 0;      my $clipboardcount = 0;
   
 # Construct identifiers for current contents of user's paste buffer  # Construct identifiers for current contents of user's paste buffer
Line 1429  sub print_paste_buffer { Line 1242  sub print_paste_buffer {
             ($url ne '')) {              ($url ne '')) {
             $clipboardcount ++;              $clipboardcount ++;
             my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent,              my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent,
                 $canpaste,$nopaste,$othercrs,$areachange,$is_exttool,$toolcdom,                  $canpaste,$nopaste,$othercrs,$areachange);
                 $toolcnum,$marker);  
             my $extension = (split(/\./,$env{'docs.markedcopy_url_'.$suffix}))[-1];              my $extension = (split(/\./,$env{'docs.markedcopy_url_'.$suffix}))[-1];
             if ($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?:&colon;|:))//} ) {              if ($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?:&colon;|:))//} ) {
                 $is_external = 1;                  $is_external = 1;
             } elsif ($url =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/ext\.tool$}) {  
                 ($toolcdom,$toolcnum,$marker) = ($1,$2,$3);  
                 $is_exttool = 1;  
             }              }
             if ($folder =~ /^supplemental/) {              if ($folder =~ /^supplemental/) {
                 $canpaste = &supp_pasteable($env{'docs.markedcopy_url_'.$suffix});                  $canpaste = &supp_pasteable($env{'docs.markedcopy_url_'.$suffix});
Line 1469  sub print_paste_buffer { Line 1278  sub print_paste_buffer {
                         $is_uploaded_map = 1;                          $is_uploaded_map = 1;
                     }                      }
                 } elsif (($url =~ m{^/res/lib/templates/\w+\.problem$}) ||                  } elsif (($url =~ m{^/res/lib/templates/\w+\.problem$}) ||
                          ($url =~ m{^/adm/($match_domain)/($match_username)/\d+/(bulletinboard|smppg|ext\.tool)$})) {                           ($url =~ m{^/adm/($match_domain)/($match_username)/\d+/(bulletinboard|smppg)$})) {
                     if ($cid ne $env{'request.course.id'}) {                      if ($cid ne $env{'request.course.id'}) {
                         my ($srcdom,$srcnum) = split(/_/,$cid);                          my ($srcdom,$srcnum) = split(/_/,$cid);
                         if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) {                          if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) {
                             if ($is_exttool) {                              $othercrs = '<br />'.&mt('(from another course)');
                                 if ($toolcdom ne $coursedom) {  
                                     $canpaste = 0;  
                                     $nopaste = &mt('Paste from another domain unavailable.');  
                                 } elsif ($toolcnum ne $coursenum) {  
                                     my %toolsettings =  
                                         &Apache::lonnet::dump('exttool_'.$marker,$toolcdom,$toolcnum);  
                                     my %tooltypes = &Apache::loncommon::usable_exttools();  
                                     if ((($toolsettings{'id'} =~ /^c\d+$/) && (!$tooltypes{'crs'})) ||  
                                         (($toolsettings{'id'} =~ /^\d+$/) && (!$tooltypes{'dom'}))) {  
                                         $canpaste = 0;  
                                         $nopaste = &mt('Paste from another course unavailable.');  
                                     } elsif ($toolsettings{'id'} =~ /^c\d+$/) {  
                                         unless ($checkedsameinst) {  
                                             my $primary_id = &Apache::lonnet::domain($coursedom,'primary');  
                                             my $intdom = &Apache::lonnet::internet_dom($primary_id);  
                                             if ($intdom ne '') {  
                                                 my $internet_names =  
                                                     &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});  
                                                 if (ref($internet_names) eq 'ARRAY') {  
                                                     if (grep(/^\Q$intdom\E$/,@{$internet_names})) {  
                                                         $same_institution = 1;  
                                                     }  
                                                 }  
                                             }  
                                             $checkedsameinst = 1;  
                                         }  
                                         if ($same_institution) {  
                                             $othercrs = '<br />'.&mt('(from another course)');  
                                         } else {  
                                             $nopaste = &mt('Paste from another course unavailable.');  
                                         }  
                                     } else {  
                                         $othercrs = '<br />'.&mt('(from another course)');  
                                     }  
                                 }  
                             }  
                         } else {                          } else {
                             $canpaste = 0;                              $canpaste = 0;
                             $nopaste = &mt('Paste from another course unavailable.');                              $nopaste = &mt('Paste from another course unavailable.');
Line 1525  sub print_paste_buffer { Line 1298  sub print_paste_buffer {
                 $buffer = &mt('External Resource').': '.                  $buffer = &mt('External Resource').': '.
                     &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}).' ('.                      &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}).' ('.
                     &LONCAPA::map::qtescape($url).')';                      &LONCAPA::map::qtescape($url).')';
             } elsif ($is_exttool) {  
                 $buffer = &mt('External Tool').': '.  
                     &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix});  
             } else {              } else {
                 my $icon = &Apache::loncommon::icon($extension);                  my $icon = &Apache::loncommon::icon($extension);
                 if ($extension eq 'sequence' &&                  if ($extension eq 'sequence' &&
Line 1557  sub print_paste_buffer { Line 1327  sub print_paste_buffer {
             }              }
             $pasteitems .= '<label><input type="checkbox" name="pasting" id="pasting_'.$suffix.'" value="'.$suffix.'" '.$onclick.'/>'.$buffer.'</label>';              $pasteitems .= '<label><input type="checkbox" name="pasting" id="pasting_'.$suffix.'" value="'.$suffix.'" '.$onclick.'/>'.$buffer.'</label>';
             if ($nopaste) {              if ($nopaste) {
                  $pasteitems .= ' <span class="LC_cusr_emph">'.$nopaste.'</span>';                      $pasteitems .= $nopaste;   
             } else {              } else {
                 if ($othercrs) {                  if ($othercrs) {
                     $pasteitems .= $othercrs;                      $pasteitems .= $othercrs;
Line 1583  sub print_paste_buffer { Line 1353  sub print_paste_buffer {
             }              }
             $buttons = '<input type="submit" name="pastemarked" value="'.$value.'" />'.('&nbsp;'x2);              $buttons = '<input type="submit" name="pastemarked" value="'.$value.'" />'.('&nbsp;'x2);
         }          }
         $buttons .= '<input type="submit" name="clearmarked" value="'.&mt('Remove from clipboard').'" />'.('&nbsp;'x2);          $buttons .= '<input type="submit" name="clearmarked" value="'.&mt('Clear selected').'" />'.('&nbsp;'x2);
         if ($clipboardcount > 1) {          if ($clipboardcount > 1) {
             $buttons .=              $buttons .=
                 '<span style="text-decoration:line-through">'.('&nbsp;'x20).'</span>'.('&nbsp;'x2).                  '<span style="text-decoration:line-through">'.('&nbsp;'x20).'</span>'.('&nbsp;'x2).
Line 1684  sub supp_pasteable { Line 1454  sub supp_pasteable {
         (($url =~ /\.sequence$/) && ($url =~ m{^/uploaded/})) ||          (($url =~ /\.sequence$/) && ($url =~ m{^/uploaded/})) ||
         ($url =~ m{^/uploaded/$match_domain/$match_courseid/(docs|supplemental)/(default|\d+)/\d+/}) ||          ($url =~ m{^/uploaded/$match_domain/$match_courseid/(docs|supplemental)/(default|\d+)/\d+/}) ||
         ($url =~ m{^/adm/$match_domain/$match_username/aboutme}) ||          ($url =~ m{^/adm/$match_domain/$match_username/aboutme}) ||
         ($url =~ m{^/public/$match_domain/$match_courseid/syllabus}) ||          ($url =~ m{^/public/$match_domain/$match_courseid/syllabus})) {
         ($url =~ m{^/adm/$match_domain/$match_courseid/\d+/ext\.tool$})) {  
         return 1;          return 1;
     }      }
     return;      return;
Line 1807  sub do_paste_from_buffer { Line 1576  sub do_paste_from_buffer {
         return();          return();
     }      }
   
     my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%notindom,      my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%duplicate,
         %othcrstool,%duplicate,%prefixchg,%srcdom,%srcnum,%srcmapidx,          %prefixchg,%srcdom,%srcnum,%srcmapidx,%marktomove,$save_err,$lockerrors,$allresult);
         %marktomove,$save_err,$lockerrors,$allresult,%currcrsltitools,  
         %currltititles,$currltimax,$gotcrsltitools);  
     $currltimax = 0;  
     $gotcrsltitools = 0;  
     foreach my $suffix (@topaste) {      foreach my $suffix (@topaste) {
         my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix});          my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix});
         my $cid=&LONCAPA::map::qtescape($env{'docs.markedcopy_crs_'.$suffix});          my $cid=&LONCAPA::map::qtescape($env{'docs.markedcopy_crs_'.$suffix});
Line 1839  sub do_paste_from_buffer { Line 1605  sub do_paste_from_buffer {
             $srcdom{$suffix} = $srcd;              $srcdom{$suffix} = $srcd;
             $srcnum{$suffix} = $srcn;              $srcnum{$suffix} = $srcn;
         } elsif (($url =~ m{^/res/lib/templates/\w+\.problem$}) ||          } elsif (($url =~ m{^/res/lib/templates/\w+\.problem$}) ||
                  ($url =~ m{^/adm/$match_domain/$match_username/\d+/(bulletinboard|smppg)$}) ||                   ($url =~ m{^/adm/$match_domain/$match_username/\d+/(bulletinboard|smppg)$})) {
                  ($url =~ m{^/adm/$match_domain/$match_courseid/\d+/ext\.tool$})) {  
             my ($srcd,$srcn) = split(/_/,$cid);              my ($srcd,$srcn) = split(/_/,$cid);
 # When paste buffer was populated using an active role in a different course  # When paste buffer was populated using an active role in a different course
 # check for mdc privilege in the course from which the resource was pasted  # check for mdc privilege in the course from which the resource was pasted
Line 1850  sub do_paste_from_buffer { Line 1615  sub do_paste_from_buffer {
                     next;                      next;
                 }                  }
             }              }
 # When buffer was populated using an active role in a different course  
 # disallow pasting of External Tool if course is in a different domain,  
 # or if External Tool use is not permitted in this course.  
             if ($url =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/ext\.tool$}) {  
                 my ($toolcdom,$toolcnum,$marker) = ($1,$2,$3);  
                 if ($toolcdom ne $coursedom) {  
                     $notindom{$suffix} = 1;  
                     next;  
                 } elsif ($toolcnum ne $coursenum) {  
                     my %toolsettings =  
                         &Apache::lonnet::dump('exttool_'.$marker,$toolcdom,$toolcnum);  
                     my %tooltypes = &Apache::loncommon::usable_exttools();  
                     if ((($toolsettings{'id'} =~ /^c\d+$/) && (!$tooltypes{'crs'})) ||  
                         (($toolsettings{'id'} =~ /^\d+$/) && (!$tooltypes{'dom'}))) {  
                         $othcrstool{$suffix} = 1;  
                         next;  
                     }  
                     if ($toolsettings{'id'} =~ /^c\d+$/) {  
                         unless ($gotcrsltitools) {  
                             %currcrsltitools =  
                                 &Apache::lonnet::get_course_lti($coursenum,$coursedom,'consumer');  
                             foreach my $item (sort(keys(%currcrsltitools))) {  
                                 if (ref($currcrsltitools{$item}) eq 'HASH') {  
                                     $currltimax ++;  
                                     if (ref($currltititles{$currcrsltitools{$item}{'title'}}) eq 'ARRAY') {  
                                         push(@{$currltititles{$currcrsltitools{$item}{'title'}}},$item);  
                                     } else {  
                                         $currltititles{$currcrsltitools{$item}{'title'}} = [$item];  
                                     }  
                                 }  
                             }  
                             $gotcrsltitools = 1;  
                         }  
                     }  
                 }  
             }  
             $srcdom{$suffix} = $srcd;              $srcdom{$suffix} = $srcd;
             $srcnum{$suffix} = $srcn;              $srcnum{$suffix} = $srcn;
         }          }
Line 1894  sub do_paste_from_buffer { Line 1623  sub do_paste_from_buffer {
         if ($url=~/\.(page|sequence)$/) {          if ($url=~/\.(page|sequence)$/) {
             $is_map{$suffix} = 1;               $is_map{$suffix} = 1; 
         }          }
   
         if ($url =~ m{^/uploaded/$match_domain/$match_courseid/([^/]+)}) {          if ($url =~ m{^/uploaded/$match_domain/$match_courseid/([^/]+)}) {
             my $oldprefix = $1;              my $oldprefix = $1;
 # When pasting content from Main Content to Supplemental Content and vice versa   # When pasting content from Main Content to Supplemental Content and vice versa 
Line 1938  sub do_paste_from_buffer { Line 1668  sub do_paste_from_buffer {
     %msgs = &Apache::lonlocal::texthash (      %msgs = &Apache::lonlocal::texthash (
                 notinsupp => 'Paste failed: content type is not supported within Supplemental Content',                  notinsupp => 'Paste failed: content type is not supported within Supplemental Content',
                 notincrs  => 'Paste failed: Item is from a different course which you do not have rights to edit.',                  notincrs  => 'Paste failed: Item is from a different course which you do not have rights to edit.',
                 notindom  => 'Paste failed: Item is an external tool from a course in a different domain.',  
                 othcrstool => 'Paste failed: Item is an external tool from a different course, for which use is not allowed in this course.',  
                 duplicate => 'Paste failed: only one instance of a particular published sequence or page is allowed within each course.',                  duplicate => 'Paste failed: only one instance of a particular published sequence or page is allowed within each course.',
             );              );
   
Line 1968  sub do_paste_from_buffer { Line 1696  sub do_paste_from_buffer {
 # Retrieve information about all course maps in main content area   # Retrieve information about all course maps in main content area 
   
     my $allmaps = {};      my $allmaps = {};
     my (@toclear,%mapurls,%lockerrs,%msgerrs,%results,$donechk,      my (@toclear,%mapurls,%lockerrs,%msgerrs,%results,$donechk);
         @updatetoolsenc,$updatetoolscache,$checkedsameinst,  
         $same_institution);  
   
 # Loop over the items to paste  # Loop over the items to paste
     foreach my $suffix (@dopaste) {      foreach my $suffix (@dopaste) {
Line 1995  sub do_paste_from_buffer { Line 1721  sub do_paste_from_buffer {
                                                          $env{'request.course.id'});                                                           $env{'request.course.id'});
                 $donechk = 1;                   $donechk = 1; 
             }              }
             &contained_map_check($url,$folder,$coursenum,$coursedom,              &contained_map_check($url,$folder,\%removefrommap,\%removeparam,
                                  \%removefrommap,\%removeparam,\%addedmaps,                                   \%addedmaps,\%hierarchy,\%titles,$allmaps);
                                  \%hierarchy,\%titles,$allmaps);  
             if ($url=~ m{^/uploaded/}) {              if ($url=~ m{^/uploaded/}) {
                 my $newurl;                  my $newurl;
                 unless ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') {                  unless ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') {
Line 2050  sub do_paste_from_buffer { Line 1775  sub do_paste_from_buffer {
                 }                  }
             }              }
         }          }
         if ($url=~ m{/(bulletinboard|smppg|ext\.tool)$}) {          if ($url=~ m{/(bulletinboard|smppg)$}) {
             my $prefix = $1;              my $prefix = $1;
             my $fromothercrs;              my $fromothercrs;
             #need to copy the db contents to a new one, unless this is a move.              #need to copy the db contents to a new one, unless this is a move.
Line 2059  sub do_paste_from_buffer { Line 1784  sub do_paste_from_buffer {
                          cdom => $coursedom,                           cdom => $coursedom,
                          cnum => $coursenum,                           cnum => $coursenum,
                        );                         );
             if ($prefix eq 'ext.tool') {  
                 if ($prefixchg{$suffix} eq 'docstosupp') {  
                     $info{'delgradable'} = 1;  
                 }  
             }  
             if (($srcdom{$suffix} =~ /^$match_domain$/) && ($srcnum{$suffix} =~ /^$match_courseid$/)) {              if (($srcdom{$suffix} =~ /^$match_domain$/) && ($srcnum{$suffix} =~ /^$match_courseid$/)) {
                 unless (($srcdom{$suffix} eq $coursedom) && ($srcnum{$suffix} eq $coursenum)) {                  unless (($srcdom{$suffix} eq $coursedom) && ($srcnum{$suffix} eq $coursenum)) {
                     $fromothercrs = 1;                      $fromothercrs = 1;
                     $info{'cdom'} = $srcdom{$suffix};                      $info{'cdom'} = $srcdom{$suffix};
                     $info{'cnum'} = $srcnum{$suffix};                      $info{'cnum'} = $srcnum{$suffix};
                     unless ($checkedsameinst) {  
                         my $primary_id = &Apache::lonnet::domain($coursedom,'primary');  
                         my $intdom = &Apache::lonnet::internet_dom($primary_id);  
                         if ($intdom ne '') {  
                             my $internet_names =  
                                 &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});  
                             if (ref($internet_names) eq 'ARRAY') {  
                                 if (grep(/^\Q$intdom\E$/,@{$internet_names})) {  
                                     $same_institution = 1;  
                                 }  
                             }  
                         }  
                         $checkedsameinst = 1;  
                     }  
                 }                  }
             }              }
             unless (($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') && (!$fromothercrs)) {              unless (($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') && (!$fromothercrs)) {
                 my (%lockerr,$msg);                   my (%lockerr,$msg); 
                 my ($newurl,$result,$errtext) =                  my ($newurl,$result,$errtext) =
                     &dbcopy(\%info,$coursedom,$coursenum,\%lockerr,\%currltititles,                      &dbcopy(\%info,$coursedom,$coursenum,\%lockerr);
                             \$currltimax,\@updatetoolsenc,\$updatetoolscache,$same_institution);  
                 if ($result eq 'ok') {                  if ($result eq 'ok') {
                     $url = $newurl;                      $url = $newurl;
                     $title=&mt('Copy of').' '.$title;                      $title=&mt('Copy of').' '.$title;
Line 2098  sub do_paste_from_buffer { Line 1803  sub do_paste_from_buffer {
                         $msg = &mt('Paste failed: An error occurred when copying the simple page.').' '.$errtext;                          $msg = &mt('Paste failed: An error occurred when copying the simple page.').' '.$errtext;
                     } elsif ($prefix eq 'bulletinboard') {                      } elsif ($prefix eq 'bulletinboard') {
                         $msg = &mt('Paste failed: An error occurred when copying the discussion board.').' '.$errtext;                          $msg = &mt('Paste failed: An error occurred when copying the discussion board.').' '.$errtext;
                     } elsif ($prefix eq 'ext.tool') {  
                         $msg = &mt('Paste failed: An error occurred when copying the external tool.').' '.$errtext;  
                     }                      }
                     $results{$suffix} = $result;                      $results{$suffix} = $result;
                     $msgerrs{$suffix} = $msg;                      $msgerrs{$suffix} = $msg;
Line 2170  sub do_paste_from_buffer { Line 1873  sub do_paste_from_buffer {
                     &copy_templated_files($url,$srcdom{$suffix},$srcnum{$suffix},$srcmapidx{$suffix},                      &copy_templated_files($url,$srcdom{$suffix},$srcnum{$suffix},$srcmapidx{$suffix},
                                           $coursedom,$coursenum,$template,$newidx,"$folder.$container");                                            $coursedom,$coursenum,$template,$newidx,"$folder.$container");
                 }                  }
             } elsif ($url =~ /ext\.tool$/) {  
                 if (($newidx) && ($folder=~/^default/)) {  
                     my $marker = (split(m{/},$url))[4];  
                     my %toolsettings = &Apache::lonnet::dump('exttool_'.$marker,$coursedom,$coursenum);  
                     my $val = 'no';  
                     if ($toolsettings{'gradable'}) {  
                         $val = 'yes';  
                     }  
                     &LONCAPA::map::storeparameter($newidx,'parameter_0_gradable',$val,  
                                                   'string_yesno');  
                     &remember_parms($newidx,'gradable','set',$val);  
                 }  
             }              }
             $LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url).              $LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url).
                                               ':'.$ext.':normal:res';                                                ':'.$ext.':normal:res';
Line 2258  sub do_paste_from_buffer { Line 1949  sub do_paste_from_buffer {
             }              }
         }          }
     }      }
     if (($updatetoolscache) || (@updatetoolsenc)) {  
         &update_ltitools_caches($coursedom,$coursenum,$updatetoolscache,  
                                 \@updatetoolsenc);  
     }  
     &clear_from_buffer(\@toclear,\@currpaste);      &clear_from_buffer(\@toclear,\@currpaste);
     my $msgsarray;      my $msgsarray;
     foreach my $suffix (keys(%msgs)) {      foreach my $suffix (keys(%msgs)) {
Line 2310  sub clear_from_buffer { Line 1997  sub clear_from_buffer {
     return $numdel;      return $numdel;
 }  }
   
 sub update_ltitools_caches {  
     my ($coursedom,$coursenum,$updatetoolscache,$updatetoolsenc) = @_;  
     my $hashid=$coursedom.'_'.$coursenum;  
     if ($updatetoolscache) {  
         &Apache::lonnet::devalidate_cache_new('courseltitools',$hashid);  
     }  
     if ((ref($updatetoolsenc) eq 'ARRAY') &&  
         (@{$updatetoolsenc})) {  
         my @ids=&Apache::lonnet::current_machine_ids();  
         my $updatedone;  
         foreach my $lonhost (@{$updatetoolsenc}) {  
             if (grep(/^\Q$lonhost\E$/,@ids)) {  
                 unless ($updatedone) {  
                     &Apache::lonnet::devalidate_cache_new('crsltitoolsenc',$hashid);  
                 }  
                 $updatedone = 1;  
             } else {  
                 &Apache::lonnet::remote_devalidate_cache($lonhost,["crsltitoolsenc:$hashid"]);  
             }  
         }  
     }  
     return;  
 }  
   
 sub get_newmap_url {  sub get_newmap_url {
     my ($url,$folder,$prefixchg,$coursedom,$coursenum,$srcdom,$srcnum,      my ($url,$folder,$prefixchg,$coursedom,$coursenum,$srcdom,$srcnum,
         $titleref,$allmaps,$newurls) = @_;          $titleref,$allmaps,$newurls) = @_;
Line 2395  sub get_newmap_url { Line 2058  sub get_newmap_url {
 }  }
   
 sub dbcopy {  sub dbcopy {
     my ($dbref,$coursedom,$coursenum,$lockerrorsref,$currltititles,      my ($dbref,$coursedom,$coursenum,$lockerrorsref) = @_;
         $currltimax,$updatetoolsenc,$updatetoolscache,$same_institution) = @_;  
     my ($url,$result,$errtext);      my ($url,$result,$errtext);
     if (ref($dbref) eq 'HASH') {      if (ref($dbref) eq 'HASH') {
         $url = $dbref->{'src'};          $url = $dbref->{'src'};
         if ($url =~ m{/(smppg|bulletinboard|ext\.tool)$}) {          if ($url =~ m{/(smppg|bulletinboard)$}) {
             my $prefix = $1;              my $prefix = $1;
             if ($prefix eq 'ext.tool') {  
                 $prefix = 'exttool';  
             }  
             if (($dbref->{'cdom'} =~ /^$match_domain$/) &&              if (($dbref->{'cdom'} =~ /^$match_domain$/) &&
                 ($dbref->{'cnum'} =~ /^$match_courseid$/)) {                  ($dbref->{'cnum'} =~ /^$match_courseid$/)) {
                 my $db_name;                  my $db_name;
Line 2415  sub dbcopy { Line 2074  sub dbcopy {
                         &Apache::lonsimplepage::get_db_name($url,$marker,                          &Apache::lonsimplepage::get_db_name($url,$marker,
                                                             $dbref->{'cdom'},                                                              $dbref->{'cdom'},
                                                             $dbref->{'cnum'});                                                              $dbref->{'cnum'});
                 } elsif ($dbref->{'src'} =~ m{/ext\.tool$}) {  
                     $db_name = 'exttool_'.$marker;  
                 } else {                  } else {
                     $db_name = 'bulletinpage_'.$marker;                      $db_name = 'bulletinpage_'.$marker;
                 }                  }
Line 2427  sub dbcopy { Line 2084  sub dbcopy {
                 if (!$suffix) {                  if (!$suffix) {
                     if ($prefix eq 'smppg') {                      if ($prefix eq 'smppg') {
                         $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a simple page [_1].',$url);                          $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a simple page [_1].',$url);
                     } elsif ($prefix eq 'exttool') {  
                         $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying an external tool [_1].',$url);  
                     } else {                      } else {
                         $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a discussion board [_1].',$url);                          $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a discussion board [_1].',$url);
                     }                      }
Line 2440  sub dbcopy { Line 2095  sub dbcopy {
                     my %contents=&Apache::lonnet::dump($db_name,                      my %contents=&Apache::lonnet::dump($db_name,
                                                        $dbref->{'cdom'},                                                         $dbref->{'cdom'},
                                                        $dbref->{'cnum'});                                                         $dbref->{'cnum'});
                     my ($toolcopyerror,$toolpassback,$toolroster,%toolinfo,$oldtoolid,$defincrs);  
                     if ($url eq '/adm/'.$dbref->{'cdom'}.'/'.$dbref->{'cnum'}."/$marker/ext.tool") {  
                         if ($contents{'id'} =~ /^(|c)(\d+)$/) {  
                             $oldtoolid = $2;  
                             if ($1 eq 'c') {  
                                 $defincrs = 1;  
                                 %toolinfo =  
                                     &Apache::lonnet::get('ltitools',[$oldtoolid],$dbref->{'cdom'},$dbref->{'cnum'});  
                             } else {  
                                 %toolinfo= &Apache::lonnet::get_domain_lti($dbref->{'cdom'},'consumer');  
                             }  
                             if (ref($toolinfo{$oldtoolid}) eq 'HASH') {  
                                 if ($toolinfo{$oldtoolid}{'passback'}) {  
                                     $toolpassback = 1;  
                                 }  
                                 if ($toolinfo{$oldtoolid}{'roster'}) {  
                                     $toolroster = 1;  
                                 }  
                             } else {  
                                 $toolcopyerror = 1;  
                                 $errtext = &mt('Could not retrieve original settings for pasted external tool.');  
                             }  
                         }  
                         unless (($dbref->{'cnum'} eq $coursenum) && ($dbref->{'cdom'} eq $coursedom)) {  
                             $url = "/adm/$coursedom/$coursenum/$marker/ext.tool";  
                             if ($contents{'crstitle'} ne '') {  
                                 $contents{'crstitle'} = $env{'course.'.$coursedom.'_'.$coursenum.'.description'};  
                             }  
                             if (($defincrs) && (!$toolcopyerror)) {  
                                 my %newtool;  
                                 my $oldcdom = $dbref->{'cdom'};  
                                 my $oldcnum = $dbref->{'cnum'};  
                                 my $title = $toolinfo{$oldtoolid}{'title'};  
                                 if (ref($currltititles) eq 'HASH') {  
                                     if (exists($currltititles->{$title})) {  
                                         $title .= ' (copied from another course)';  
                                     }  
                                 }  
                                 my ($newid,$iderror) =  
                                     &Apache::lonnet::get_ltitools_id('course',$coursedom,$coursenum,$title);  
                                 if ($newid =~ /^\d+$/) {  
                                     %{$newtool{$newid}} = %{$toolinfo{$oldtoolid}};  
                                     $newtool{$newid}{'title'} = $title;  
                                     if (ref($currltimax)) {  
                                         $newtool{$newid}{'order'} = $$currltimax;  
                                     }  
                                     if ($newtool{$newid}{'image'} =~ m{^\Q/uploaded/$oldcdom/$oldcnum/toollogo/$oldtoolid/\E([^/]+)$}) {  
                                         my $fname = $1;  
                                         my $content = &Apache::lonnet::getfile($newtool{$newid}{'image'});  
                                         if ($content eq '-1') {  
                                             delete($newtool{$newid}{'image'});  
                                         } else {  
                                             $env{'form.'.$suffix.'.image'} = $content;  
                                             my $newlogo =  
                                                 &Apache::lonnet::finishuserfileupload($coursenum,$coursedom,$suffix.'.image',"toollogo/$newid/$fname");  
                                             delete($env{'form.'.$suffix.'.image'});  
                                             if ($newlogo =~ m{^/uploaded/}) {  
                                                 $newtool{$newid}{'image'} = $newlogo;  
                                             } else {  
                                                 delete($newtool{$newid}{'image'});  
                                             }  
                                         }  
                                     }  
                                     my $newusable;  
                                     if ($same_institution) {  
                                         my %oldtoolsenc = &Apache::lonnet::eget('nohist_toolsenc',[$oldtoolid],$oldcdom,$oldcnum);  
                                         if (ref($oldtoolsenc{$oldtoolid}) eq 'HASH') {  
                                             my %newtoolsenc;  
                                             %{$newtoolsenc{$newid}} = %{$oldtoolsenc{$oldtoolid}};  
                                             my $putres = &Apache::lonnet::put('nohist_toolsenc',\%newtoolsenc,$coursedom,$coursenum,1);  
                                             if ($putres eq 'ok') {  
                                                 if (ref($updatetoolsenc) eq 'ARRAY') {  
                                                     my $newhome = &Apache::lonnet::homeserver($coursenum,$coursedom);  
                                                     unless (grep(/^\Q$newhome\E$/,@{$updatetoolsenc})) {  
                                                         push(@{$updatetoolsenc},$newhome);  
                                                     }  
                                                 }  
                                                 $newusable = 1;  
                                             }  
                                         }  
                                     }  
                                     if ($newtool{$newid}{'usable'}) {  
                                         unless ($newusable) {  
                                             delete($newtool{$newid}{'usable'});  
                                         }  
                                     }  
                                     my $putres = &Apache::lonnet::put('ltitools',\%newtool,$coursedom,$coursenum);  
                                     if ($putres eq 'ok') {  
                                         $contents{'id'} = "c$newid";  
                                         if (ref($updatetoolscache)) {  
                                             $$updatetoolscache ++;  
                                         }  
                                         if (ref($currltititles->{$title}) eq 'ARRAY') {  
                                             push(@{$currltititles->{$title}},$newid);  
                                         } else {  
                                             $currltititles->{$title} = [$newid];  
                                         }  
                                         if (ref($currltimax)) {  
                                             $$currltimax ++;  
                                         }  
                                     } else {  
                                         $toolcopyerror = 1;  
                                         $errtext = &mt('Unable to save external tool definition in Course Settings.');  
                                     }  
                                 } else {  
                                     $toolcopyerror = 1;  
                                     $errtext = &mt('Unable to retrieve new tool ID when adding external tool definition to Course Settings.');  
                                 }  
                             }  
                         }  
                     }  
                     if (exists($contents{'uploaded.photourl'})) {                      if (exists($contents{'uploaded.photourl'})) {
                         my $photo = $contents{'uploaded.photourl'};                          my $photo = $contents{'uploaded.photourl'};
                         my ($subdir,$fname) =                          my ($subdir,$fname) =
Line 2570  sub dbcopy { Line 2114  sub dbcopy {
                         }                          }
                     }                      }
                     $db_name =~ s{_\d*$ }{_$suffix}x;                      $db_name =~ s{_\d*$ }{_$suffix}x;
                     if ($prefix eq 'exttool') {                      $result=&Apache::lonnet::put($db_name,\%contents,
                         unless ($toolcopyerror) {                                                   $coursedom,$coursenum);
                             foreach my $key ('oldgradesecret','gradesecret','gradesecretdate','oldrostersecret','rostersecret','rostersecretdate') {                      if ($result eq 'ok') {
                                 if (exists($contents{$key})) {                          $url =~ s{/(\d*)/(smppg|bulletinboard)$}{/$suffix/$2}x;
                                     delete($contents{$key});  
                                 }  
                             }  
                             if ($dbref->{'delgradable'}) {  
                                 if (exists($contents{'gradable'})) {  
                                     delete($contents{'gradable'});  
                                 }  
                             }  
                             if ($toolpassback) {  
                                 if ($contents{'gradable'}) {  
                                     my $gradesecret = UUID::Tiny::create_uuid_as_string(UUID_V4);  
                                     $contents{'gradesecret'} = $gradesecret;  
                                     $contents{'gradesecretdate'} = time;  
                                 }  
                             }  
                             if ($toolroster) {  
                                 my $rostersecret = UUID::Tiny::create_uuid_as_string(UUID_V4);  
                                 $contents{'rostersecret'} = $rostersecret;  
                                 $contents{'rostersecretdate'} = time;  
                             }  
                         }  
                     }  
                     if (($prefix eq 'exttool') && ($toolcopyerror)) {  
                         $result = 'error';  
                     } else {  
                         $result=&Apache::lonnet::put($db_name,\%contents,  
                                                      $coursedom,$coursenum);  
                         if ($result eq 'ok') {  
                             $url =~ s{/(\d*)/(smppg|bulletinboard|ext\.tool)$}{/$suffix/$2}x;  
                         }  
                     }                      }
                 }                  }
                 if (($freedlock ne 'ok') && (ref($lockerrorsref) eq 'HASH')) {                  if (($freedlock ne 'ok') && (ref($lockerrorsref) eq 'HASH')) {
Line 2613  sub dbcopy { Line 2127  sub dbcopy {
                     if ($prefix eq 'smppg') {                      if ($prefix eq 'smppg') {
                         $lockerrorsref->{$prefix} .=                          $lockerrorsref->{$prefix} .=
                             ' '.&mt('This will prevent creation of additional simple pages in this course.');                              ' '.&mt('This will prevent creation of additional simple pages in this course.');
                     } elsif ($prefix eq 'exttool') {  
                         $lockerrorsref->{$prefix} .=  
                             ' '.&mt('This will prevent addition of more external tools to this course.');  
                     } else {                      } else {
                         $lockerrorsref->{$prefix} .= ' '.&mt('This will prevent creation of additional discussion boards in this course.');                          $lockerrorsref->{$prefix} .= ' '.&mt('This will prevent creation of additional discussion boards in this course.');
                     }                      }
Line 2747  sub uniqueness_check { Line 2258  sub uniqueness_check {
 }  }
   
 sub contained_map_check {  sub contained_map_check {
     my ($url,$folder,$coursenum,$coursedom,$removefrommap,$removeparam,$addedmaps,      my ($url,$folder,$removefrommap,$removeparam,$addedmaps,$hierarchy,$titles,
         $hierarchy,$titles,$allmaps) = @_;          $allmaps) = @_;
     my $content = &Apache::lonnet::getfile($url);      my $content = &Apache::lonnet::getfile($url);
     unless ($content eq '-1') {      unless ($content eq '-1') {
         my $parser = HTML::TokeParser->new(\$content);          my $parser = HTML::TokeParser->new(\$content);
Line 2758  sub contained_map_check { Line 2269  sub contained_map_check {
             if ($token->[1] eq 'resource') {              if ($token->[1] eq 'resource') {
                 next if ($token->[2]->{'type'} eq 'zombie');                  next if ($token->[2]->{'type'} eq 'zombie');
                 my $ressrc = $token->[2]->{'src'};                  my $ressrc = $token->[2]->{'src'};
                 if ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/ext\.tool$}) {                  if ($folder =~ /^supplemental/) {
                     my ($srcdom,$srcnum,$marker) = ($1,$2,$3);  
                     unless ($srcdom eq $coursedom) {  
                         $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;  
                         next;  
                     }  
                     unless ($srcnum eq $coursenum) {  
                         my %toolsettings =  
                             &Apache::lonnet::dump('exttool_'.$marker,$srcdom,$srcnum);  
                         my %tooltypes = &Apache::loncommon::usable_exttools();  
                         if ((($toolsettings{'id'} =~ /^c\d+$/) && (!$tooltypes{'crs'})) ||  
                             (($toolsettings{'id'} =~ /^\d+$/) && (!$tooltypes{'dom'}))) {  
                             $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;  
                             next;  
                         }  
                     }  
                 } elsif ($folder =~ /^supplemental/) {  
                     unless (&supp_pasteable($ressrc)) {                      unless (&supp_pasteable($ressrc)) {
                         $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;                          $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
                         next;                          next;
Line 2793  sub contained_map_check { Line 2288  sub contained_map_check {
                             $addedmaps->{$ressrc} = [$url];                              $addedmaps->{$ressrc} = [$url];
                         }                          }
                     }                      }
                     &contained_map_check($ressrc,$folder,$coursenum,$coursedom,                      &contained_map_check($ressrc,$folder,$removefrommap,$removeparam,
                                          $removefrommap,$removeparam,  
                                          $addedmaps,$hierarchy,$titles,$allmaps);                                           $addedmaps,$hierarchy,$titles,$allmaps);
                 }                  }
             } elsif ($token->[1] eq 'param') {              } elsif ($token->[1] eq 'param') {
Line 2897  sub url_paste_fixups { Line 2391  sub url_paste_fixups {
                         $changed = 1;                          $changed = 1;
                     }                      }
                 }                  }
             } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/(.+)$}) {              } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/.+$}) {
                 next if ($skip);                  next if ($skip);
                 my $srcdom = $1;                  my $srcdom = $1;
                 my $srcnum = $2;                  my $srcnum = $2;
                 my $rem = $3;  
                 my ($is_exttool,$exttoolchg);  
                 if ($rem =~ m{\d+/ext\.tool$}) {  
                     $is_exttool = 1;  
                 }  
                 if (($srcdom ne $cdom) || ($srcnum ne $cnum)) {                  if (($srcdom ne $cdom) || ($srcnum ne $cnum)) {
                     $rewrites->{$oldurl}{$id} = $ressrc;                      $rewrites->{$oldurl}{$id} = $ressrc;
                     $dbcopies->{$oldurl}{$id}{'src'} = $ressrc;                      $dbcopies->{$oldurl}{$id}{'src'} = $ressrc;
                     $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom;                      $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom;
                     $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum;                      $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum;
                     $changed = 1;                      $changed = 1;
                     if ($is_exttool) {  
                         $exttoolchg = 1;  
                     }  
                 } elsif (($is_exttool) &&  
                          ($env{'form.docs.markedcopy_options'} ne 'move')) {  
                     $dbcopies->{$oldurl}{$id}{'src'} = $ressrc;  
                     $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom;  
                     $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum;  
                     $changed = 1;  
                     $exttoolchg = 1;  
                 }  
                 if (($is_exttool) && ($prefixchg)) {  
                     if ($oldurl =~ m{^/uploaded/$match_domain/$match_courseid/default}) {  
                         if ($exttoolchg) {  
                             $dbcopies->{$oldurl}{$id}{'delgradable'} = 1;  
                         }  
                     }  
                 }                  }
             } elsif ($ressrc =~ m{^/adm/$match_domain/$match_username/\d+/(smppg|bulletinboard)$}) {              } elsif ($ressrc =~ m{^/adm/$match_domain/$match_username/\d+/(smppg|bulletinboard)$}) {
                 if (($fromcdom ne $cdom) || ($fromcnum ne $cnum) ||                  if (($fromcdom ne $cdom) || ($fromcnum ne $cnum) ||
Line 2975  sub apply_fixups { Line 2447  sub apply_fixups {
         $oldurl,$url,$caller) = @_;          $oldurl,$url,$caller) = @_;
     my (%rewrites,%zombies,%removefrommap,%removeparam,%dbcopies,%retitles,      my (%rewrites,%zombies,%removefrommap,%removeparam,%dbcopies,%retitles,
         %params,%newsubdir,%before,%after,%copies,%docmoves,%mapmoves,@msgs,          %params,%newsubdir,%before,%after,%copies,%docmoves,%mapmoves,@msgs,
         %resdatacopy,%lockerrors,$lockmsg,%currcrsltitools,$gotcrsltitools,          %resdatacopy,%lockerrors,$lockmsg);
         %currltititles,$currltimax);  
     $currltimax = 0;  
     if (ref($updated) eq 'HASH') {      if (ref($updated) eq 'HASH') {
         if (ref($updated->{'rewrites'}) eq 'HASH') {          if (ref($updated->{'rewrites'}) eq 'HASH') {
             %rewrites = %{$updated->{'rewrites'}};              %rewrites = %{$updated->{'rewrites'}};
Line 3093  sub apply_fixups { Line 2563  sub apply_fixups {
             $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/;              $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/;
         }          }
         my $mapcontent = &Apache::lonnet::getfile($key);          my $mapcontent = &Apache::lonnet::getfile($key);
         if (($mapcontent eq '-1') && ($before{'map'} eq 'supplemental') &&  
             ($after{'map'} eq 'default') &&  
             ($key =~ m{^/uploaded/$match_domain/$match_courseid/supplemental_\d+\.sequence$})) {  
             $mapcontent = '<map>'."\n".  
                           '<resource id="1" src="" type="start" />'."\n".  
                           '<link from="1" to="2" index="1" />'."\n".  
                           '<resource id="2" src="" type="finish" />'."\n".  
                           '</map>';  
         }  
         if ($mapcontent eq '-1') {          if ($mapcontent eq '-1') {
             if (ref($errors) eq 'HASH') {              if (ref($errors) eq 'HASH') {
                 $errors->{$key} = 1;                  $errors->{$key} = 1;
Line 3128  sub apply_fixups { Line 2589  sub apply_fixups {
                 }                  }
             }              }
         }          }
         my ($updatetoolscache,@updatetoolsenc,$same_institution,$checkedsameinst);  
         foreach my $key (keys(%updates)) {          foreach my $key (keys(%updates)) {
             my (%torewrite,%toretitle,%toremove,%remparam,%currparam,%zombie,%newdb);              my (%torewrite,%toretitle,%toremove,%remparam,%currparam,%zombie,%newdb);
             if (ref($rewrites{$key}) eq 'HASH') {              if (ref($rewrites{$key}) eq 'HASH') {
Line 3149  sub apply_fixups { Line 2609  sub apply_fixups {
             if (ref($dbcopies{$key}) eq 'HASH') {              if (ref($dbcopies{$key}) eq 'HASH') {
                 foreach my $idx (keys(%{$dbcopies{$key}})) {                  foreach my $idx (keys(%{$dbcopies{$key}})) {
                     if (ref($dbcopies{$key}{$idx}) eq 'HASH') {                      if (ref($dbcopies{$key}{$idx}) eq 'HASH') {
                         my $oldurl = $dbcopies{$key}{$idx}{'src'};  
                         my $oldcdom = $dbcopies{$key}{$idx}{'cdom'};  
                         my $oldcnum = $dbcopies{$key}{$idx}{'cnum'};  
                         my $oldmarker;  
                         if ($oldurl =~ m{^\Q/adm/$oldcdom/$oldcnum/\E(\d+)/ext\.tool$}) {  
                             $oldmarker = $1;  
                             unless (($gotcrsltitools) ||  
                                     (($oldcnum eq $cnum) && ($oldcdom eq $cdom))) {  
                                 my %oldtoolsettings=&Apache::lonnet::dump('exttool_'.$oldmarker,$oldcdom,$oldcnum);  
                                 if ($oldtoolsettings{'id'} =~ /^c\d+$/) {  
                                     unless ($gotcrsltitools) {  
                                         %currcrsltitools =  
                                             &Apache::lonnet::get_course_lti($cnum,$cdom,'consumer');  
                                         foreach my $item (sort(keys(%currcrsltitools))) {  
                                             if (ref($currcrsltitools{$item}) eq 'HASH') {  
                                                 $currltimax ++;  
                                                 if (ref($currltititles{$currcrsltitools{$item}{'title'}}) eq 'ARRAY') {  
                                                     push(@{$currltititles{$currcrsltitools{$item}{'title'}}},$item);  
                                                 } else {  
                                                     $currltititles{$currcrsltitools{$item}{'title'}} = [$item];  
                                                 }  
                                             }  
                                         }  
                                         $gotcrsltitools = 1;  
                                     }  
                                     unless ($checkedsameinst) {  
                                         my $primary_id = &Apache::lonnet::domain($cdom,'primary');  
                                         my $intdom = &Apache::lonnet::internet_dom($primary_id);  
                                         if ($intdom ne '') {  
                                             my $internet_names =  
                                                 &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});  
                                             if (ref($internet_names) eq 'ARRAY') {  
                                                 if (grep(/^\Q$intdom\E$/,@{$internet_names})) {  
                                                     $same_institution = 1;  
                                                 }  
                                             }  
                                         }  
                                         $checkedsameinst = 1;  
                                     }  
                                 }  
                             }  
                         }  
                         my ($newurl,$result,$errtext) =                          my ($newurl,$result,$errtext) =
                             &dbcopy($dbcopies{$key}{$idx},$cdom,$cnum,\%lockerrors,\%currltititles,                              &dbcopy($dbcopies{$key}{$idx},$cdom,$cnum,\%lockerrors);
                                     \$currltimax,\@updatetoolsenc,\$updatetoolscache,$same_institution);  
                         if ($result eq 'ok') {                          if ($result eq 'ok') {
                             $newdb{$idx} = $newurl;                              $newdb{$idx} = $newurl;
                             if ($newurl =~ /ext\.tool$/) {  
                                 if ($torewrite{$idx} eq "/adm/$oldcdom/$oldcnum/$oldmarker/ext.tool") {  
                                     if ($newurl =~ m{^\Q/adm/$cdom/$cnum/\E(\d+)/ext.tool$}) {  
                                         my $newmarker = $1;  
                                         unless ($oldmarker eq $newmarker) {  
                                             $torewrite{$idx} = "/adm/$oldcdom/$oldcnum/$newmarker/ext.tool";  
                                         }  
                                     }  
                                 }  
                             }  
                         } elsif (ref($errors) eq 'HASH') {                          } elsif (ref($errors) eq 'HASH') {
                             $errors->{$key} = 1;                              $errors->{$key} = 1;
                         }                          }
Line 3344  sub apply_fixups { Line 2751  sub apply_fixups {
                 }                  }
             }              }
         }          }
         if (($updatetoolscache) || (@updatetoolsenc)) {  
             &update_ltitools_caches($cdom,$cnum,$updatetoolscache,  
                                     \@updatetoolsenc);  
         }  
     }      }
     return ('ok',\@msgs,$lockmsg);      return ('ok',\@msgs,$lockmsg);
 }  }
Line 3442  sub update_parameter { Line 2845  sub update_parameter {
             my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);              my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
             $name=&LONCAPA::map::qtescape($name);              $name=&LONCAPA::map::qtescape($name);
             $url=&LONCAPA::map::qtescape($url);              $url=&LONCAPA::map::qtescape($url);
             next unless $url;              next unless ($url);
             my $is_map;              my $is_map;
             if ($url =~ m{/uploaded/.+\.(page|sequence)$}) {              if ($url =~ m{/uploaded/.+\.(page|sequence)$}) {
                 $is_map = 1;                  $is_map = 1;
Line 3527  sub update_parameter { Line 2930  sub update_parameter {
   
 sub handle_edit_cmd {  sub handle_edit_cmd {
     my ($coursenum,$coursedom) =@_;      my ($coursenum,$coursedom) =@_;
     my $haschanges = 0;  
     if ($env{'form.cmd'} eq '') {      if ($env{'form.cmd'} eq '') {
         return $haschanges;          return 0;
     }      }
     my ($cmd,$idx)=split('_',$env{'form.cmd'});      my ($cmd,$idx)=split('_',$env{'form.cmd'});
   
Line 3544  sub handle_edit_cmd { Line 2946  sub handle_edit_cmd {
     &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);      &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);
  }   }
  splice(@LONCAPA::map::order, $idx, 1);   splice(@LONCAPA::map::order, $idx, 1);
         $haschanges = 1;  
     } elsif ($cmd eq 'cut') {      } elsif ($cmd eq 'cut') {
  &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);   &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);
  splice(@LONCAPA::map::order, $idx, 1);   splice(@LONCAPA::map::order, $idx, 1);
         $haschanges = 1;  
     } elsif ($cmd eq 'up'      } elsif ($cmd eq 'up'
      && ($idx) && (defined($LONCAPA::map::order[$idx-1]))) {       && ($idx) && (defined($LONCAPA::map::order[$idx-1]))) {
  @LONCAPA::map::order[$idx-1,$idx] = @LONCAPA::map::order[$idx,$idx-1];   @LONCAPA::map::order[$idx-1,$idx] = @LONCAPA::map::order[$idx,$idx-1];
         $haschanges = 1;  
     } elsif ($cmd eq 'down'      } elsif ($cmd eq 'down'
      && defined($LONCAPA::map::order[$idx+1])) {       && defined($LONCAPA::map::order[$idx+1])) {
  @LONCAPA::map::order[$idx+1,$idx] = @LONCAPA::map::order[$idx,$idx+1];   @LONCAPA::map::order[$idx+1,$idx] = @LONCAPA::map::order[$idx,$idx+1];
         $haschanges = 1;  
     } elsif ($cmd eq 'rename') {      } elsif ($cmd eq 'rename') {
  my $comment = &LONCAPA::map::qtunescape($env{'form.title'});   my $comment = &LONCAPA::map::qtunescape($env{'form.title'});
  if ($comment=~/\S/) {   if ($comment=~/\S/) {
Line 3566  sub handle_edit_cmd { Line 2968  sub handle_edit_cmd {
 # Devalidate title cache  # Devalidate title cache
  my $renamed_url=&LONCAPA::map::qtescape($url);   my $renamed_url=&LONCAPA::map::qtescape($url);
  &Apache::lonnet::devalidate_title_cache($renamed_url);   &Apache::lonnet::devalidate_title_cache($renamed_url);
         $haschanges = 1;  
       } else {
    return 0;
     }      }
     return $haschanges;      return 1;
 }  }
   
 sub editor {  sub editor {
     my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype,      my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype,
         $supplementalflag,$orderhash,$iconpath,$pathitem,$ltitoolsref,          $supplementalflag,$orderhash,$iconpath,$pathitem,$canedit,
         $canedit,$hostname,$navmapref,$hiddentop)=@_;          $hostname,$navmapref,$hiddentop)=@_;
     my ($randompick,$ishidden,$isencrypted,$plain,$is_random_order,$container);      my ($randompick,$ishidden,$isencrypted,$plain,$is_random_order,$container);
     if ($allowed) {      if ($allowed) {
         (my $breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,          (my $breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,
Line 3785  sub editor { Line 3189  sub editor {
                         } else {                          } else {
                             return $errortxt;                              return $errortxt;
                         }                          }
                     } elsif ($url =~ m{^/adm/$coursedom/$coursenum/new/ext\.tool}) {  
                         my ($suffix,$errortxt,$locknotfreed) =  
                             &new_timebased_suffix($coursedom,$coursenum,'exttool');  
                         if ($locknotfreed) {  
                             $r->print($locknotfreed);  
                         }  
                         if ($suffix) {  
                             $url =~ s{^(/adm/$coursedom/$coursenum)/new}{$1/$suffix};  
                         } else {  
                             return $errortxt;  
                         }  
                     } elsif ($url =~ m{^/uploaded/$coursedom/$coursenum/(docs|supplemental)/(default|\d+)/new.html$}) {                      } elsif ($url =~ m{^/uploaded/$coursedom/$coursenum/(docs|supplemental)/(default|\d+)/new.html$}) {
                         if ($supplementalflag) {                          if ($supplementalflag) {
                             next unless ($1 eq 'supplemental');                              next unless ($1 eq 'supplemental');
Line 3818  sub editor { Line 3211  sub editor {
     }      }
             ($errtext,$fatal,my $fixuperrors) =              ($errtext,$fatal,my $fixuperrors) =
                 &group_import($coursenum, $coursedom, $folder,$container,                  &group_import($coursenum, $coursedom, $folder,$container,
                               'londocs',$ltitoolsref,@imports);                                'londocs',@imports);
     return $errtext if ($fatal);      return $errtext if ($fatal);
             if ($fixuperrors) {              if ($fixuperrors) {
                 $r->print($fixuperrors);                  $r->print($fixuperrors);
Line 3878  sub editor { Line 3271  sub editor {
         $r->print('</div>');          $r->print('</div>');
     }      }
   
     if ((!$allowed) && ($folder =~ /^supplemental_\d+$/)) {  
         my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);  
         if (ref($supplemental) eq 'HASH') {  
             if ((ref($supplemental->{'hidden'}) eq 'HASH') &&  
                 (ref($supplemental->{'ids'}) eq 'HASH')) {  
                 if (ref($supplemental->{'ids'}->{"/uploaded/$coursedom/$coursenum/$folder.$container"}) eq 'ARRAY') {  
                     my $mapnum = $supplemental->{'ids'}->{"/uploaded/$coursedom/$coursenum/$folder.$container"}->[0];  
                     if ($supplemental->{'hidden'}->{$mapnum}) {  
                         $ishidden = 1;  
                     }  
                 }  
             }  
         }  
     }  
   
     my ($to_show,$output,@allidx,@allmapidx,%filters,%lists,%curr_groups);      my ($to_show,$output,@allidx,@allmapidx,%filters,%lists,%curr_groups);
     %filters =  (      %filters =  (
                   canremove      => [],                    canremove      => [],
Line 3916  sub editor { Line 3294  sub editor {
             push(@allmapidx,$res);              push(@allmapidx,$res);
         }          }
   
         if (($supplementalflag) && (!$allowed) && (!$env{'request.role.adv'})) {  
             if (($ishidden) || ((&LONCAPA::map::getparameter($res,'parameter_hiddenresource'))[0]=~/^yes$/i)) {  
                 $idx++;  
                 next;  
             }  
         }  
         $output .= &entryline($idx,$name,$url,$folder,$allowed,$res,          $output .= &entryline($idx,$name,$url,$folder,$allowed,$res,
                               $coursenum,$coursedom,$crstype,                                $coursenum,$coursedom,$crstype,
                               $pathitem,$supplementalflag,$container,                                $pathitem,$supplementalflag,$container,
                               \%filters,\%curr_groups,$ltitoolsref,$canedit,                                \%filters,\%curr_groups,$canedit,
                               $isencrypted,$ishidden,$navmapref,$hostname);                                $isencrypted,$navmapref,$hostname);
         $idx++;          $idx++;
         $shown++;          $shown++;
     }      }
Line 3935  sub editor { Line 3307  sub editor {
     my $need_save;      my $need_save;
     if ($allowed || ($supplementalflag && $folder eq 'supplemental')) {      if ($allowed || ($supplementalflag && $folder eq 'supplemental')) {
         my $toolslink;          my $toolslink;
         if ($allowed || $canedit) {          if ($allowed) {
             my $helpitem = 'Navigation_Screen';  
             if (!$allowed) {  
                 $helpitem = 'Supplemental_Navigation';  
             }  
             $toolslink = '<table><tr><td>'              $toolslink = '<table><tr><td>'
                        .&Apache::loncommon::help_open_menu('Navigation Screen',                         .&Apache::loncommon::help_open_menu('Navigation Screen',
                                                            $helpitem,undef,'RAT')                                                             'Navigation_Screen',undef,'RAT')
                        .'</td><td class="LC_middle">'.&mt('Tools:').'</td>'                         .'</td><td class="LC_middle">'.&mt('Tools:').'</td>'
                        .'<td align="left"><ul id="LC_toolbar">'                         .'<td align="left"><ul id="LC_toolbar">'
                        .'<li><a href="/adm/coursedocs?forcesupplement=1&amp;command=editsupp" '                         .'<li><a href="/adm/coursedocs?forcesupplement=1&amp;command=editsupp" '
Line 3958  sub editor { Line 3326  sub editor {
                           .&Apache::loncommon::start_data_table_header_row()                            .&Apache::loncommon::start_data_table_header_row()
                           .'<th colspan="2">'.&mt('Move').'</th>'                            .'<th colspan="2">'.&mt('Move').'</th>'
                           .'<th colspan="2">'.&mt('Actions').'</th>'                            .'<th colspan="2">'.&mt('Actions').'</th>'
                           .'<th>'.&mt('Document').'</th>'                            .'<th>'.&mt('Document').'</th>';
                           .'<th colspan="2">'.&mt('Settings').'</th>'                  if ($folder !~ /^supplemental/) {
                           .&Apache::loncommon::end_data_table_header_row();                      $to_show .= '<th colspan="4">'.&mt('Settings').'</th>';
                   }
                   $to_show .= &Apache::loncommon::end_data_table_header_row();
                 if ($folder !~ /^supplemental/) {                  if ($folder !~ /^supplemental/) {
                     $lists{'canhide'} = join(',',@allidx);                      $lists{'canhide'} = join(',',@allidx);
                     $lists{'canrandomlyorder'} = join(',',@allmapidx);                      $lists{'canrandomlyorder'} = join(',',@allmapidx);
Line 3988  sub editor { Line 3358  sub editor {
                                 '</td>'.                                  '</td>'.
                                 '<td>&nbsp;</td>'.                                  '<td>&nbsp;</td>'.
                                 '<td>&nbsp;</td>'.                                  '<td>&nbsp;</td>'.
                                 '<td colspan="2">'.                                  '<td colspan="4">'.
                                 &multiple_check_form('settings',\%lists,$canedit).                                  &multiple_check_form('settings',\%lists,$canedit).
                                 '</td>'.                                  '</td>'.
                                 &Apache::loncommon::end_data_table_row();                                  &Apache::loncommon::end_data_table_row();
Line 4057  sub multiple_check_form { Line 3427  sub multiple_check_form {
     return unless (ref($listsref) eq 'HASH');      return unless (ref($listsref) eq 'HASH');
     my $disabled;      my $disabled;
     unless ($canedit) {      unless ($canedit) {
         $disabled = ' disabled="disabled"';          $disabled = 'disabled="disabled"';
     }      }
     my $output =      my $output =
     '<form action="/adm/coursedocs" method="post" name="togglemult'.$caller.'">'.      '<form action="/adm/coursedocs" method="post" name="togglemult'.$caller.'">'.
Line 4307  sub is_supplemental_title { Line 3677  sub is_supplemental_title {
 sub entryline {  sub entryline {
     my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom,      my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom,
         $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups,          $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups,
         $ltitoolsref,$canedit,$isencrypted,$ishidden,$navmapref,$hostname)=@_;          $canedit,$isencrypted,$navmapref,$hostname)=@_;
     my ($foldertitle,$renametitle,$oldtitle,$encodedtitle);      my ($foldertitle,$renametitle,$oldtitle);
     if (&is_supplemental_title($title)) {      if (&is_supplemental_title($title)) {
  ($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title);   ($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title);
         $encodedtitle=$title;  
     } else {      } else {
  $title=&HTML::Entities::encode($title,'"<>&\'');   $title=&HTML::Entities::encode($title,'"<>&\'');
         $encodedtitle=$title;  
  $renametitle=$title;   $renametitle=$title;
  $foldertitle=$title;   $foldertitle=$title;
     }      }
Line 4336  sub entryline { Line 3704  sub entryline {
     my $line=&Apache::loncommon::start_data_table_row();      my $line=&Apache::loncommon::start_data_table_row();
     my ($form_start,$form_end,$form_common,$form_param);      my ($form_start,$form_end,$form_common,$form_param);
 # Edit commands  # Edit commands
     my ($esc_path, $path, $symb, $shownsymb);      my ($esc_path, $path, $symb);
     if ($env{'form.folderpath'}) {      if ($env{'form.folderpath'}) {
  $esc_path=&escape($env{'form.folderpath'});   $esc_path=&escape($env{'form.folderpath'});
  $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');   $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
Line 4406  END Line 3774  END
  'rn' => 'Rename',   'rn' => 'Rename',
  'cp' => 'Copy',   'cp' => 'Copy',
                 'ex' => 'External Resource',                  'ex' => 'External Resource',
                 'et' => 'External Tool',  
                 'ed' => 'Edit',                  'ed' => 'Edit',
                 'pr' => 'Preview',                  'pr' => 'Preview',
                 'sv' => 'Save',                  'sv' => 'Save',
Line 4426  END Line 3793  END
     |/aboutme$      |/aboutme$
     |/navmaps$      |/navmaps$
     |/bulletinboard$      |/bulletinboard$
                             |/ext\.tool$  
     |\.html$)}x)      |\.html$)}x)
              || $isexternal) {               || $isexternal) {
     $skip_confirm = 1;      $skip_confirm = 1;
Line 4536  END Line 3902  END
     my $ispage;      my $ispage;
     my $containerarg;      my $containerarg;
     my $folderurl;      my $folderurl;
     my $plainurl;  
     if ($uploaded) {      if ($uploaded) {
         if (($extension eq 'sequence') || ($extension eq 'page')) {          if (($extension eq 'sequence') || ($extension eq 'page')) {
             $url=~/\Q$coursenum\E\/([\/\w]+)\.\Q$extension\E$/;              $url=~/\Q$coursenum\E\/([\/\w]+)\.\Q$extension\E$/;
Line 4555  END Line 3920  END
                 $url='/adm/supplemental?';                  $url='/adm/supplemental?';
             }              }
  } else {   } else {
             $plainurl = $url;      &Apache::lonnet::allowuploaded('/adm/coursedoc',$url);
  }   }
     }      }
   
Line 4594  END Line 3959  END
                 if (($ENV{'SERVER_PORT'} == 443) && ($exturl !~ /^https:/)) {                  if (($ENV{'SERVER_PORT'} == 443) && ($exturl !~ /^https:/)) {
                     $nomodal = 1;                      $nomodal = 1;
                 }                  }
             } elsif ($url=~m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) {  
                 $url='/adm/wrapper'.$url;  
             } elsif ($url eq "/public/$coursedom/$coursenum/syllabus") {              } elsif ($url eq "/public/$coursedom/$coursenum/syllabus") {
                 if (($ENV{'SERVER_PORT'} == 443) &&                  if (($ENV{'SERVER_PORT'} == 443) &&
                     ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) {                      ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) {
Line 4605  END Line 3968  END
                     $nomodal = 1;                      $nomodal = 1;
                 }                  }
     }      }
             my $checkencrypt;              if (&Apache::lonnet::symbverify($symb,$url)) {
             if (!$env{'request.role.adv'}) {                  my $shownsymb = $symb;
                   if ($isexternal) {
                       $url =~ s/\#[^#]+$//;
                       if ($container eq 'page') {
                           $url = &Apache::lonnet::clutter($url);
                       }
                   }
                   unless ($env{'request.role.adv'}) {
                       if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
                           $url = '';
                       }
                       if (&Apache::lonnet::EXT('resource.0.hiddenresource',$symb) =~ /^yes$/i) {
                           $url = '';
                           $hiddenres = 1;
                       }
                   }
                   if ($url ne '') {
                       $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($shownsymb);
                   }
               } elsif (!$env{'request.role.adv'}) {
                   my $checkencrypt;
                 if (((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) ||                  if (((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) ||
                     ($isencrypted) || (&Apache::lonnet::EXT('resource.0.encrypturl',$symb) =~ /^yes$/i)) {                        $isencrypted || (&Apache::lonnet::EXT('resource.0.encrypturl',$symb) =~ /^yes$/i)) {
                     $checkencrypt = 1;                      $checkencrypt = 1;
                 } elsif (ref($navmapref)) {                  } elsif (ref($navmapref)) {
                     unless (ref($$navmapref)) {                      unless (ref($$navmapref)) {
Line 4620  END Line 4003  END
                         }                          }
                     }                      }
                 }                  }
             }                  if ($checkencrypt) {
             if ($checkencrypt) {                      my $shownsymb = &Apache::lonenc::encrypted($symb);
                 my $currenc = $env{'request.enc'};                      my $shownurl = &Apache::lonenc::encrypted($url);
                 $env{'request.enc'} = 1;                      if (&Apache::lonnet::symbverify($shownsymb,$shownurl)) {
                 $shownsymb = &Apache::lonenc::encrypted($symb);                          $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&escape($shownsymb);
                 my $shownurl = &Apache::lonenc::encrypted($url);                          if ($env{'request.enc'} ne '') {
                 if (&Apache::lonnet::symbverify($symb,$url)) {                              delete($env{'request.enc'});
                     $url = $shownurl;                          }
                 } else {                      } else {
                     $url = '';                          $url='';
                 }  
                 $env{'request.enc'} = $currenc;  
             } elsif (&Apache::lonnet::symbverify($symb,$url)) {  
                 $shownsymb = $symb;  
                 if ($isexternal) {  
                     $url =~ s/\#[^#]+$//;  
                     if ($container eq 'page') {  
                         $url = &Apache::lonnet::clutter($url);  
                     }                      }
                   } else {
                       $url='';
                 }                  }
             } else {              } else {
                 $url = '';                  $url='';
             }  
             unless ($env{'request.role.adv'}) {  
                 if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {  
                     $url = '';  
                 }  
                 if (&Apache::lonnet::EXT('resource.0.hiddenresource',$symb) =~ /^yes$/i) {  
                     $url = '';  
                     $hiddenres = 1;  
                 }  
             }  
             if (($url ne '') && ($shownsymb ne '')) {  
                 $url .= (($url=~/\?/)?'&':'?').'symb='.&escape($shownsymb);  
             }              }
  }   }
     } elsif ($supplementalflag) {      } elsif ($supplementalflag) {
Line 4682  END Line 4047  END
                 }                  }
                 $nomodal = 1;                  $nomodal = 1;
             }              }
         } elsif (($uploaded) && ($url ne '/adm/supplemental?') && ($url ne '/adm/coursedocs?')) {  
             my $embstyle=&Apache::loncommon::fileembstyle($extension);  
             unless ($embstyle eq 'ssi') {  
                 if (($embstyle eq 'img')  
                  || ($embstyle eq 'emb')  
                  || ($embstyle eq 'wrp')) {  
                     $url='/adm/wrapper'.$url;  
                 } elsif ($url !~ /\.(sequence|page)$/) {  
                     $url='/adm/coursedocs/showdoc'.$url;  
                 }  
             }  
         }  
         unless ($allowed && $env{'request.role.adv'}) {  
             if ($ishidden || (&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {  
                 $hiddenres = 1;  
             }  
         }          }
     }      }
     my ($rand_pick_text,$rand_order_text,$hiddenfolder);      my ($rand_pick_text,$rand_order_text,$hiddenfolder);
Line 4709  END Line 4058  END
         if (!$allowed && $supplementalflag) {          if (!$allowed && $supplementalflag) {
             $folderpath.=$containerarg.'&'.$foldername;              $folderpath.=$containerarg.'&'.$foldername;
             $url.='folderpath='.&escape($folderpath);              $url.='folderpath='.&escape($folderpath);
             if ($ishidden || (&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {  
                 $hiddenfolder = 1;  
             }  
         } else {          } else {
             my $rpicknum = (&LONCAPA::map::getparameter($orderidx,              my $rpicknum = (&LONCAPA::map::getparameter($orderidx,
                                                         'parameter_randompick'))[0];                                                          'parameter_randompick'))[0];
Line 4788  $form_common."\n". Line 4134  $form_common."\n".
 '<span class="LC_nobreak"><label><input type="checkbox" name="randomorder_'.$orderidx.'" id="randomorder_'.$orderidx.'" onclick="checkForSubmit(this.form,'."'randomorder','settings'".');" '.$ro_set.$disabled.' /> '.&mt('Random Order').' </label></span>'.  '<span class="LC_nobreak"><label><input type="checkbox" name="randomorder_'.$orderidx.'" id="randomorder_'.$orderidx.'" onclick="checkForSubmit(this.form,'."'randomorder','settings'".');" '.$ro_set.$disabled.' /> '.&mt('Random Order').' </label></span>'.
 $form_end;  $form_end;
         }          }
     } elsif ($supplementalflag) {      } elsif ($supplementalflag && !$allowed) {
         my $isexttool;  
         if ($url=~m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) {  
             $url='/adm/wrapper'.$url;  
             $isexttool = 1;  
         }  
         $url .= ($url =~ /\?/) ? '&amp;':'?';          $url .= ($url =~ /\?/) ? '&amp;':'?';
         $url .= 'folderpath='.&HTML::Entities::encode($esc_path,'<>&"');          $url .= 'folderpath='.&HTML::Entities::encode($esc_path,'<>&"');
         if ($title) {          if ($title) {
             $url .= '&amp;title='.$encodedtitle;              $url .= '&amp;title='.&HTML::Entities::encode($renametitle,'<>&"');
         }          }
         if ((($isexternal) || ($isexttool)) && $orderidx) {          if ($isexternal && $orderidx) {
             $url .= '&amp;idx='.$orderidx;              $url .= '&amp;idx='.$orderidx;
         }          }
         if ($anchor ne '') {          if ($anchor ne '') {
Line 4813  $form_end; Line 4154  $form_end;
         if ($isexternal) {          if ($isexternal) {
             ($editlink,$extresform) =               ($editlink,$extresform) = 
                 &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem,                  &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem,
                                                      undef,undef,undef,undef,undef,undef,                                                       undef,undef,undef,$disabled);
                                                      undef,$disabled);  
         } elsif ($orig_url =~ m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) {  
             ($editlink,$extresform) =  
                 &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem,  
                                                      undef,undef,undef,'tool',$coursedom,  
                                                      $coursenum,$ltitoolsref,$disabled);  
         } elsif (!$isfolder && !$ispage) {          } elsif (!$isfolder && !$ispage) {
             my ($cfile,$home,$switchserver,$forceedit,$forceview) =               my ($cfile,$home,$switchserver,$forceedit,$forceview) = 
                 &Apache::lonnet::can_edit_resource($fileloc,$coursenum,$coursedom,$orig_url);                  &Apache::lonnet::can_edit_resource($fileloc,$coursenum,$coursedom,$orig_url);
Line 4832  $form_end; Line 4167  $form_end;
                     &Apache::lonhtmlcommon::jump_to_editres($cfile,$home,                      &Apache::lonhtmlcommon::jump_to_editres($cfile,$home,
                                                             $switchserver,                                                              $switchserver,
                                                             $forceedit,                                                              $forceedit,
                                                             undef,$symb,$shownsymb,                                                              undef,$symb,
                                                             &escape($env{'form.folderpath'}),                                                              &escape($env{'form.folderpath'}),
                                                             $renametitle,$hostname,                                                              $renametitle,$hostname,
                                                             '','',1,$suppanchor);                                                              '','',1,$suppanchor);
Line 4852  $form_end; Line 4187  $form_end;
         $reinit = &mt('(re-initialize course to access)');          $reinit = &mt('(re-initialize course to access)');
     }      }
     $line.='<td class="LC_docs_entry_commands"'.$tdalign.'><span class="LC_nobreak">'.$editlink.$renamelink;      $line.='<td class="LC_docs_entry_commands"'.$tdalign.'><span class="LC_nobreak">'.$editlink.$renamelink;
     my ($link,$nolink);      my $link;
     if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {      if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
         if ($allowed && !$env{'request.role.adv'} && !$isfolder && !$ispage) {         $line.='<a href="'.$url.'"><img src="'.$icon.'" alt="" class="LC_icon" /></a>';
             if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {  
                 $nolink = 1;  
             }  
         }  
         if ($nolink) {  
             $line .= '<img src="'.$icon.'" alt="" class="LC_icon" /></a>';  
         } else {  
             $line.='<a href="'.$url.'"><img src="'.$icon.'" alt="" class="LC_icon" /></a>';  
         }  
     } elsif ($url) {      } elsif ($url) {
        if ($anchor ne '') {         if ($anchor ne '') {
            if ($supplementalflag) {             if ($supplementalflag) {
Line 4872  $form_end; Line 4198  $form_end;
                $anchor = '#'.&HTML::Entities::encode($anchor,'"<>&');                 $anchor = '#'.&HTML::Entities::encode($anchor,'"<>&');
            }             }
        }         }
        if (($nomodal) && ($hostname ne '')) {  
          if ((!$supplementalflag) && ($nomodal) && ($hostname ne '')) {
            $link = 'http://'.$hostname.$url;             $link = 'http://'.$hostname.$url;
        } else {         } else {
            $link = $url;             $link = $url;
        }         }
        my $inhibitmenu;         $link = &js_escape($link.(($url=~/\?/)?'&amp;':'?').'inhibitmenu=yes'.$anchor);
        if ((($supplementalflag) && ($allowed) && ($url =~ m{^/adm/wrapper/})) ||         if ($nomodal) {
            (($allowed) && (($url =~ m{^/adm/(viewclasslist|$match_domain/$match_username/aboutme)(\?|$)}) ||  
                            ($url =~ m{^/public/$match_domain/$match_courseid/syllabus(\?|$)})))) {  
            $inhibitmenu = 'only_body=1';  
        } else {  
            $inhibitmenu = 'inhibitmenu=yes';  
        }  
        $link = &js_escape($link.(($url=~/\?/)?'&amp;':'?').$inhibitmenu.$anchor);  
        if ($allowed && !$env{'request.role.adv'} && !$isfolder && !$ispage && !$uploaded) {  
            if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {  
                $nolink = 1;  
            }  
        }  
        if ($nolink) {  
            $line.='<img src="'.$icon.'" alt="" class="LC_icon" />';  
        } elsif ($nomodal) {  
            $line.='<a href="#" onclick="javascript:window.open('."'$link','syllabuspreview','height=400,width=500,scrollbars=1,resizable=1,menubar=0,location=1')".'; return false;" />'.             $line.='<a href="#" onclick="javascript:window.open('."'$link','syllabuspreview','height=400,width=500,scrollbars=1,resizable=1,menubar=0,location=1')".'; return false;" />'.
                   '<img src="'.$icon.'" alt="" class="LC_icon" border="0" /></a>';                    '<img src="'.$icon.'" alt="" class="LC_icon" border="0" /></a>';
        } else {         } else {
Line 4905  $form_end; Line 4217  $form_end;
     }      }
     $line.='</span></td><td'.$tdwidth.'>';      $line.='</span></td><td'.$tdwidth.'>';
     if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {      if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
        if ($nolink) {         $line.='<a href="'.$url.'">'.$title.'</a>';
            $line.=$title;  
        } else {  
            $line.='<a href="'.$url.'">'.$title.'</a>';  
        }  
        if (!$allowed && $supplementalflag && $canedit && $isfolder) {  
            my $editicon = &Apache::loncommon::lonhttpdurl('/res/adm/pages').'/editmap.png';  
            my $editurl = $url;  
            $editurl =~ s{^\Q/adm/supplemental?\E}{/adm/coursedocs?command=direct&amp;forcesupplement=1&amp;};  
            $line .= '&nbsp;'.'<a href="'.$editurl.'">'.  
                     '<img src="'.$editicon.'" alt="'.&mt('Edit Content').'" title="'.&mt('Edit Content').'" />'.  
                     '</a>';  
        }  
        if ((($hiddenfolder) || ($hiddenres)) && (!$allowed) && ($supplementalflag))  {  
            $line.= ' <span class="LC_warning">('.&mt('hidden').')</span> ';  
        }  
     } elsif ($url) {      } elsif ($url) {
        if ($nolink) {         if ($nomodal) {
            $line.=$title;  
        } elsif ($nomodal) {  
            $line.='<a href="#" onclick="javascript:window.open('."'$link','syllabuspreview','height=400,width=500,scrollbars=1,resizable=1,menubar=0,location=1')".'; return false;" />'.             $line.='<a href="#" onclick="javascript:window.open('."'$link','syllabuspreview','height=400,width=500,scrollbars=1,resizable=1,menubar=0,location=1')".'; return false;" />'.
                   $title.'</a>';                    $title.'</a>';
        } else {         } else {
Line 4938  $form_end; Line 4233  $form_end;
     $line.="$extresform</td>";      $line.="$extresform</td>";
     $rand_pick_text = '&nbsp;' if ($rand_pick_text eq '');      $rand_pick_text = '&nbsp;' if ($rand_pick_text eq '');
     $rand_order_text = '&nbsp;' if ($rand_order_text eq '');      $rand_order_text = '&nbsp;' if ($rand_order_text eq '');
     if ($uploaded && $url && !$isfolder && !$ispage) {      if (($allowed) && ($folder!~/^supplemental/)) {
         if (($plainurl ne '') && ($env{'request.role.adv'} || $allowed || !$hiddenres)) {    my %lt=&Apache::lonlocal::texthash(
             &Apache::lonnet::allowuploaded('/adm/coursedoc',$plainurl);         'hd' => 'Hidden',
          'ec' => 'URL hidden');
           my ($enctext,$hidtext);
           if ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) {
               $enctext = ' checked="checked"';
               if (($ishash) && (ref($filtersref->{'encrypturl'}) eq 'ARRAY')) {
                   push(@{$filtersref->{'encrypturl'}},$orderidx);
               }
         }          }
     }  
     if ($allowed) {  
         my %lt=&Apache::lonlocal::texthash(  
                               'hd' => 'Hidden',  
                               'ec' => 'URL hidden');  
         my ($enctext,$hidtext,$formhidden,$formurlhidden);  
         if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {          if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
             $hidtext = ' checked="checked"';              $hidtext = ' checked="checked"';
             if (($ishash) && (ref($filtersref->{'hiddenresource'}) eq 'ARRAY')) {              if (($ishash) && (ref($filtersref->{'randomorder'}) eq 'ARRAY')) {
                 push(@{$filtersref->{'hiddenresource'}},$orderidx);                  push(@{$filtersref->{'hiddenresource'}},$orderidx);
             }              }
         }          }
         $formhidden = 'edit_hiddenresource_'.$orderidx;          my $formhidden = 'edit_hiddenresource_'.$orderidx;
         $line.=(<<ENDPARMS);          my $formurlhidden = 'edit_encrypturl_'.$orderidx;
    $line.=(<<ENDPARMS);
   <td class="LC_docs_entry_parameter">    <td class="LC_docs_entry_parameter">
     <form action="/adm/coursedocs" method="post" name="$formhidden">      <form action="/adm/coursedocs" method="post" name="$formhidden">
     $form_param      $form_param
     $form_common      $form_common
     <label><input type="checkbox" name="hiddenresource_$orderidx" id="hiddenresource_$orderidx" onclick="checkForSubmit(this.form,'hiddenresource','settings');" $hidtext $disabled /> $lt{'hd'}</label>      <label><input type="checkbox" name="hiddenresource_$orderidx" id="hiddenresource_$orderidx" onclick="checkForSubmit(this.form,'hiddenresource','settings');" $hidtext $disabled /> $lt{'hd'}</label>
     $form_end      $form_end
 ENDPARMS  
         if ($folder =~/^supplemental/) {  
             $line.= "\n    <td>";  
         } else {  
             if ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) {  
                 $enctext = ' checked="checked"';  
                 if (($ishash) && (ref($filtersref->{'encrypturl'}) eq 'ARRAY')) {  
                     push(@{$filtersref->{'encrypturl'}},$orderidx);  
                 }  
             }  
             $formurlhidden = 'edit_encrypturl_'.$orderidx;  
     $line.=(<<ENDPARMS);  
     <br />      <br />
     <form action="/adm/coursedocs" method="post" name="$formurlhidden">      <form action="/adm/coursedocs" method="post" name="$formurlhidden">
     $form_param      $form_param
Line 4984  ENDPARMS Line 4269  ENDPARMS
   <td class="LC_docs_entry_parameter">$rand_pick_text<br />    <td class="LC_docs_entry_parameter">$rand_pick_text<br />
                                       $rand_order_text</td>                                        $rand_order_text</td>
 ENDPARMS  ENDPARMS
         }  
     }      }
     $line.=&Apache::loncommon::end_data_table_row();      $line.=&Apache::loncommon::end_data_table_row();
     return $line;      return $line;
Line 5081  sub new_timebased_suffix { Line 4365  sub new_timebased_suffix {
             $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new folder/page.');              $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new folder/page.');
         } elsif ($type eq 'smppg') {          } elsif ($type eq 'smppg') {
             $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new simple page.');              $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new simple page.');
         } elsif ($type eq 'exttool') {  
             $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new external tool.');  
         } else {          } else {
             $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new discussion board.');              $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new discussion board.');
         }          }
Line 5111  sub new_timebased_suffix { Line 4393  sub new_timebased_suffix {
         } elsif ($type eq 'smppg') {          } elsif ($type eq 'smppg') {
             $locknotfreed .=              $locknotfreed .=
                 &mt('This will prevent creation of additional simple pages in this course.');                  &mt('This will prevent creation of additional simple pages in this course.');
         } elsif ($type eq 'exttool') {  
             $locknotfreed .=  
                 &mt('This will prevent creation of additional external tools in this course.');  
         } else {          } else {
             $locknotfreed .=              $locknotfreed .=
                 &mt('This will prevent creation of additional discussion boards in this course.');                  &mt('This will prevent creation of additional discussion boards in this course.');
Line 5297  sub list_symbs { Line 4576  sub list_symbs {
     $r->print(&endContentScreen());      $r->print(&endContentScreen());
 }  }
   
 sub short_urls {  
     my ($r,$canedit) = @_;  
     my $crstype = &Apache::loncommon::course_type();  
     my $formname = 'shortenurl';  
     $r->print(&Apache::loncommon::start_page('Display/Set Shortened URLs'));  
     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Shortened URLs'));  
     $r->print(&startContentScreen('tools'));  
     my ($navmap,$errormsg) =  
         &Apache::loncourserespicker::get_navmap_object($crstype,'shorturls');  
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};  
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};  
     my (%maps,%resources,%titles);  
     if (!ref($navmap)) {  
         $r->print($errormsg.  
                   &endContentScreen());  
         return '';  
     } else {  
         $r->print('<h4 class="LC_info">'.&mt('Tiny URLs for deep-linking into course').'</h4>'."\n");  
         $r->rflush();  
         my $readonly;  
         if ($canedit) {  
             my ($numnew,$errors) = &Apache::loncommon::get_requested_shorturls($cdom,$cnum,$navmap);  
             if ($numnew) {  
                 $r->print('<p class="LC_info">'.&mt('Created [quant,_1,URL]',$numnew).'</p>');  
             }  
             if ((ref($errors) eq 'ARRAY') && (@{$errors} > 0)) {  
                 $r->print(&mt('The following errors occurred when processing your request to create shortened URLs:').'<br /><ul>');  
                 foreach my $error (@{$errors}) {  
                     $r->print('<li>'.$error.'</li>');  
                 }  
                 $r->print('</ul><br />');  
             }  
         } else {  
             $readonly = 1;  
         }  
         my %currtiny = &Apache::lonnet::dump('tiny',$cdom,$cnum);  
         $r->print(&Apache::loncourserespicker::create_picker($navmap,'shorturls',$formname,$crstype,undef,  
                                                              undef,undef,undef,undef,undef,\%currtiny,$readonly));  
     }  
     $r->print(&endContentScreen());  
 }  
   
 sub contentverifyform {  sub contentverifyform {
     my ($r) = @_;      my ($r) = @_;
     my $crstype = &Apache::loncommon::course_type();      my $crstype = &Apache::loncommon::course_type();
Line 5710  sub changewarning { Line 4947  sub changewarning {
     if (!defined($message)) {      if (!defined($message)) {
  $message='Changes will become active for your current session after [_1], or the next time you log in.';   $message='Changes will become active for your current session after [_1], or the next time you log in.';
     }      }
     my $windowname = 'loncapaclient';  
     if ($env{'request.lti.login'}) {  
         $windowname .= 'lti';  
     }  
     $r->print("\n\n".      $r->print("\n\n".
 '<script type="text/javascript">'."\n".  '<script type="text/javascript">'."\n".
 '// <![CDATA['."\n".  '// <![CDATA['."\n".
 'function reinit(tf) { tf.submit();'.$postexec.' }'."\n".  'function reinit(tf) { tf.submit();'.$postexec.' }'."\n".
 '// ]]>'."\n".  '// ]]>'."\n".
 '</script>'."\n".  '</script>'."\n".
 '<form name="reinitform" method="post" action="/adm/roles" target="'.$windowname.'">'.  '<form name="reinitform" method="post" action="/adm/roles" target="loncapaclient">'.
 '<input type="hidden" name="orgurl" value="'.$url.  '<input type="hidden" name="orgurl" value="'.$url.
 '" /><input type="hidden" name="selectrole" value="1" /><p class="LC_warning">'.  '" /><input type="hidden" name="selectrole" value="1" /><p class="LC_warning">'.
 &mt($message,' <input type="hidden" name="'.  &mt($message,' <input type="hidden" name="'.
Line 5816  sub handler { Line 5049  sub handler {
 #  #
 # --------------------------------------------- Initialize help topics for this  # --------------------------------------------- Initialize help topics for this
     foreach my $topic ('Adding_Course_Doc','Main_Course_Documents',      foreach my $topic ('Adding_Course_Doc','Main_Course_Documents',
                'Adding_External_Resource','Adding_External_Tool',                 'Adding_External_Resource','Navigate_Content',
                        'Navigate_Content','Adding_Folders','Docs_Overview',                 'Adding_Folders','Docs_Overview', 'Load_Map',
                'Load_Map','Supplemental','Score_Upload_Form',                  'Supplemental','Score_Upload_Form','Adding_Pages',
                'Adding_Pages','Importing_LON-CAPA_Resource',                 'Importing_LON-CAPA_Resource','Importing_IMS_Course',
                'Importing_IMS_Course','Uploading_From_Harddrive',                         'Uploading_From_Harddrive','Course_Roster','Web_Page',
                        'Course_Roster','Web_Page','Dropbox','Simple_Problem') {                         'Dropbox','Simple_Problem') {
  $help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic);   $help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic);
     }      }
     # Composite help files      # Composite help files
Line 5837  sub handler { Line 5070  sub handler {
     $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching');      $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching');
     
     my ($allowed,$canedit,$canview,$disabled);      my ($allowed,$canedit,$canview,$disabled);
 # does this user have privileges to modify content.  
     if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {  
 # URI is /adm/supplemental when viewing supplemental docs in non-edit mode.  # URI is /adm/supplemental when viewing supplemental docs in non-edit mode.
         unless ($r->uri eq '/adm/supplemental') {      unless ($r->uri eq '/adm/supplemental') {
           # does this user have privileges to modify content.  
           if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
             $allowed = 1;              $allowed = 1;
         }              $canedit = 1;
         $canedit = 1;              $canview = 1;
         $canview = 1;          } elsif (&Apache::lonnet::allowed('cev',$env{'request.course.id'})) {
     } elsif (&Apache::lonnet::allowed('cev',$env{'request.course.id'})) {  
 # URI is /adm/supplemental when viewing supplemental docs in non-edit mode.  
         unless ($r->uri eq '/adm/supplemental') {  
             $allowed = 1;              $allowed = 1;
               $canview = 1;
         }          }
         $canview = 1;  
     }      }
     unless ($canedit) {      unless ($canedit) {
         $disabled = ' disabled="disabled"';          $disabled = ' disabled="disabled"';
Line 5878  sub handler { Line 5108  sub handler {
   } elsif ($allowed && $env{'form.listsymbs'}) {    } elsif ($allowed && $env{'form.listsymbs'}) {
       &init_breadcrumbs('listsymbs','List Content IDs');        &init_breadcrumbs('listsymbs','List Content IDs');
       &list_symbs($r);        &list_symbs($r);
   } elsif ($allowed && $env{'form.shorturls'}) {  
       &init_breadcrumbs('shorturls','Set/Display Shortened URLs','Docs_Short_URLs');  
       &short_urls($r,$canedit);  
   } elsif ($allowed && $env{'form.docslog'}) {    } elsif ($allowed && $env{'form.docslog'}) {
       &init_breadcrumbs('docslog','Show Log');        &init_breadcrumbs('docslog','Show Log');
       my $folder = $env{'form.folder'};        my $folder = $env{'form.folder'};
Line 5904  sub handler { Line 5131  sub handler {
 # Get the parameters that may be needed  # Get the parameters that may be needed
 #  #
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                             ['folderpath','title',                                              ['folderpath',
                                              'forcesupplement','forcestandard',                                               'forcesupplement','forcestandard',
                                              'tools','symb','command','supppath']);                                               'tools','symb','command','supppath']);
   
Line 5945  sub handler { Line 5172  sub handler {
     }      }
     if ($env{'form.forcesupplement'}) { $supplementalflag=1; }      if ($env{'form.forcesupplement'}) { $supplementalflag=1; }
     if ($env{'form.forcestandard'})   { $supplementalflag=0; }      if ($env{'form.forcestandard'})   { $supplementalflag=0; }
     unless (($supplementalflag) ||      unless ($allowed) { $supplementalflag=1; }
             ($r->uri =~ m{^/adm/coursedocs/showdoc/uploaded/\Q$coursedom\E/\Q$coursenum\E/docs/})) {      unless ($standard) { $supplementalflag=1; }
         unless ($allowed) { $supplementalflag=1; }  
         unless ($standard) { $supplementalflag=1; }  
     }  
     my $toolsflag=0;      my $toolsflag=0;
     if ($env{'form.tools'}) { $toolsflag=1; }      if ($env{'form.tools'}) { $toolsflag=1; }
   
     if ($env{'form.folderpath'} ne '') {      if ($env{'form.folderpath'} ne '') {
         &Apache::loncommon::validate_folderpath($supplementalflag,$allowed,$coursenum,$coursedom);          &validate_folderpath($supplementalflag);
     }      }
   
     my $backto_supppath;  
     if ($env{'form.supppath'} ne '') {      if ($env{'form.supppath'} ne '') {
         if ($supplementalflag && $allowed) {          &validate_suppath();
             $backto_supppath = &validate_supppath($coursenum,$coursedom);  
         }  
     }      }
   
     my $script='';      my $script='';
Line 5970  sub handler { Line 5191  sub handler {
     my $container;      my $container;
     my $containertag;      my $containertag;
     my $pathitem;      my $pathitem;
     my %ltitools;  
     my $posslti;  
     my $hiddentop;      my $hiddentop;
     my $navmap;      my $navmap;
     my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) };      my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) };
Line 5983  sub handler { Line 5202  sub handler {
                &Apache::loncommon::symb_to_docspath($env{'form.symb'},\$navmap);                 &Apache::loncommon::symb_to_docspath($env{'form.symb'},\$navmap);
            &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>             &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>
                $env{'form.command'}.'_'.$env{'form.symb'}});                 $env{'form.command'}.'_'.$env{'form.symb'}});
        } elsif (($env{'form.supppath'} ne '') && $supplementalflag && $allowed) {         } elsif ($env{'form.supppath'} ne '') {
            $env{'form.folderpath'}=$env{'form.supppath'};             $env{'form.folderpath'}=$env{'form.supppath'};
            &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>             &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>
                $env{'form.command'}.'_'.$backto_supppath});                 $env{'form.command'}.'_'.$env{'form.supppath'}});
        }         }
    } elsif ($env{'form.command'} eq 'editdocs') {     } elsif ($env{'form.command'} eq 'editdocs') {
        $env{'form.folderpath'} = &default_folderpath($coursenum,$coursedom,\$navmap);         $env{'form.folderpath'} = &default_folderpath($coursenum,$coursedom,\$navmap);
Line 6022  sub handler { Line 5241  sub handler {
             undef($env{'form.folderpath'});              undef($env{'form.folderpath'});
         }          }
         if ($env{'form.folderpath'} ne '') {          if ($env{'form.folderpath'} ne '') {
             &Apache::loncommon::validate_folderpath($supplementalflag,$allowed,$coursenum,$coursedom);              &validate_folderpath($supplementalflag);
         }          }
     }      }
      
 # If we are not allowed to make changes and this is supplemental content set folderpath  # If we are not allowed to make changes, all we can see are supplemental docs
     if ((!$allowed) && ($supplementalflag)) {      if (!$allowed) {
         unless ($env{'form.folderpath'} =~ /^supplemental/) {          unless ($env{'form.folderpath'} =~ /^supplemental/) {
             $env{'form.folderpath'} = &supplemental_base();              $env{'form.folderpath'} = &supplemental_base();
         }          }
Line 6039  sub handler { Line 5258  sub handler {
                                   $env{'form.folderpath'};                                    $env{'form.folderpath'};
     }      }
 # If allowed and user's role is not advanced check folderpath is not hidden  # If allowed and user's role is not advanced check folderpath is not hidden
     my $hidden_and_empty;      if (($allowed) && (!$env{'request.role.adv'}) &&
     if (($allowed) && (!$env{'request.role.adv'}) && ($env{'form.folderpath'} ne '')) {          ($env{'form.folderpath'} ne '') && (!$supplementalflag)) {
         my ($folderurl,$foldername,$hiddenfolder);          my $folderurl;
         my @pathitems = split(/\&/,$env{'form.folderpath'});          my @pathitems = split(/\&/,$env{'form.folderpath'});
         my $folder = $pathitems[-2];          my $folder = $pathitems[-2];
         if ($folder eq '') {          if ($folder eq '') {
Line 6053  sub handler { Line 5272  sub handler {
             } else {              } else {
                 $folderurl .= '.sequence';                  $folderurl .= '.sequence';
             }              }
             if ($supplementalflag) {              unless (ref($navmap)) {
                 ($foldername,$hiddenfolder) = ($pathitems[-1] =~ /^([^:]*)::(|1):::$/);                  $navmap = Apache::lonnavmaps::navmap->new();
                 $foldername = &HTML::Entities::decode(&unescape($foldername));  
                 my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);  
                 if (ref($supplemental) eq 'HASH') {  
                     my ($suppmap,$suppmapnum);  
                     if ($folder eq 'supplemental') {  
                         $suppmap = 'default';  
                         $suppmapnum = 0;  
                     } elsif ($folder =~ /^supplemental_(\d+)$/) {  
                         $suppmap = $1;  
                         $suppmapnum = $suppmap;  
                     }  
                     if ($hiddenfolder) {  
                         my $hascontent;  
                         foreach my $key (reverse(sort(keys(%{$supplemental->{'ids'}})))) {  
                             if ($key =~ m{^\Q/uploaded/$coursedom/$coursenum/supplemental/$suppmap/\E}) {  
                                 $hascontent = 1;  
                             } elsif (ref($supplemental->{'ids'}->{$key}) eq 'ARRAY') {  
                                 foreach my $id (@{$supplemental->{'ids'}->{$key}}) {  
                                     if ($id =~ /^$suppmapnum\:/) {  
                                         $hascontent = 1;  
                                         last;  
                                     }  
                                 }  
                             }  
                             last if ($hascontent);  
                         }  
                         unless ($hascontent) {  
                             if ($foldername ne '') {  
                                 $hidden_and_empty = $foldername;  
                             } else {  
                                 $hidden_and_empty = $folder;  
                             }  
                         }  
                     }  
                 }  
             } else {  
                 unless (ref($navmap)) {  
                     $navmap = Apache::lonnavmaps::navmap->new();  
                 }  
                 ($foldername,$hiddenfolder) = ($pathitems[-1] =~ /^([^:]*):|\d+:|1:(|1):|1:|1$/);  
                 $foldername = &HTML::Entities::decode(&unescape($foldername));  
                 if (ref($navmap)) {  
                     if ($hiddenfolder ||  
                         (lc($navmap->get_mapparam(undef,$folderurl,"0.hiddenresource")) eq 'yes')) {  
                         my @resources = $navmap->retrieveResources($folderurl,$filterFunc,1,1);  
                         unless (@resources) {  
                             if ($foldername ne '') {  
                                 $hidden_and_empty = $foldername;  
                             } else {  
                                 $hidden_and_empty = $folder;  
                             }  
                         }  
                     }  
                 }  
             }              }
             if ($hidden_and_empty ne '') {              if (ref($navmap)) {
                 splice(@pathitems,-2);                  if (lc($navmap->get_mapparam(undef,$folderurl,"0.hiddenresource")) eq 'yes') {
                 if (@pathitems) {                      my @resources = $navmap->retrieveResources($folderurl,$filterFunc,1,1);
                     $env{'form.folderpath'} = join('&',@pathitems);                      unless (@resources) {
                 } else {                          undef($env{'form.folderpath'});
                     undef($env{'form.folderpath'});                      }
                 }                  }
             }              }
         }          }
     }      }
   
   
 # If after all of this, we still don't have any paths, make them  # If after all of this, we still don't have any paths, make them
     unless ($env{'form.folderpath'}) {      unless ($env{'form.folderpath'}) {
        if ($supplementalflag) {         if ($supplementalflag) {
Line 6205  sub handler { Line 5371  sub handler {
                 }                  }
             }              }
             my $tabidstr = join("','",@tabids);              my $tabidstr = join("','",@tabids);
             my (%domtools,%crstools);  
             my %tooltypes = &Apache::loncommon::usable_exttools();  
             if ($tooltypes{'dom'}) {  
                 %domtools = &Apache::lonnet::get_domain_lti($coursedom,'consumer');  
             }  
             if ($tooltypes{'crs'}) {  
                 %crstools = &Apache::lonnet::get_course_lti($coursenum,$coursedom,'consumer');  
             }  
             %ltitools = (  
                           dom => \%domtools,  
                           crs => \%crstools,  
                         );  
             $posslti = scalar(keys(%domtools)) + scalar(keys(%crstools));  
             my $hostname = $r->hostname();              my $hostname = $r->hostname();
             $script .= &editing_js($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti,      $script .= &editing_js($udom,$uname,$supplementalflag,$coursedom,$coursenum,
                                    $canedit,$hostname,\$navmap).                                     $canedit,$hostname,\$navmap).
                        &history_tab_js().                         &history_tab_js().
                        &inject_data_js().                         &inject_data_js().
                        &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr,$tid).                         &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr,$tid).
                        &Apache::lonextresedit::extedit_javascript(\%ltitools);                         &Apache::lonextresedit::extedit_javascript();
             my $onload = "javascript:resize_scrollbox('contentscroll','1','1');";  
             if ($hidden_and_empty ne '') {  
                 my $alert = &mt("Additional privileges required to edit empty and hidden folder: '[_1]'",  
                                 $hidden_and_empty);  
                 $onload .= "javascript:alert('".&js_escape($alert)."');";  
             }  
             $addentries = {              $addentries = {
                             onload => $onload,                              onload   => "javascript:resize_scrollbox('contentscroll','1','1');",
                           };                            };
         }          }
         $script .= &paste_popup_js();           $script .= &paste_popup_js(); 
Line 6253  sub handler { Line 5400  sub handler {
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
   
     if ($showdoc) {      if ($showdoc) {
         my $args;          $r->print(&Apache::loncommon::start_page("$crstype documents",undef,
         if ($supplementalflag) {                                                  {'force_register' => $showdoc,}));
             my $title = &HTML::Entities::encode($env{'form.title'},'\'"<>&');  
             my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);  
             $args = {'bread_crumbs' => $brcrum,  
                      'bread_crumbs_nomenu' => 1};  
         } else {  
             $args = {'force_register' => $showdoc};  
         }  
         $r->print(&Apache::loncommon::start_page("$crstype documents",undef,$args));  
     } elsif ($toolsflag) {      } elsif ($toolsflag) {
         my ($breadtext,$breadtitle);          my ($breadtext,$breadtitle);
         $breadtext = "$crstype Editor";          $breadtext = "$crstype Editor";
Line 6280  sub handler { Line 5419  sub handler {
                      $breadtitle)                       $breadtitle)
                  );                   );
     } elsif ($r->uri eq '/adm/supplemental') {      } elsif ($r->uri eq '/adm/supplemental') {
         unless ($env{'request.role.adv'}) {  
             unless (&Apache::lonnet::has_unhidden_suppfiles($coursenum,$coursedom)) {  
                 $r->internal_redirect('/adm/navmaps');  
                 return OK;  
             }  
         }  
         my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype);          my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype);
         my $args = {'bread_crumbs' => $brcrum};  
         unless (($env{'form.folderpath'} eq '') ||  
                 ($env{'form.folder'} eq 'supplemental')) {  
             $args->{'bread_crumbs_nomenu'} = 1;  
         }  
         $r->print(&Apache::loncommon::start_page("Supplemental $crstype Content",undef,          $r->print(&Apache::loncommon::start_page("Supplemental $crstype Content",undef,
                                                 $args));                                                  {'bread_crumbs' => $brcrum,}));
     } else {      } else {
         my ($breadtext,$breadtitle,$helpitem);          my ($breadtext,$breadtitle,$helpitem);
         $breadtext = "$crstype Editor";          $breadtext = "$crstype Editor";
Line 6321  sub handler { Line 5449  sub handler {
   my %codebase = ();    my %codebase = ();
   my ($upload_result,$upload_output,$uploadphase);    my ($upload_result,$upload_output,$uploadphase);
   if ($canedit) {    if ($canedit) {
       undef($suppchanges);  
       if (($env{'form.uploaddoc.filename'}) &&        if (($env{'form.uploaddoc.filename'}) &&
   ($env{'form.cmd'}=~/^upload_(\w+)/)) {    ($env{'form.cmd'}=~/^upload_(\w+)/)) {
           my $context = $1;             my $context = $1; 
Line 6333  sub handler { Line 5460  sub handler {
   if ($hadchanges) {    if ($hadchanges) {
       &mark_hash_old();        &mark_hash_old();
   }    }
           if ($suppchanges) {  
               &Apache::lonnet::update_supp_caches($coursedom,$coursenum);  
               undef($suppchanges);  
           }  
           $r->print($upload_output);            $r->print($upload_output);
       } elsif ($env{'form.phase'} eq 'upload_embedded') {        } elsif ($env{'form.phase'} eq 'upload_embedded') {
           # Process file upload - phase two - upload embedded objects             # Process file upload - phase two - upload embedded objects 
Line 6390  sub handler { Line 5513  sub handler {
                 'impo' => 'Import',                  'impo' => 'Import',
  'lnks' => 'Import from Stored Links',   'lnks' => 'Import from Stored Links',
                 'impm' => 'Import from Assembled Map',                  'impm' => 'Import from Assembled Map',
                 'extr' => 'External Resource',  
                 'extt' => 'External Tool',  
                 'selm' => 'Select Map',                  'selm' => 'Select Map',
                 'load' => 'Load Map',                  'load' => 'Load Map',
                 'newf' => 'New Folder',                  'newf' => 'New Folder',
Line 6458  sub handler { Line 5579  sub handler {
  my $fileupload=(<<FIUP);   my $fileupload=(<<FIUP);
         $quotainfo          $quotainfo
  $lt{'file'}:<br />   $lt{'file'}:<br />
    <input type="file" name="uploaddoc" class="LC_flUpload" size="40" $disabled />
           <input type="hidden" id="LC_free_space" value="$free_space" />
 FIUP  FIUP
   
  my $checkbox=(<<CHBO);   my $checkbox=(<<CHBO);
  <!-- <label>$lt{'parse'}?   <!-- <label>$lt{'parse'}?
  <input type="checkbox" name="parserflag" />   <input type="checkbox" name="parserflag" />
Line 6478  CHBO Line 5602  CHBO
         <fieldset id="uploadimsform" style="display: none;">          <fieldset id="uploadimsform" style="display: none;">
         <legend>$lt{'imsf'}</legend>          <legend>$lt{'imsf'}</legend>
         $fileupload          $fileupload
         <input type="file" name="uploaddoc" id="uploaddocims" class="LC_flUpload LC_uploaddoc" size="40" $disabled />  
         <input type="hidden" id="LC_free_space_ims" value="$free_space" />  
         <br />          <br />
         <p>          <p>
         $lt{'cms'}:&nbsp;           $lt{'cms'}:&nbsp; 
Line 6506  IMSFORM Line 5628  IMSFORM
         <legend>$lt{'upfi'}</legend>          <legend>$lt{'upfi'}</legend>
  <input type="hidden" name="active" value="aa" />   <input type="hidden" name="active" value="aa" />
  $fileupload   $fileupload
         <input type="file" name="uploaddoc" class="LC_flUpload" size="40" $disabled />  
         <input type="hidden" id="LC_free_space" value="$free_space" />  
  <br />   <br />
  $lt{'title'}:<br />   $lt{'title'}:<br />
  <input type="text" size="60" name="comment" $disabled />   <input type="text" size="60" name="comment" $disabled />
Line 6564  SEDFFORM Line 5684  SEDFFORM
         my $extresourcesform =          my $extresourcesform =
             &Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem,              &Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem,
                                                  $help{'Adding_External_Resource'},                                                   $help{'Adding_External_Resource'},
                                                  undef,undef,undef,undef,undef,undef,$disabled);                                                   undef,undef,$disabled);
         my $exttoolform =  
             &Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem,  
                                                  $help{'Adding_External_Tool'},undef,  
                                                  undef,'tool',$coursedom,$coursenum,  
                                                  \%ltitools,$disabled);  
     if ($allowed) {      if ($allowed) {
         my $folder = $env{'form.folder'};          my $folder = $env{'form.folder'};
         if ($folder eq '') {          if ($folder eq '') {
Line 6626  HIDDENFORM Line 5741  HIDDENFORM
        }         }
        my $postexec='';         my $postexec='';
        if ($folder eq 'default') {         if ($folder eq 'default') {
            my $windowname = 'loncapaclient';  
            if ($env{'request.lti.login'}) {  
                $windowname .= 'lti';  
            }  
            $r->print('<script type="text/javascript">'."\n"             $r->print('<script type="text/javascript">'."\n"
                     .'// <![CDATA['."\n"                      .'// <![CDATA['."\n"
                     .'this.window.name="$windowname";'."\n"                      .'this.window.name="loncapaclient";'."\n"
                     .'// ]]>'."\n"                      .'// ]]>'."\n"
                     .'</script>'."\n"                      .'</script>'."\n"
        );         );
Line 6828  NGFFORM Line 5939  NGFFORM
         my @importdoc = (          my @importdoc = (
         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="toggleUpload(\'ext\');" />'=>$extresourcesform}          {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="toggleUpload(\'ext\');" />'=>$extresourcesform}
         );          );
         if ($posslti) {  
             push(@importdoc,  
                 {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/exttool.png" alt="'.$lt{extt}.'" onclick="toggleUpload(\'tool\');" />'=>$exttoolform},  
         );  
         }  
         unless ($container eq 'page') {          unless ($container eq 'page') {
             push(@importdoc,              push(@importdoc,
                 {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/ims.png" alt="'.$lt{imsf}.'" onclick="javascript:toggleUpload(\'ims\');" />'=>$imspform}                  {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/ims.png" alt="'.$lt{imsf}.'" onclick="javascript:toggleUpload(\'ims\');" />'=>$imspform}
Line 6875  unless ($container eq 'page') { Line 5981  unless ($container eq 'page') {
        unless (($supplementalflag || $toolsflag)) {         unless (($supplementalflag || $toolsflag)) {
           my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,            my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
                               $supplementalflag,\%orderhash,$iconpath,$pathitem,                                $supplementalflag,\%orderhash,$iconpath,$pathitem,
                               \%ltitools,$canedit,$hostname,\$navmap,$hiddentop);                                $canedit,$hostname,\$navmap,$hiddentop);
           undef($navmap);            undef($navmap);
           if ($error) {            if ($error) {
              $r->print('<p><span class="LC_error">'.$error.'</span></p>');               $r->print('<p><span class="LC_error">'.$error.'</span></p>');
Line 6896  unless ($container eq 'page') { Line 6002  unless ($container eq 'page') {
        unless ($supplementalflag) {         unless ($supplementalflag) {
    $folder='supplemental';     $folder='supplemental';
        }         }
        if (($folder eq 'supplemental') &&         if ($folder =~ /^supplemental$/ &&
    (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) {     (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) {
           $env{'form.folderpath'} = &supplemental_base();            $env{'form.folderpath'} = &supplemental_base();
        } elsif ($allowed) {         } elsif ($allowed) {
Line 6916  unless ($container eq 'page') { Line 6022  unless ($container eq 'page') {
         <legend>$lt{'upfi'}</legend>          <legend>$lt{'upfi'}</legend>
  <input type="hidden" name="active" value="ee" />   <input type="hidden" name="active" value="ee" />
  $fileupload   $fileupload
         <input type="file" name="uploaddoc" id="uploaddocsupp" class="LC_flUpload LC_uploaddoc" size="40" $disabled />  
         <input type="hidden" id="LC_free_space_supp" value="$free_space" />  
  <br />   <br />
  <br />   <br />
  <span class="LC_nobreak">   <span class="LC_nobreak">
Line 6930  unless ($container eq 'page') { Line 6034  unless ($container eq 'page') {
  $pathitem   $pathitem
  <input type="hidden" name="cmd" value="upload_supplemental" />   <input type="hidden" name="cmd" value="upload_supplemental" />
         <input type='submit' value="$lt{'upld'}" />          <input type='submit' value="$lt{'upld'}" />
         </fieldset>  
         </form>          </form>
 SUPDOCFORM  SUPDOCFORM
   
Line 6948  SNFFORM Line 6051  SNFFORM
             &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem,              &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem,
                                                  $help{'Adding_External_Resource'},                                                   $help{'Adding_External_Resource'},
                                                  undef,undef,$disabled);                                                   undef,undef,$disabled);
         my $supexttoolform =  
             &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem,  
                                                  $help{'Adding_External_Tool'},  
                                                  undef,undef,'tool',$coursedom,  
                                                  $coursenum,\%ltitools,$disabled);  
   
  my $supnewsylform=(<<SNSFORM);   my $supnewsylform=(<<SNSFORM);
  <form action="/adm/coursedocs" method="post" name="supnewsyl">   <form action="/adm/coursedocs" method="post" name="supnewsyl">
Line 7007  my @specialdocs = ( Line 6105  my @specialdocs = (
  );   );
 my @supimportdoc = (  my @supimportdoc = (
  {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="javascript:toggleUpload(\'suppext\')" />'   {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="javascript:toggleUpload(\'suppext\')" />'
             =>$supextform});              =>$supextform},
         if (keys(%ltitools)) {  
             push(@supimportdoc,  
                 {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/exttool.png" alt="'.$lt{extt}.'" onclick="javascript:toggleUpload(\'supptool\')" />'  
             =>$supexttoolform});  
         }  
         push(@supimportdoc,  
                 {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/pdfupload.png" alt="'.$lt{upl}.'" onclick="javascript:toggleUpload(\'suppdoc\');" />'                  {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/pdfupload.png" alt="'.$lt{upl}.'" onclick="javascript:toggleUpload(\'suppdoc\');" />'
             =>$supupdocform},              =>$supupdocform},
         );                     );
   
 $supupdocform =  &create_form_ul(&create_list_elements(@supimportdoc));  $supupdocform =  &create_form_ul(&create_list_elements(@supimportdoc));
 my %suporderhash = (  my %suporderhash = (
Line 7025  my %suporderhash = ( Line 6117  my %suporderhash = (
                 'ff' => ['Other',&create_form_ul(&create_list_elements(@specialdocs))]                  'ff' => ['Other',&create_form_ul(&create_list_elements(@specialdocs))]
                 );                  );
         if ($supplementalflag) {          if ($supplementalflag) {
             $suppchanges = 0;             my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
             my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,                                 $supplementalflag,\%suporderhash,$iconpath,$pathitem,
                                 $supplementalflag,\%suporderhash,$iconpath,$pathitem,                                 $canedit,$hostname);
                                 \%ltitools,$canedit,$hostname);             if ($error) {
             if ($error) {                $r->print('<p><span class="LC_error">'.$error.'</span></p>');
                 $r->print('<p><span class="LC_error">'.$error.'</span></p>');             } else {
             }                 if ($suppchanges) {
             if ($suppchanges) {                     my %servers = &Apache::lonnet::internet_dom_servers($coursedom);
                 &Apache::lonnet::update_supp_caches($coursedom,$coursenum);                     my @ids=&Apache::lonnet::current_machine_ids();
                 undef($suppchanges);                     foreach my $server (keys(%servers)) {
             }                         next if (grep(/^\Q$server\E$/,@ids));
                          my $hashid=$coursenum.':'.$coursedom;
                          my $cachekey = &escape('suppcount').':'.&escape($hashid);
                          &Apache::lonnet::remote_devalidate_cache($server,[$cachekey]);
                      }
                      &Apache::lonnet::get_numsuppfiles($coursenum,$coursedom,1);
                      undef($suppchanges);
                  }
              }
         }          }
     } elsif ($supplementalflag) {      } elsif ($supplementalflag) {
         my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,          my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
                             $supplementalflag,'',$iconpath,$pathitem,'',$canedit,                              $supplementalflag,'',$iconpath,$pathitem,'',$hostname);
                             $hostname);  
         if ($error) {          if ($error) {
             $r->print('<p><span class="LC_error">'.$error.'</span></p>');              $r->print('<p><span class="LC_error">'.$error.'</span></p>');
         }          }
Line 7202  sub remove_archive { Line 6301  sub remove_archive {
             if ($url eq $env{'form.archiveurl'}) {              if ($url eq $env{'form.archiveurl'}) {
                 if (&handle_edit_cmd($docuname,$docudom)) {                  if (&handle_edit_cmd($docuname,$docudom)) {
                     ($errtext,$fatal) = &storemap($docuname,$docudom,$map,1);                      ($errtext,$fatal) = &storemap($docuname,$docudom,$map,1);
                     if ($suppchanges) {  
                         &Apache::lonnet::update_supp_caches($docudom,$docuname);  
                         undef($suppchanges);  
                     }  
                     if ($fatal) {                      if ($fatal) {
                         if ($container eq 'page') {                          if ($container eq 'page') {
                             $delwarning = &mt('An error occurred updating the contents of the current page.');                              $delwarning = &mt('An error occurred updating the contents of the current page.');
Line 7244  sub generate_admin_menu { Line 6339  sub generate_admin_menu {
                                          'vc'   => 'Verify Content',                                           'vc'   => 'Verify Content',
                                          'cv'   => 'Check/Set Resource Versions',                                           'cv'   => 'Check/Set Resource Versions',
                                          'ls'   => 'List Resource Identifiers',                                           'ls'   => 'List Resource Identifiers',
                                          'ct'   => 'Display/Set Shortened URLs for Deep-linking',  
                                          'imse' => 'Export contents to IMS Archive',                                           'imse' => 'Export contents to IMS Archive',
                                          'dcd'  => "Copy $crstype Content to Authoring Space",                                           'dcd'  => "Copy $crstype Content to Authoring Space",
             );              );
Line 7295  sub generate_admin_menu { Line 6389  sub generate_admin_menu {
                     icon       => 'symbs.png',                      icon       => 'symbs.png',
                     linktitle  => "List the unique identifier used for each resource instance in your $lc_crstype"                      linktitle  => "List the unique identifier used for each resource instance in your $lc_crstype"
                 },                  },
                 {   linktext   => $lt{'ct'},  
                     url        => "javascript:injectData(document.courseverify,'dummy','shorturls','$lt{'ct'}')",  
                     permission => 'F',  
                     help       => 'Docs_Short_URLs',  
                     icon       => 'shorturls.png',  
                     linktitle  => "Set shortened URLs for a resource or folder in your $lc_crstype for use in deep-linking"  
                 },  
                 ]                  ]
         });          });
     if ($canedit) {      if ($canedit) {
Line 7432  END Line 6519  END
 }  }
   
 sub editing_js {  sub editing_js {
     my ($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti,      my ($udom,$uname,$supplementalflag,$coursedom,$coursenum,
         $canedit,$hostname,$navmapref) = @_;          $canedit,$hostname,$navmapref) = @_;
     my %js_lt = &Apache::lonlocal::texthash(      my %js_lt = &Apache::lonlocal::texthash(
                                           p_mnf => 'Name of New Folder',                                            p_mnf => 'Name of New Folder',
Line 7543  sub editing_js { Line 6630  sub editing_js {
     } elsif ($env{'docs.exit.'.$env{'request.course.id'}} eq '/adm/menu') {      } elsif ($env{'docs.exit.'.$env{'request.course.id'}} eq '/adm/menu') {
         $backtourl = '/adm/menu';          $backtourl = '/adm/menu';
     } elsif ($supplementalflag) {      } elsif ($supplementalflag) {
         if (($env{'request.role.adv'}) ||          $backtourl = '/adm/supplemental';
             (&Apache::lonnet::has_unhidden_suppfiles($coursenum,$coursedom))) {  
             $backtourl = '/adm/supplemental';  
         } else {  
             $backtourl = '/adm/navmaps';  
         }  
     } else {      } else {
         $backtourl = '/adm/navmaps';          $backtourl = '/adm/navmaps';
     }      }
   
     my $fieldsets = "'ext','doc'";      my $fieldsets = "'ext','doc'";
     if ($posslti) {  
         $fieldsets .= ",'tool'";  
     }  
     unless ($main_container_page) {      unless ($main_container_page) {
         $fieldsets .=",'ims'";          $fieldsets .=",'ims'";
     }      }
     if ($supplementalflag) {      if ($supplementalflag) {
         $fieldsets = "'suppext','suppdoc'";          $fieldsets = "'suppext','suppdoc'";
         if ($posslti) {  
             $fieldsets .= ",'supptool'";  
         }  
     }      }
   
     my $jsmakefunctions;      my $jsmakefunctions;
Line 7761  function toggleUpload(caller) { Line 6837  function toggleUpload(caller) {
             }              }
         }          }
         document.getElementById('upload'+blocks[i]+'form').style.display=disp;          document.getElementById('upload'+blocks[i]+'form').style.display=disp;
         if ((caller == 'tool') || (caller == 'supptool')) {  
             if (disp == 'block') {  
                 if (document.getElementById('LC_exttoolid')) {  
                     var toolselector = document.getElementById('LC_exttoolid');  
                     var suppflag = 0;  
                     if (caller == 'supptool') {  
                         suppflag = 1;  
                     }  
                     currForm = document.getElementById('new'+caller);  
                     updateExttool(toolselector,currForm,suppflag);  
                 }  
             }  
         }  
     }      }
     resize_scrollbox('contentscroll','1','1');      resize_scrollbox('contentscroll','1','1');
     return;      return;

Removed from v.1.484.2.93.2.17  
changed lines
  Added in v.1.484.2.94


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>