Diff for /loncom/interface/lonmenu.pm between versions 1.369.2.57 and 1.369.2.71.2.2

version 1.369.2.57, 2016/08/13 21:14:50 version 1.369.2.71.2.2, 2020/04/07 18:34:26
Line 132  Inputs: 6 - (a) link and (b) target for Line 132  Inputs: 6 - (a) link and (b) target for
             (f) optional class for <li> element in primary menu, for which              (f) optional class for <li> element in primary menu, for which
                 sub menu is being generated.                  sub menu is being generated.
   
   The underlying datastructure used in (d) contains data from mydesk.tab.
   It consists of an array which has an array for each item appearing in
   the menu (e.g. [["link", "title", "condition"]] for a single-item menu).
   create_submenu() supports also the creation of XHTML for nested dropdown
   menus represented by unordered lists. This is done by replacing the
   scalar used for the link with an arrayreference containing the menuitems
   for the nested menu. This can be done recursively so that the next menu
   may also contain nested submenus.
   
    Example:
    [                                                                                      # begin of datastructure
           ["/home/", "Home", "condition1"],               # 1st item of the 1st layer menu
           [                                                                               # 2nd item of the 1st layer menu
                   [                                                                       # anon. array for nested menu
                           ["/path1", "Path1", undef],     # 1st item of the 2nd layer menu
                           ["/path2", "Path2", undef],     # 2nd item of the 2nd layer menu
                           [                                                               # 3rd item of the 2nd layer menu
                                   [[...], [...], ..., [...]],     # containing another menu layer
                                   "Sub-Sub-Menu",                         # title for this container
                                   undef
                           ]
                   ],                                                                      # end of array/nested menu
                   "Sub-Menu",                                                     # title for the container item
                   undef
           ]                                                                               # end of 2nd item of the 1st layer menu
   ]
   
   
 =item innerregister()  =item innerregister()
   
Line 286  sub primary_menu { Line 313  sub primary_menu {
                     push(@primsub,$item);                      push(@primsub,$item);
                 }                  }
                 if (@primsub > 0) {                  if (@primsub > 0) {
                       if ($title eq 'Personal' && $env{'user.name'} && $env{'user.domain'} ) {
                           $title = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});
                       } else {
                           $title = &mt($title);
                       }
                     $menu{$position} .= &create_submenu($link,$target,$title,\@primsub,1);                      $menu{$position} .= &create_submenu($link,$target,$title,\@primsub,1);
                 } elsif ($link) {                  } elsif ($link) {
                     $menu{$position} .= '<li><a href="'.$link.'" target="'.$target.'">'.&mt($title).'</a></li>';                      $menu{$position} .= '<li><a href="'.$link.'" target="'.$target.'">'.&mt($title).'</a></li>';
Line 352  sub secondary_menu { Line 384  sub secondary_menu {
                                                ? "/$env{'request.course.sec'}"                                                 ? "/$env{'request.course.sec'}"
                                                : '');                                                 : '');
     my $canedit       = &Apache::lonnet::allowed('mdc', $env{'request.course.id'});      my $canedit       = &Apache::lonnet::allowed('mdc', $env{'request.course.id'});
       my $canvieweditor = &Apache::lonnet::allowed('cev', $env{'request.course.id'}); 
     my $canviewroster = $env{'course.'.$env{'request.course.id'}.'.student_classlist_view'};      my $canviewroster = $env{'course.'.$env{'request.course.id'}.'.student_classlist_view'};
     if ($canviewroster eq 'disabled') {      if ($canviewroster eq 'disabled') {
         undef($canviewroster);          undef($canviewroster);
     }      }
     my $canviewgrps   = &Apache::lonnet::allowed('vcg', $crs_sec);      my $canviewgrps   = &Apache::lonnet::allowed('vcg', $crs_sec);
     my $canmodifyuser = &Apache::lonnet::allowed('cst', $crs_sec);      my $canmodifyuser = &Apache::lonnet::allowed('cst', $crs_sec);
       my $canviewusers  = &Apache::lonnet::allowed('vcl', $crs_sec);
     my $canviewwnew   = &Apache::lonnet::allowed('whn', $crs_sec);      my $canviewwnew   = &Apache::lonnet::allowed('whn', $crs_sec);
       my $canviewpara   = &Apache::lonnet::allowed('vpa', $crs_sec);
     my $canmodpara    = &Apache::lonnet::allowed('opa', $crs_sec);      my $canmodpara    = &Apache::lonnet::allowed('opa', $crs_sec);
     my $canvgr        = &Apache::lonnet::allowed('vgr', $crs_sec);      my $canvgr        = &Apache::lonnet::allowed('vgr', $crs_sec);
     my $canmgr        = &Apache::lonnet::allowed('mgr', $crs_sec);      my $canmgr        = &Apache::lonnet::allowed('mgr', $crs_sec);
Line 368  sub secondary_menu { Line 403  sub secondary_menu {
     if ($env{'request.course.id'}) {      if ($env{'request.course.id'}) {
         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};          $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};          $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
         unless ($canedit) {          unless ($canedit || $canvieweditor) {
             unless (&Apache::lonnet::is_on_map("public/$cdom/$cnum/syllabus")) {              unless (&Apache::lonnet::is_on_map("public/$cdom/$cnum/syllabus")) {
                 if (($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'}) ||                  if (($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'}) ||
                     ($env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'}) ||                      ($env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'}) ||
Line 381  sub secondary_menu { Line 416  sub secondary_menu {
                 $showfeeds = 1;                  $showfeeds = 1;
             }              }
         }          }
         unless ($canmgr) {          unless ($canmgr || $canvgr) {
             my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom);              my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom);
             if (keys(%slots) > 0) {              if (keys(%slots) > 0) {
                 $showresv = 1;                  $showresv = 1;
Line 411  sub secondary_menu { Line 446  sub secondary_menu {
         next if    $$menuitem[4]   ne 'always'          next if    $$menuitem[4]   ne 'always'
                 && ($$menuitem[4]  ne 'author' && $$menuitem[4] ne 'cca')                  && ($$menuitem[4]  ne 'author' && $$menuitem[4] ne 'cca')
                 && !$env{'request.course.id'};                  && !$env{'request.course.id'};
         next if    $$menuitem[4]   =~ /^mdc/          next if    $$menuitem[4]   =~ /^crsedit/
                 && !$canedit;                  && (!$canedit && !$canvieweditor);
         next if    $$menuitem[4]  eq 'mdcCourse'          next if    $$menuitem[4]  eq 'crseditCourse'
                 && ($crstype eq 'Community');                  && ($crstype eq 'Community');
         next if    $$menuitem[4]  eq 'mdcCommunity'          next if    $$menuitem[4]  eq 'crseditCommunity'
                 && ($crstype eq 'Course');                  && ($crstype eq 'Course');
         next if    $$menuitem[4]  eq 'nvgr'          next if    $$menuitem[4]  eq 'nvgr'
                 && $canvgr;                  && $canvgr;
         next if    $$menuitem[4]  eq 'vgr'          next if    $$menuitem[4]  eq 'vgr'
                 && !$canvgr;                  && !$canvgr;
         next if    $$menuitem[4]   eq 'cst'          next if    $$menuitem[4]   eq 'viewusers'
                 && !$canmodifyuser;                  && !$canmodifyuser && !$canviewusers;
         next if    $$menuitem[4]   eq 'ncst'          next if    $$menuitem[4]   eq 'noviewusers'
                 && ($canmodifyuser || !$canviewroster);                  && ($canmodifyuser || $canviewusers || !$canviewroster);
         next if    $$menuitem[4]   eq 'mgr'          next if    $$menuitem[4]   eq 'mgr'
                 && !$canmgr;                  && !$canmgr;
         next if    $$menuitem[4]   eq 'showresv'          next if    $$menuitem[4]   eq 'showresv'
                 && !$showresv;                  && !$showresv;
         next if    $$menuitem[4]   eq 'whn'          next if    $$menuitem[4]   eq 'whn'
                 && !$canviewwnew;                  && !$canviewwnew;
         next if    $$menuitem[4]   eq 'opa'          next if    $$menuitem[4]   eq 'params'
                 && !$canmodpara;                  && (!$canmodpara && !$canviewpara);
         next if    $$menuitem[4]   eq 'nvcg'          next if    $$menuitem[4]   eq 'nvcg'
                 && ($canviewgrps || !%groups);                  && ($canviewgrps || !%groups);
         next if    $$menuitem[4]   eq 'showsyllabus'          next if    $$menuitem[4]   eq 'showsyllabus'
Line 459  sub secondary_menu { Line 494  sub secondary_menu {
                     if (ref($item) eq 'ARRAY') {                      if (ref($item) eq 'ARRAY') {
                         next if ($item->[2] eq 'vgr' && !$canvgr);                          next if ($item->[2] eq 'vgr' && !$canvgr);
                         next if ($item->[2] eq 'opa' && !$canmodpara);                          next if ($item->[2] eq 'opa' && !$canmodpara);
                         next if ($item->[2] eq 'cst' && !$canmodifyuser);                          next if ($item->[2] eq 'vpa' && !$canviewpara);
                           next if ($item->[2] eq 'viewusers' && !($canmodifyuser || $canviewusers));
                         next if ($item->[2] eq 'mgr' && !$canmgr);                          next if ($item->[2] eq 'mgr' && !$canmgr);
                         next if ($item->[2] eq 'vcg' && !$canviewgrps);                          next if ($item->[2] eq 'vcg' && !$canviewgrps);
                         next if ($item->[2] eq 'mdc' && !$canedit);                          next if ($item->[2] eq 'crsedit' && !$canedit && !$canvieweditor);
                         push(@scndsub,$item);                           push(@scndsub,$item); 
                     }                      }
                 }                  }
Line 510  sub secondary_menu { Line 546  sub secondary_menu {
             my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};              my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
             ($escurl = $env{'request.filename'}) =~ s{^\Q$londocroot\E}{};              ($escurl = $env{'request.filename'}) =~ s{^\Q$londocroot\E}{};
             $escurl  = &escape($escurl);              $escurl  = &escape($escurl);
         }              }
         $menu =~ s/\[url\]/$escurl/g;          $menu =~ s/\[url\]/$escurl/g;
         $menu =~ s/\[symb\]/$escsymb/g;          $menu =~ s/\[symb\]/$escsymb/g;
     }      }
Line 536  sub create_submenu { Line 572  sub create_submenu {
     if ($target ne '') {      if ($target ne '') {
         $disptarget = ' target="'.$target.'"';          $disptarget = ' target="'.$target.'"';
     }      }
     my $name;  
     if ($title eq 'Personal') {  
         if ($env{'user.name'} && $env{'user.domain'}) {  
             $name = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});  
         } else {  
             $name = &mt($title);  
         }  
     } else {  
         $name = &mt($title);  
     }  
     my $menu = '<li class="LC_hoverable '.$addclass.'">'.      my $menu = '<li class="LC_hoverable '.$addclass.'">'.
                '<a href="'.$link.'"'.$disptarget.'>'.                 '<a href="'.$link.'"'.$disptarget.'>'.
                '<span class="LC_nobreak">'.$name.                 '<span class="LC_nobreak">'.$title.
                '<span class="LC_fontsize_small" style="font-weight:normal;">'.                 '<span class="LC_fontsize_small" style="font-weight:normal;">'.
                ' &#9660;</span></span></a>'.                 ' &#9660;</span></span></a>'.
                '<ul>';                 '<ul>';
   
       # $link and $title are only used in the initial string written in $menu
       # as seen above, not needed for nested submenus
       $menu .= &build_submenu($target, $submenu, $translate, '1');
       $menu .= '</ul></li>';
   
       return $menu;
   }
   
   # helper routine for create_submenu
   # build the dropdown (and nested submenus) recursively
   # see perldoc create_submenu documentation for further information
   sub build_submenu {
       my ($target, $submenu, $translate, $first_level) = @_;
       unless (@{$submenu}) {
           return '';
       }
   
       my $menu = '';
     my $count = 0;      my $count = 0;
     my $numsub = scalar(@{$submenu});      my $numsub = scalar(@{$submenu});
     foreach my $item (@{$submenu}) {      foreach my $item (@{$submenu}) {
         $count ++;          $count ++;
         if (ref($item) eq 'ARRAY') {          if (ref($item) eq 'ARRAY') {
             my $href = $item->[0];              my $href = $item->[0];
             if ($href =~ /(aboutme|rss\.html)$/) {              my $bordertop;
                 next unless (($env{'user.name'} ne '') && ($env{'user.domain'} ne ''));  
                 $href =~ s/\[domain\]/$env{'user.domain'}/g;  
                 $href =~ s/\[user\]/$env{'user.name'}/g;  
             }  
             my $borderbot;              my $borderbot;
             if ($count == $numsub) {              my $title;
                 $borderbot = 'border-bottom:1px solid black;';  
             }  
             unless (($href eq '') || ($href =~ /^\#/)) {  
                 $target = ' target="_top"';  
             }  
             $menu .= '<li style="margin:0;padding:0;'.  
                      $borderbot.'"><a href="'.$href.'"'.$target.'>';  
             if ($translate) {              if ($translate) {
                 $menu .= &mt($item->[1]);                   $title = &mt($item->[1]);
             } else {              } else {
                 $menu .= $item->[1];                  $title = $item->[1];
               }
   
               if ($count == 1 && !$first_level) {
                   $bordertop = 'border-top: 1px solid black;';
               }
               if ($count == $numsub) {
                   $borderbot = 'border-bottom: 1px solid black;';
               }
   
               # href is a reference to another submenu
               if (ref($href) eq 'ARRAY') {
                   $menu .= '<li style="margin:0;padding:0;'.$bordertop . $borderbot . '">';
                   $menu .= '<p><span class="LC_primary_menu_innertitle">'
                                           . $title . '</span><span class="LC_primary_menu_innerarrow">&#9654;</span></p>';
                   $menu .= '<ul>';
                   $menu .= &build_submenu($target, $href, $translate);
                   $menu .= '</ul>';
                   $menu .= '</li>';
               } else {    # href is the actual hyperlink and does not represent another submenu
                           # for the current menu title
                   if ($href =~ /(aboutme|rss\.html)$/) {
                       next unless (($env{'user.name'} ne '') && ($env{'user.domain'} ne ''));
                       $href =~ s/\[domain\]/$env{'user.domain'}/g;
                       $href =~ s/\[user\]/$env{'user.name'}/g;
                   }
                   unless (($href eq '') || ($href =~ /^\#/)) {
                       $target = ' target="_top"';
                   }
   
                   $menu .= '<li style="margin:0;padding:0;'. $bordertop . $borderbot .'">';
                   $menu .= '<a href="'.$href.'"'.$target.'>' .  $title . '</a>';
                   $menu .= '</li>';
             }              }
             $menu .= '</a></li>';  
         }          }
     }      }
     $menu .= '</ul></li>';  
     return $menu;      return $menu;
 }  }
   
Line 613  sub registerurl { Line 678  sub registerurl {
 }  }
   
 sub innerregister {  sub innerregister {
     my ($forcereg,$bread_crumbs,$group) = @_;      my ($forcereg,$bread_crumbs,$group,$pagebuttonshide) = @_;
     my $const_space = ($env{'request.state'} eq 'construct');      my $const_space = ($env{'request.state'} eq 'construct');
     my $is_const_dir = 0;      my $is_const_dir = 0;
   
Line 759  sub innerregister { Line 824  sub innerregister {
             $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};              $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
             $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};              $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
             $perms{'mdc'} = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});              $perms{'mdc'} = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});
               $perms{'cev'} = &Apache::lonnet::allowed('cev',$env{'request.course.id'});
             my @privs;              my @privs;
             if ($env{'request.symb'} ne '') {              if ($env{'request.symb'} ne '') {
                 if ($env{'request.filename'}=~/$LONCAPA::assess_re/) {                  if ($env{'request.filename'}=~/$LONCAPA::assess_re/) {
                     push(@privs,('mgr','vgr'));                      push(@privs,('mgr','vgr'));
                 }                  }
                 push(@privs,'opa');                  push(@privs,('opa','vpa'));
             }              }
             foreach my $priv (@privs) {              foreach my $priv (@privs) {
                 $perms{$priv} = &Apache::lonnet::allowed($priv,$env{'request.course.id'});                  $perms{$priv} = &Apache::lonnet::allowed($priv,$env{'request.course.id'});
Line 790  sub innerregister { Line 856  sub innerregister {
                                        'Content Submissions');                                         'Content Submissions');
                 }                  }
             }              }
             if (($env{'request.symb'} ne '') && ($perms{'opa'})) {              if (($env{'request.symb'} ne '') && (($perms{'opa'}) || ($perms{'vpa'}))) {
                 $hwkadd .= &switch('','',7,3,'pparm.png','Content Settings',                  $hwkadd .= &switch('','',7,3,'pparm.png','Content Settings',
                                    'parms[_2]',"gocmd('/adm/parmset','set')",                                     'parms[_2]',"gocmd('/adm/parmset','set')",
                                    'Content Settings');                                     'Content Settings');
Line 800  sub innerregister { Line 866  sub innerregister {
 #  #
 # This applies to items inside a folder/page modifiable in the course.  # This applies to items inside a folder/page modifiable in the course.
 #  #
             if (($env{'request.symb'}=~/^uploaded/) && ($perms{'mdc'})) {              if (($env{'request.symb'}=~/^uploaded/) && (($perms{'mdc'}) || ($perms{'cev'}))) {
                 my $text = 'Edit Folder';                  my $text = 'Edit Folder';
                 if (($mapurl =~ /\.page$/) ||                  if (($mapurl =~ /\.page$/) ||
                     ($env{'request.symb'}=~                      ($env{'request.symb'}=~
Line 899  if ($env{'browser.mobile'}) { Line 965  if ($env{'browser.mobile'}) {
     $is_mobile = 1;      $is_mobile = 1;
 }  }
   
             unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme|viewclasslist|portfolio)(\?|$)/) {              unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme|viewclasslist|portfolio|ext\.tool)(\?|$)/) {
  if ((!$env{'request.enc'}) && ($env{'request.noversionuri'} !~ m{^/adm/wrapper/ext/}) && ($env{'request.noversionuri'} !~ m{^/uploaded/$match_domain/$match_courseid/docs/})) {   if ((!$env{'request.enc'}) && ($env{'request.noversionuri'} !~ m{^/adm/wrapper/ext/}) && ($env{'request.noversionuri'} !~ m{^/uploaded/$match_domain/$match_courseid/docs/})) {
     $menuitems.=(<<ENDREALRES);      $menuitems.=(<<ENDREALRES);
 s&6&3&catalog.png&$swtext{'catalog'}&info[_1]&catalog_info('$is_mobile')&Show Metadata  s&6&3&catalog.png&$swtext{'catalog'}&info[_1]&catalog_info('$is_mobile')&Show Metadata
Line 967  ENDMENUITEMS Line 1033  ENDMENUITEMS
     my $addremote=0;      my $addremote=0;
     foreach (@inlineremote) { if ($_ ne '') { $addremote=1; last;} }      foreach (@inlineremote) { if ($_ ne '') { $addremote=1; last;} }
             if ($addremote) {              if ($addremote) {
                   my ($countdown,$buttonshide);
                 &Apache::lonhtmlcommon::clear_breadcrumb_tools();  
   
                 &Apache::lonhtmlcommon::add_breadcrumb_tool(  
                     'navigation', @inlineremote[21,23]);  
   
                 my $countdown;  
                 if ($env{'request.filename'} =~ /\.page$/) {                  if ($env{'request.filename'} =~ /\.page$/) {
                     my %breadcrumb_tools = &Apache::lonhtmlcommon::current_breadcrumb_tools();                      my %breadcrumb_tools = &Apache::lonhtmlcommon::current_breadcrumb_tools();
                     if (ref($breadcrumb_tools{'tools'}) eq 'ARRAY') {                      if (ref($breadcrumb_tools{'tools'}) eq 'ARRAY') {
                         $countdown = $breadcrumb_tools{'tools'}[0];                          $countdown = $breadcrumb_tools{'tools'}->[0];
                     }                      }
                       $buttonshide = $pagebuttonshide;
                 } else {                  } else {
                     $countdown = &countdown_timer();                      $countdown = &countdown_timer();
                       $buttonshide = &hidden_button_check();
                 }                  }
                 if (&hidden_button_check() eq 'yes') {  
                   &Apache::lonhtmlcommon::clear_breadcrumb_tools();
   
                   &Apache::lonhtmlcommon::add_breadcrumb_tool(
                       'navigation', @inlineremote[21,23]);
   
                   if ($buttonshide eq 'yes') {
                     if ($countdown) {                      if ($countdown) {
                         &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$countdown);                          &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$countdown);
                     }                      }
Line 1335  sub get_editbutton { Line 1403  sub get_editbutton {
     my ($cfile,$home,$switchserver,$forceedit,$forceview,$forcereg) = @_;      my ($cfile,$home,$switchserver,$forceedit,$forceview,$forcereg) = @_;
     my $jscall;      my $jscall;
     if (($forceview) && ($env{'form.todocs'})) {      if (($forceview) && ($env{'form.todocs'})) {
         my ($folderpath,$command);          my ($folderpath,$command,$navmap);
         if ($env{'request.symb'}) {          if ($env{'request.symb'}) {
             $folderpath = &Apache::loncommon::symb_to_docspath($env{'request.symb'});              $folderpath = &Apache::loncommon::symb_to_docspath($env{'request.symb'},\$navmap);
         } elsif ($env{'form.folderpath'} =~ /^supplemental/) {          } elsif ($env{'form.folderpath'} =~ /^supplemental/) {
             $folderpath = $env{'form.folderpath'};              $folderpath = $env{'form.folderpath'};
             $command = '&forcesupplement=1';              $command = '&forcesupplement=1';
Line 1345  sub get_editbutton { Line 1413  sub get_editbutton {
         $folderpath = &escape(&HTML::Entities::encode(&escape($folderpath),'<>&"'));          $folderpath = &escape(&HTML::Entities::encode(&escape($folderpath),'<>&"'));
         $jscall = "go('/adm/coursedocs?folderpath=$folderpath$command')";          $jscall = "go('/adm/coursedocs?folderpath=$folderpath$command')";
     } else {      } else {
           my $suppanchor;
           if ($env{'form.folderpath'}) {
               $suppanchor = $env{'form.anchor'};
           }
         $jscall = &Apache::lonhtmlcommon::jump_to_editres($cfile,$home,$switchserver,          $jscall = &Apache::lonhtmlcommon::jump_to_editres($cfile,$home,$switchserver,
                                                 $forceedit,$forcereg,$env{'request.symb'},                                                  $forceedit,$forcereg,$env{'request.symb'},
                                                 &escape($env{'form.folderpath'}),                                                  &escape($env{'form.folderpath'}),
                                                 &escape($env{'form.title'}),$env{'form.idx'},                                                  &escape($env{'form.title'}),$env{'form.idx'},
                                                 &escape($env{'form.suppurl'},$env{'form.todocs'}));                                                  &escape($env{'form.suppurl'}),$env{'form.todocs'},
                                                   $suppanchor);
     }      }
     if ($jscall) {      if ($jscall) {
         my $icon = 'pcstr.png';          my $icon = 'pcstr.png';
Line 1428  sub prepare_functions { Line 1501  sub prepare_functions {
 # This applies in course context  # This applies in course context
 #  #
         if (($perms{'mdc'}) &&          if (($perms{'mdc'}) &&
             (($resurl eq "/public/$cdom/$cnum/syllabus") ||              (($resurl =~ m{^/?public/$cdom/$cnum/syllabus}) ||
             ($resurl =~ m{^/uploaded/$cdom/$cnum/portfolio/syllabus/}))) {              ($resurl =~ m{^/?uploaded/$cdom/$cnum/portfolio/syllabus/}))) {
             $cfile = $resurl;              if ($resurl =~ m{^/}) {
                   $cfile = $resurl;
               } else {
                   $cfile = "/$resurl";
               }
             $home = &Apache::lonnet::homeserver($cnum,$cdom);              $home = &Apache::lonnet::homeserver($cnum,$cdom);
             if ($env{'form.forceedit'}) {              if ($env{'form.forceedit'}) {
                 $forceview = 1;                  $forceview = 1;
Line 1515  sub prepare_functions { Line 1592  sub prepare_functions {
         if (($env{'form.folderpath'} =~ /^supplemental/) &&          if (($env{'form.folderpath'} =~ /^supplemental/) &&
             (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) &&              (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) &&
             (($resurl =~ m{^/adm/wrapper/ext/}) ||              (($resurl =~ m{^/adm/wrapper/ext/}) ||
                ($resurl =~ m{^/adm/$cdom/$cnum/\d+/ext\.tool$}) ||
              ($resurl =~ m{^/uploaded/$cdom/$cnum/supplemental/}) ||               ($resurl =~ m{^/uploaded/$cdom/$cnum/supplemental/}) ||
              ($resurl eq '/adm/supplemental') ||               ($resurl eq '/adm/supplemental') ||
              ($resurl =~ m{^/public/$cdom/$cnum/syllabus$}) ||               ($resurl =~ m{^/public/$cdom/$cnum/syllabus$}) ||
              ($resurl =~ m{^/adm/$match_domain/$match_username/aboutme$}))) {               ($resurl =~ m{^/adm/$match_domain/$match_username/aboutme$}))) {
             my @folders=split('&',$env{'form.folderpath'});              my @folders=split('&',$env{'form.folderpath'});
             if ((@folders > 2) || ($resurl ne '/adm/supplemental')) {              if ((@folders > 2) || ($resurl ne '/adm/supplemental')) {
                   my $suppanchor;
                   if ($resurl =~ m{^/adm/wrapper/ext/}) {
                       $suppanchor = $env{'form.anchor'};
                   }
                 my $esc_path=&escape(&HTML::Entities::encode(&escape($env{'form.folderpath'}),'<>&"'));                  my $esc_path=&escape(&HTML::Entities::encode(&escape($env{'form.folderpath'}),'<>&"'));
                 &switch('','',7,4,'docs-22x22.png','Edit Folder','parms[_2]',                  &switch('','',7,4,'docs-22x22.png','Edit Folder','parms[_2]',
                         "location.href='/adm/coursedocs?command=direct&amp;forcesupplement=1&amp;supppath=$esc_path'",                          "location.href='/adm/coursedocs?command=direct&amp;forcesupplement=1&amp;supppath=$esc_path&amp;anchor=$suppanchor'",
                         'Folder/Page Content','','',1);                          'Folder/Page Content','','',1);
             }              }
         }          }
Line 2017  function toggleCountdown() { Line 2099  function toggleCountdown() {
 END  END
 }  }
   
   # This creates a "done button" for timed events.  The confirmation box is a jQuery
   # dialog widget. If the interval parameter requires a proctor key for the timed
   # event to be marked done, there will also be a textbox where that can be entered.
   # Clicking OK will set the value of LC_interval_done to 'true', and, if needed will
   # set the value of LC_interval_done_proctorpass to the text entered in that box,
   # and submit the corresponding form.
   #
   # The &zero_time() routine in lonhomework.pm is called when a page is rendered if
   # LC_interval_done is true.
   #
   sub done_button_js {
       my ($type,$width,$height,$proctor,$donebuttontext) = @_;
       return unless (($type eq 'map') || ($type eq 'resource'));
       my %lt = &Apache::lonlocal::texthash(
                    title    => 'WARNING!',
                    preamble => 'You are trying to end this timed event early.',
                    map      => 'Confirming that you are done will cause the time to expire and prevent you from changing any answers in the current folder.',
                    resource => 'Confirming that you are done will cause the time to expire for this question, and prevent you from changing your answer(s).',
                    okdone   => 'Click "OK" if you are completely finished.',
                    cancel   => 'Click "Cancel" to continue working.',
                    proctor  => 'Ask a proctor to enter the key, then click "OK" if you are completely finished.',
                    ok       => 'OK',
                    exit     => 'Cancel',
                    key      => 'Key:',
                    nokey    => 'A proctor key is required',
       );
       my $navmap = Apache::lonnavmaps::navmap->new();
       my ($missing,$tried) = (0,0);
       if (ref($navmap)) {
           my @resources=();
           if ($type eq 'map') {
               my ($mapurl,$rid,$resurl)=&Apache::lonnet::decode_symb($env{'request.symb'});
               if ($env{'request.symb'} =~ /\.page$/) {
                   @resources=$navmap->retrieveResources($resurl,sub { $_[0]->is_problem() });
               } else {
                   @resources=$navmap->retrieveResources($mapurl,sub { $_[0]->is_problem() });
               }
           } else {
               my $res = $navmap->getBySymb($env{'request.symb'});
               if (ref($res)) {
                   if ($res->is_problem()) {
                       push(@resources,$res);
                   }
               }
           }
           foreach my $res (@resources) {
               if (ref($res->parts()) eq 'ARRAY') {
                   foreach my $part (@{$res->parts()}) {
                       if (!$res->tries($part)) {
                           $missing++;
                       } else {
                           $tried++;
                       }
                   }
               }
           }
       }
       if ($missing) {
           $lt{'miss'} .= '<p class="LC_error">';
           if ($type eq 'map') {
               $lt{'miss'} .= &mt('Submissions are missing for [quant,_1,question part,question parts] in this folder.',$missing);
           } else {
               $lt{'miss'} .= &mt('Submissions are missing for [quant,_1,part] in this question.',$missing);
           }
           if ($missing > 1) {
               $lt{'miss'} .= ' '.&mt('If you confirm you are done you will be unable to submit answers for them.').'</span>';
           } else {
               $lt{'miss'} .= ' '.&mt('If you confirm you are done you will be unable to submit an answer for it.').'</p>';
           }
       }
       $donebuttontext = &HTML::Entities::encode($donebuttontext,'<>&"');
       if ($proctor) {
           if ($height !~ /^\d+$/) {
               $height = 400;
               if ($missing) {
                   $height += 60;
               }
           }
           if ($width !~ /^\d+$/) {
               $width = 400;
               if ($missing) {
                   $width += 60;
               }
           }
           return <<END;
   <form method="post" name="LCdoneButton" action="">
       <input type="hidden" name="LC_interval_done" value="" />
       <input type="hidden" name="LC_interval_done_proctorpass" value="" />
       <button id="LC_done-confirm-opener" type="button">$donebuttontext</button>
   </form>
   
   <div id="LC_done-confirm" title="$lt{'title'}">
     <p>$lt{'preamble'} $lt{$type}</p>
     $lt{'miss'}
     <p>$lt{'proctor'}</p>
     <form name="LCdoneButtonProctor" action="">
       <label>$lt{'key'}<input type="password" name="LC_interval_done_proctorkey" value="" /></label>
       <input type="submit" tabindex="-1" style="position:absolute; top:-1000px" />
     </form>
     <p>$lt{'cancel'}</p>
   </div>
   
   <script type="text/javascript">
   // <![CDATA[
       \$( "#LC_done-confirm" ).dialog({ autoOpen: false });
       \$( "#LC_done-confirm-opener" ).on("click", function() {
           \$( "#LC_done-confirm" ).dialog("open");
           \$( "#LC_done-confirm" ).dialog({
               height: $height,
               width: $width,
               modal: true,
               resizable: false,
               buttons: [
                   {
                       text: "$lt{'ok'}",
                       click: function() {
                           var proctorkey = \$( '[name="LC_interval_done_proctorkey"]' )[0].value;
                           if ((proctorkey == '') || (proctorkey == null)) {
                               alert("$lt{'nokey'}");
                           } else {
                               \$( '[name="LC_interval_done"]' )[0].value = 'true';
                               \$( '[name="LC_interval_done_proctorpass"]' )[0].value = proctorkey;
                               \$( '[name="LCdoneButton"]' )[0].submit();
                           }
                       },
                   },
                   {
                       text: "$lt{'exit'}",
                       click: function() {
                           \$("#LC_done-confirm").dialog( "close" );
                       }
                   }
               ],
               close: function() {
                   \$( '[name="LC_interval_done_proctorkey"]' )[0].value = '';
               }
           });
           \$( "#LC_done-confirm" ).find( "form" ).on( "submit", function( event ) {
               event.preventDefault();
               \$( '[name="LC_interval_done"]' )[0].value = 'true';
               \$( '[name="LC_interval_done_proctorpass"]' )[0].value = \$( '[name="LC_interval_done_proctorkey"]' )[0].value;
               \$( '[name="LCdoneButton"]' )[0].submit();
           });
   });
   
   // ]]>
   </script>
   
   END
       } else {
           if ($height !~ /^\d+$/) {
               $height = 320;
               if ($missing) {
                   $height += 60;
               }
           }
           if ($width !~ /^\d+$/) {
               $width = 320;
               if ($missing) {
                   $width += 60;
               }
           }
           if ($missing) {
               $lt{'miss'} = '</p>'.$lt{'miss'}.'<p>';
           }
           return <<END;
   
   <form method="post" name="LCdoneButton" action="">
       <input type="hidden" name="LC_interval_done" value="" />
       <button id="LC_done-confirm-opener" type="button">$donebuttontext</button>
   </form>
   
   <div id="LC_done-confirm" title="$lt{'title'}">
       <p>$lt{'preamble'} $lt{$type} $lt{'miss'} $lt{'okdone'} $lt{'cancel'}</p>
   </div>
   
   <script type="text/javascript">
   // <![CDATA[
   \$( "#LC_done-confirm" ).dialog({ autoOpen: false });
   \$( "#LC_done-confirm-opener" ).click(function() {
       \$( "#LC_done-confirm" ).dialog( "open" );
       \$( "#LC_done-confirm" ).dialog({
         resizable: false,
         height: $height,
         width: $width,
         modal: true,
         buttons: [
                    {
                       text: "$lt{'ok'}",
                       click: function() {
                           \$( this ).dialog( "close" );
                           \$( '[name="LC_interval_done"]' )[0].value = 'true';
                           \$( '[name="LCdoneButton"]' )[0].submit();
                       },
                    },
                    {
                        text: "$lt{'exit'}",
                        click: function() {
                            \$( this ).dialog( "close" );
                        },
                     },
                  ],
          });
   });
   // ]]>
   </script>
   
   END
       }
   }
   
 sub utilityfunctions {  sub utilityfunctions {
     my ($httphost) = @_;      my ($httphost) = @_;
     my $currenturl=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));      my $currenturl=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
Line 2079  return (<<ENDUTILITY) Line 2372  return (<<ENDUTILITY)
   
 $dc_popup_cid  $dc_popup_cid
   
 function go(url) {  
    if (url!='' && url!= null) {  
        currentURL = null;  
        currentSymb= null;  
        var lcHostname = setLCHost();  
        window.location.href=lcHostname+url;  
    }  
 }  
   
 $jumptores  $jumptores
   
 function gopost(url,postdata) {  function gopost(url,postdata) {
Line 2283  sub roles_selector { Line 2567  sub roles_selector {
     my ($cdom,$cnum,$httphost) = @_;      my ($cdom,$cnum,$httphost) = @_;
     my $crstype = &Apache::loncommon::course_type();      my $crstype = &Apache::loncommon::course_type();
     my $now = time;      my $now = time;
     my (%courseroles,%seccount,%courseprivs);      my (%courseroles,%seccount,%courseprivs,%roledesc);
     my $is_cc;      my $is_cc;
     my ($js,$form,$switcher,$switchtext);      my ($js,$form,$switcher);
     my $ccrole;      my $ccrole;
     if ($crstype eq 'Community') {      if ($crstype eq 'Community') {
         $ccrole = 'co';          $ccrole = 'co';
     } else {      } else {
         $ccrole = 'cc';          $ccrole = 'cc';
     }      }
     my ($priv,$gotsymb,$destsymb);      my ($privref,$gotsymb,$destsymb);
     my $destinationurl = $ENV{'REQUEST_URI'};      my $destinationurl = $ENV{'REQUEST_URI'};
     if ($destinationurl =~ /\?symb=/) {      if ($destinationurl =~ /\?symb=/) {
         $gotsymb = 1;          $gotsymb = 1;
Line 2313  sub roles_selector { Line 2597  sub roles_selector {
         my $destination = $destinationurl;          my $destination = $destinationurl;
         $destination =~ s/(\?.*)$//;          $destination =~ s/(\?.*)$//;
         if (exists($reqprivs->{$destination})) {          if (exists($reqprivs->{$destination})) {
             $priv = $reqprivs->{$destination};              if ($reqprivs->{$destination} =~ /,/) {
                   @{$privref} = split(/,/,$reqprivs->{$destination});
               } else {
                   $privref = [$reqprivs->{$destination}];
               }
         }          }
     }      }
     if ($env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}) {      if ($env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}) {
         my ($start,$end) = split(/\./,$env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum});          my ($start,$end) = split(/\./,$env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum});
           
         if ((($start) && ($start<0)) ||           if ((($start) && ($start<0)) || 
             (($end) && ($end<$now))  ||              (($end) && ($end<$now))  ||
             (($start) && ($now<$start))) {              (($start) && ($now<$start))) {
Line 2328  sub roles_selector { Line 2615  sub roles_selector {
         }          }
     }      }
     if ($is_cc) {      if ($is_cc) {
         &get_all_courseroles($cdom,$cnum,\%courseroles,\%seccount,\%courseprivs,$priv);          &get_all_courseroles($cdom,$cnum,\%courseroles,\%seccount,\%courseprivs);
       } elsif ($env{'request.role'} =~ m{^\Qcr/$cdom/$cdom-domainconfig/\E(\w+)\.\Q/$cdom/$cnum\E}) {
           &get_customadhoc_roles($cdom,$cnum,\%courseroles,\%seccount,\%courseprivs,\%roledesc,$privref);
     } else {      } else {
         my %gotnosection;          my %gotnosection;
         foreach my $item (keys(%env)) {          foreach my $item (keys(%env)) {
Line 2344  sub roles_selector { Line 2633  sub roles_selector {
                         $gotnosection{$role} = 1;                          $gotnosection{$role} = 1;
                     }                      }
                 }                  }
                 if ($priv ne '') {                  if ((ref($privref) eq 'ARRAY') && (@{$privref} > 0)) {
                     my $cnumsec = $cnum;                      my $cnumsec = $cnum;
                     if ($sec ne '') {                      if ($sec ne '') {
                         $cnumsec .= "/$sec";                          $cnumsec .= "/$sec";
Line 2373  sub roles_selector { Line 2662  sub roles_selector {
             }              }
         }          }
     }      }
     $switchtext = 'Switch role'; # do not translate here  
     my @roles_order = ($ccrole,'in','ta','ep','ad','st');      my @roles_order = ($ccrole,'in','ta','ep','ad','st');
     my $numdiffsec;      my $numdiffsec;
     if (keys(%seccount) == 1) {      if (keys(%seccount) == 1) {
Line 2383  sub roles_selector { Line 2671  sub roles_selector {
     }      }
     if ((keys(%seccount) > 1) || ($numdiffsec > 1)) {      if ((keys(%seccount) > 1) || ($numdiffsec > 1)) {
         my @submenu;          my @submenu;
         $js = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,$priv);          $js = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,\%roledesc,$privref);
         $form =           $form = 
             '<form name="rolechooser" method="post" action="'.$httphost.'/adm/roles">'."\n".              '<form name="rolechooser" method="post" action="'.$httphost.'/adm/roles">'."\n".
             '  <input type="hidden" name="destinationurl" value="'.              '  <input type="hidden" name="destinationurl" value="'.
Line 2423  sub roles_selector { Line 2711  sub roles_selector {
                     $include = 1;                      $include = 1;
                 }                  }
                 if ($include) {                  if ($include) {
                       my $rolename;
                       if ($role =~ m{^cr/$cdom/$cdom\-domainconfig/(\w+)(?:/\w+|$)}) {
                           $rolename = $roledesc{$role};
                           if ($rolename eq '') {
                               $rolename = &mt('Helpdesk [_1]',$1);
                           }
                       } else {
                           $rolename = &Apache::lonnet::plaintext($role);
                       }
                     push(@submenu,['javascript:adhocRole('."'$role'".')',                      push(@submenu,['javascript:adhocRole('."'$role'".')',
                                    &Apache::lonnet::plaintext($role)]);                                     $rolename]);
                 }                  }
             }              }
         }          }
         if (@submenu > 0) {          if (@submenu > 0) {
             $switcher = &create_submenu('','',$switchtext,\@submenu);              $switcher = &create_submenu('','',&mt('Switch role'),\@submenu);
         }          }
     }      }
     return ($js,$form,$switcher);      return ($js,$form,$switcher);
Line 2505  sub get_all_courseroles { Line 2802  sub get_all_courseroles {
     return;      return;
 }  }
   
   sub get_customadhoc_roles {
       my ($cdom,$cnum,$courseroles,$seccount,$courseprivs,$roledesc,$privref) = @_;
       unless ((ref($courseroles) eq 'HASH') && (ref($seccount) eq 'HASH') &&
               (ref($courseprivs) eq 'HASH') && (ref($roledesc) eq 'HASH')) {
           return;
       }
       my $is_helpdesk = 0;
       my $now = time;
       foreach my $role ('dh','da') {
           if ($env{"user.role.$role./$cdom/"}) {
               my ($start,$end)=split(/\./,$env{"user.role.$role./$cdom/"});
               if (!($start && ($now<$start)) && !($end && ($now>$end))) {
                   $is_helpdesk = 1;
                   last;
               }
           }
       }
       if ($is_helpdesk) {
           my ($possroles,$description) = &Apache::lonnet::get_my_adhocroles($cdom.'_'.$cnum);
           my %available;
           if (ref($possroles) eq 'ARRAY') {
               map { $available{$_} = 1; } @{$possroles};
           }
           my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom);
           if (ref($domdefaults{'adhocroles'}) eq 'HASH') {
               if (keys(%{$domdefaults{'adhocroles'}})) {
                   my $numsec = 1;
                   my @sections;
                   my ($allseclist,$cached) =
                       &Apache::lonnet::is_cached_new('courseseclist',$cdom.'_'.$cnum);
                   if (defined($cached)) {
                       if ($allseclist ne '') {
                           @sections = split(/,/,$allseclist);
                           $numsec += scalar(@sections);
                       }
                   } else {
                       my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);
                       @sections = sort(keys(%sections_count));
                       $numsec += scalar(@sections);
                       $allseclist = join(',',@sections);
                       &Apache::lonnet::do_cache_new('courseseclist',$cdom.'_'.$cnum,$allseclist);
                   }
                   my (%adhoc,$gotprivs);
                   my $prefix = "cr/$cdom/$cdom".'-domainconfig';
                   foreach my $role (keys(%{$domdefaults{'adhocroles'}})) {
                       next if (($role eq '') || ($role =~ /\W/));
                       $seccount->{"$prefix/$role"} = $numsec;
                       $roledesc->{"$prefix/$role"} = $description->{$role};  
                       if ((ref($privref) eq 'ARRAY') && (@{$privref} > 0)) {
                           if (exists($env{"user.priv.$prefix/$role./$cdom/$cnum./"})) {
                               $courseprivs->{"$prefix/$role./$cdom/$cnum./"} =
                                   $env{"user.priv.$prefix/$role./$cdom/$cnum./"};
                               $courseprivs->{"$prefix/$role./$cdom/$cnum./$cdom/"} =
                                   $env{"user.priv.$prefix/$role./$cdom/$cnum./$cdom/"};
                               $courseprivs->{"$prefix/$role./$cdom/$cnum./$cdom/$cnum"} =
                                   $env{"user.priv.$prefix/$role./$cdom/$cnum./$cdom/$cnum"};
                           } else {
                               unless ($gotprivs) {
                                   my ($adhocroles,$privscached) =
                                       &Apache::lonnet::is_cached_new('adhocroles',$cdom);
                                   if ((defined($privscached)) && (ref($adhocroles) eq 'HASH')) {
                                       %adhoc = %{$adhocroles};
                                   } else {
                                       my $confname = &Apache::lonnet::get_domainconfiguser($cdom);
                                       my %roledefs = &Apache::lonnet::dump('roles',$cdom,$confname,'rolesdef_');
                                       foreach my $key (keys(%roledefs)) {
                                           (undef,my $rolename) = split(/_/,$key);
                                           if ($rolename ne '') {
                                               my ($systempriv,$domainpriv,$coursepriv) = split(/\_/,$roledefs{$key});
                                               $coursepriv = &Apache::lonnet::course_adhocrole_privs($rolename,$cdom,$cnum,$coursepriv);
                                               $adhoc{$rolename} = join('_',($systempriv,$domainpriv,$coursepriv));
                                           }
                                       }
                                       &Apache::lonnet::do_cache_new('adhocroles',$cdom,\%adhoc);
                                   }
                                   $gotprivs = 1;
                               }
                               ($courseprivs->{"$prefix/$role./$cdom/$cnum./"},
                                $courseprivs->{"$prefix/$role./$cdom/$cnum./$cdom/"},
                                $courseprivs->{"$prefix/$role./$cdom/$cnum./$cdom/$cnum"}) =
                                    split(/\_/,$adhoc{$role});
                           }
                       }
                       if ($available{$role}) {
                           $courseroles->{"$prefix/$role"} = \@sections;
                       }
                   }
               }
           }
       }
       return;
   }
   
 sub jump_to_role {  sub jump_to_role {
     my ($cdom,$cnum,$seccount,$courseroles,$courseprivs,$priv) = @_;      my ($cdom,$cnum,$seccount,$courseroles,$courseprivs,$roledesc,$privref) = @_;
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                 this => 'This role has section(s) associated with it.',                  this => 'This role has section(s) associated with it.',
                 ente => 'Enter a specific section.',                  ente => 'Enter a specific section.',
Line 2539  sub jump_to_role { Line 2929  sub jump_to_role {
         }          }
     }      }
     my $checkroles = 0;      my $checkroles = 0;
     if ($priv && ref($courseprivs) eq 'HASH') {      if ((ref($privref) eq 'ARRAY') && (@{$privref} > 0) && (ref($courseprivs) eq 'HASH')) {
         my (%disallowed,%allowed,@disallow);          my %disallowed;
         foreach my $role (sort(keys(%{$courseprivs}))) {          foreach my $role (sort(keys(%{$courseprivs}))) {
             my $trole;              my $trole;
             if ($role =~ m{^(.+?)\Q./$cdom/$cnum\E}) {              if ($role =~ m{^(.+?)\Q./$cdom/$cnum\E}) {
                 $trole = $1;                  $trole = $1;
             }              }
             if (($trole ne '') && ($trole ne 'cm')) {              if (($trole ne '') && ($trole ne 'cm')) {
                 if ($courseprivs->{$role} =~ /\Q:$priv\E($|:|\&\w+)/) {                  $disallowed{$trole} = 1;
                     $allowed{$trole} = 1;                  foreach my $priv (@{$privref}) { 
                 } else {                      if ($courseprivs->{$role} =~ /\Q:$priv\E($|:|\&\w+)/) {
                     $disallowed{$trole} = 1;                          delete($disallowed{$trole});
                           last;
                       }
                 }                  }
             }              }
         }          }
         foreach my $trole (keys(%disallowed)) {          if (keys(%disallowed) > 0) {
             unless ($allowed{$trole}) {  
                 push(@disallow,$trole);  
             }  
         }  
         if (@disallow > 0) {  
             $checkroles = 1;              $checkroles = 1;
             $js .= "    var disallow = new Array('".join("','",@disallow)."');\n".              $js .= "    var disallow = new Array('".join("','",keys(%disallowed))."');\n".
                    "    var rolecheck = 1;\n";                     "    var rolecheck = 1;\n";
         }          }
     }      }
Line 2659  END Line 3046  END
   
 sub required_privs {  sub required_privs {
     my $privs =  {      my $privs =  {
              '/adm/parmset'      => 'opa',               '/adm/parmset'      => 'opa,vpa',
              '/adm/courseprefs'  => 'opa',               '/adm/courseprefs'  => 'opa,vpa',
              '/adm/whatsnew'     => 'whn',               '/adm/whatsnew'     => 'whn',
              '/adm/populate'     => 'cst',               '/adm/populate'     => 'cst,vpa,vcl',
              '/adm/trackstudent' => 'vsa',               '/adm/trackstudent' => 'vsa',
              '/adm/statistics'   => 'vgr',               '/adm/statistics'   => 'mgr,vgr',
              '/adm/setblock'     => 'dcm',               '/adm/setblock'     => 'dcm,vcb',
              '/adm/coursedocs'   => 'mdc',               '/adm/coursedocs'   => 'mdc',
            };             };
     unless ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'spreadsheet') {      unless ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'spreadsheet') {
Line 2701  sub countdown_timer { Line 3088  sub countdown_timer {
         }          }
         my $duedate = &Apache::lonnet::EXT("resource.0.duedate");          my $duedate = &Apache::lonnet::EXT("resource.0.duedate");
         my @interval=&Apache::lonnet::EXT("resource.0.interval");          my @interval=&Apache::lonnet::EXT("resource.0.interval");
           my ($timelimit,$usesdone,$donebuttontext,$proctor,$secret);
         if (@interval > 1) {          if (@interval > 1) {
               ($timelimit,my $donesuffix) = split(/_/,$interval[0],2);
               if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) {
                   $usesdone = 'done';
                   $donebuttontext = $1;
                   (undef,$proctor,$secret) = split(/_/,$2);
               } elsif ($donesuffix =~ /^done(|_.+)$/) {
                   $donebuttontext = &mt('Done');
                   ($usesdone,$proctor,$secret) = split(/_/,$donesuffix);
               }
             my $first_access=&Apache::lonnet::get_first_access($interval[1]);              my $first_access=&Apache::lonnet::get_first_access($interval[1]);
             if ($first_access > 0) {              if ($first_access > 0) {
                 if ($first_access+$interval[0] > time) {                  if ($first_access+$timelimit > time) {
                     $hastimeleft = 1;                      $hastimeleft = 1;
                 }                  }
             }              }
Line 2712  sub countdown_timer { Line 3109  sub countdown_timer {
         if (($duedate && $duedate > time) ||          if (($duedate && $duedate > time) ||
             (!$duedate && $hastimeleft) ||              (!$duedate && $hastimeleft) ||
             ($slot_name ne '' && $slothastime)) {              ($slot_name ne '' && $slothastime)) {
             my ($collapse,$expand,$alttxt,$title,$currdisp);              my ($collapse,$expand,$alttxt,$title,$currdisp,$donebutton);
             if ((@interval > 1 && $hastimeleft) ||              if ((@interval > 1 && $hastimeleft) ||
                 ($type eq 'Task' && $slothastime)) {                  ($type eq 'Task' && $slothastime)) {
                 $currdisp = 'inline';                  $currdisp = 'inline';
                 $collapse = '&#9658;&nbsp;';                  $collapse = '&#9658;&nbsp;';
                   if ((@interval > 1) && ($hastimeleft)) {
                       if ($usesdone eq 'done') {
                           $donebutton = &done_button_js($interval[1],'','',$proctor,$donebuttontext);
                       }
                   }
             } else {              } else {
                 $currdisp = 'none';                  $currdisp = 'none';
                 $expand = '&#9668;&nbsp;';                  $expand = '&#9668;&nbsp;';
Line 2727  sub countdown_timer { Line 3129  sub countdown_timer {
             }              }
             my $desc = &mt('Countdown to due date/time');              my $desc = &mt('Countdown to due date/time');
             return <<END;              return <<END;
   $donebutton
 <a href="javascript:toggleCountdown();" class="LC_menubuttons_link">  <a href="javascript:toggleCountdown();" class="LC_menubuttons_link">
 <span id="ddcountcollapse" class="LC_menubuttons_inline_text">  <span id="ddcountcollapse" class="LC_menubuttons_inline_text">
 $collapse  $collapse

Removed from v.1.369.2.57  
changed lines
  Added in v.1.369.2.71.2.2


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