--- loncom/interface/lonblockingmenu.pm	2014/06/07 19:13:42	1.12
+++ loncom/interface/lonblockingmenu.pm	2016/10/16 21:49:51	1.19
@@ -2,7 +2,7 @@
 # Routines for configuring blocking of access to collaborative functions, 
 # and specific resources during an exam
 #
-# $Id: lonblockingmenu.pm,v 1.12 2014/06/07 19:13:42 raeburn Exp $
+# $Id: lonblockingmenu.pm,v 1.19 2016/10/16 21:49:51 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -105,6 +105,19 @@ block (including deletion), or when a ne
 
 =over
 
+=item &get_permission()
+
+Returns information about permission user has to set/modify exam
+blocking events.
+
+Inputs: None
+
+Outputs: 2
+    $readonly - true if modification of blocking events is prohibited.
+
+    $allowed  - true if blocking events information can be shown.
+ 
+
 =item &get_timed_items()
 
 Provides perl data structure with information about timed interval
@@ -222,7 +235,7 @@ Side Effects: &update_released_required(
 Generates web form elements used to display, cancel, or modify 
 existing blocking events. 
 
-Inputs: 7 
+Inputs: 8 
       - $r - Apache request object
 
       - $records - Reference to hash of current blocks
@@ -238,6 +251,9 @@ Inputs: 7
 
       - $blockcount - number of existing blocking events in course
 
+      - $readonly - if true, modification not allowed.
+ 
+
 Output: None
 
 Side Effects: prints web form elements (in a table) for current blocks. 
@@ -422,11 +438,10 @@ sub handler {
 
 # ----------------------------------------------------------- Permissions check
 
-    unless ((&Apache::lonnet::allowed('dcm',$env{'request.course.id'})) ||
-            (&Apache::lonnet::allowed('dcm',$env{'request.course.id'}.
-                                      '/'.$env{'request.course.sec'}))) {
+    my ($readonly,$allowed) = &get_permission();
+    unless ($allowed) {
         $env{'user.error.msg'}=
-     "/adm/setblock:dcm:0:0:Cannot set blocking of communications in a course";
+     "/adm/setblock:dcm:0:0:Cannot view/set blocking of communications in a course";
         return HTTP_NOT_ACCEPTABLE;
     }
 
@@ -471,7 +486,7 @@ sub handler {
             $r->print(&Apache::loncourserespicker::create_picker($navmap,
                                      'examblock','resourceblocks',$crstype,
                                      \%blockedmaps,\%blockedresources,
-                                     $env{'form.block'}));
+                                     $env{'form.block'},'','',undef,$readonly));
         } else {
             $r->print($errormsg);
         }
@@ -480,10 +495,12 @@ sub handler {
 
 # -------------------------- Store changes and retrieve latest block information
     my $storeresult;
-    if ($env{'form.action'} eq 'store') {
-        (my $numchanges,$storeresult) = &blockstore($r,$crstype,$blockcount,\%records);
-        if ($numchanges > 0) {
-            $blockcount = &get_blockdates(\%records);
+    unless ($readonly) {
+        if ($env{'form.action'} eq 'store') {
+            (my $numchanges,$storeresult) = &blockstore($r,$crstype,$blockcount,\%records);
+            if ($numchanges > 0) {
+                $blockcount = &get_blockdates(\%records);
+            }
         }
     }
 
@@ -561,6 +578,7 @@ sub handler {
             '<li>'.&mt('accessing content in LON-CAPA portfolios or blogs').'</li>'."\n".
             '<li>'.&mt("generating printouts of $lctype content").'</li>'.
             '<li>'.&mt("accessing $lctype content in specified folders or resources").'</li>'.
+            '<li>'.&mt("changing user's own password").'</li>'.
             '</ul>'.
             '<p class="LC_warning">'.$lt{'blca'}.'<br />'.$lt{'pobl'}.'</p>'
         );
@@ -568,8 +586,10 @@ sub handler {
 
 # ------------------------ Choose between modifying existing block or adding new
     $r->print('<form name="blockform" method="post" action="/adm/setblock?action=store">');
-    if ($blockcount > 0) {
-         $r->print(<<"END");
+    
+    unless ($readonly) { 
+        if ($blockcount > 0) {
+            $r->print(<<"END");
 <div class="LC_left_float">
 <fieldset><legend>$lt{'actt'}</legend>
 <span class="LC_nobreak">
@@ -586,33 +606,62 @@ onclick="toggleAddModify();" />$lt{'addn
 <br clear="all" />
 <div id="showadd" style="display:none">
 END
-    } else {
-        $r->print($lt{'ncbc'}.'<br /><br />'.
-                  '<h4>'.$lt{'addn'}.'</h4>'.
-                  '<input type="hidden" name="blockaction" value="add" />');
+        } else {
+            $r->print($lt{'ncbc'}.'<br /><br />'.
+                      '<h4>'.$lt{'addn'}.'</h4>'.
+                      '<input type="hidden" name="blockaction" value="add" />');
+        }
     }
     my ($navmap,$errormsg) =
         &Apache::loncourserespicker::get_navmap_object($crstype,'examblock');
 
 # --------------------------------------------- Interface for adding a new block
-    &display_addblocker_table($r,$blockcount,\%ltext,\%intervals,
-                              $navmap,$errormsg);
+    if ($readonly) {
+        if (!$blockcount) {
+            $r->print($lt{'ncbc'}.'<br />');
+        }
+    } else {
+        &display_addblocker_table($r,$blockcount,\%ltext,\%intervals,
+                                  $navmap,$errormsg);
+        if ($blockcount > 0) {
+            $r->print('</div>');
+        }
+    }
 
-# ------------------------------------------------- Interface for existig blocks
+# ------------------------------------------------ Interface for existing blocks
     if ($blockcount > 0) {
-        $r->print('</div>');
         &display_blocker_status($r,\%records,\%ltext,\%intervals,
-                                $navmap,$errormsg,$blockcount);
+                                $navmap,$errormsg,$blockcount,$readonly);
     }
-    $r->print(<<"END");
+    unless ($readonly) {
+        $r->print(<<"END");
 <br />
 <input type ="submit" value="$lt{'stor'}" />
-</form>
 END
-    $r->print(&Apache::loncommon::end_page());
+    }
+    $r->print('</form>'.
+              &Apache::loncommon::end_page());
     return OK;
 }
 
+sub get_permission {
+    my %permission;
+    my $allowed = 0;
+    my $readonly = 0;
+    return ($readonly,$allowed) unless ($env{'request.course.id'});
+    if ((&Apache::lonnet::allowed('dcm',$env{'request.course.id'})) ||
+        (&Apache::lonnet::allowed('dcm',$env{'request.course.id'}.'/'.
+                  $env{'request.course.sec'}))) {
+        $allowed = 1;
+    } elsif ((&Apache::lonnet::allowed('vcb',$env{'request.course.id'})) ||
+             (&Apache::lonnet::allowed('vcb',$env{'request.course.id'}.'/'.
+                  $env{'request.course.sec'}))) {
+        $readonly = 1;
+        $allowed = 1;
+    }
+    return ($readonly,$allowed);
+}
+
 sub get_timed_items {
     my ($cdom,$cnum) = @_;
     my ($cid,%intervals);
@@ -913,6 +962,9 @@ sub get_block_choices {
                     if (ref($symb_ref) eq 'HASH') {
                         my %resources = map { $symb_ref->{$_} => 1; } 
                                             (split(/,/,$env{'form.docs_resources_'.$item}));
+                        if (exists($resources{''})) {
+                            delete($resources{''});
+                        }
                         $blocklist->{$type}->{resources} = \%resources;
                         if (keys(%resources) > 0) {
                             $blockdocs = 1;
@@ -924,6 +976,9 @@ sub get_block_choices {
                     if (ref($map_ref) eq 'HASH') {
                         my %maps = map { $map_ref->{$_} => 1; }                             
                                        (split(/,/,$env{'form.docs_maps_'.$item}));
+                        if (exists($maps{''})) {
+                            delete($maps{''});
+                        }
                         $blocklist->{$type}->{maps} = \%maps;
                         if (keys(%maps) > 0) {
                             $blockdocs = 1;
@@ -968,9 +1023,9 @@ sub check_release_required {
 }
 
 sub display_blocker_status {
-    my ($r,$records,$ltext,$intervals,$navmap,$errormsg,$blockcount) = @_;
+    my ($r,$records,$ltext,$intervals,$navmap,$errormsg,$blockcount,$readonly) = @_;
     my $parmcount = 0;
-    my (%map_url,%resource_symb,%titles,%lookups);
+    my (%map_url,%resource_symb,%titles,%lookups,$disabled);
     &Apache::loncourserespicker::enumerate_course_contents($navmap,\%map_url,\%resource_symb,\%titles,'examblock');
     %{$lookups{'maps'}} = reverse(%map_url);
     %{$lookups{'resources'}} = reverse(%resource_symb);
@@ -980,10 +1035,13 @@ sub display_blocker_status {
         'noch' => 'No change',
     );
     $r->print('<div id="showmodify" style="display:block">'.
-              &Apache::loncommon::start_data_table());
+              &Apache::loncommon::start_data_table().'<tr>');
+    if ($readonly) {
+        $disabled = ' disabled="disabled"';
+    } else {
+        $r->print('<th></th>');
+    }
     $r->print(<<"END");
-  <tr>
-    <th></th>
     <th>$ltext->{'type'}</th>
     <th>$ltext->{'even'}</th>
     <th>$ltext->{'blck'}</th>
@@ -1002,8 +1060,12 @@ END
            &Apache::loncommon::aboutmewrapper(
                            &Apache::loncommon::plainname($setuname,$setudom),
                            $setuname,$setudom);
+        my $state = '';
         $r->print(&Apache::loncommon::start_data_table_row());
-        $r->print(<<"ACT");
+        if ($readonly) {
+            $state = 'disabled';
+        } else {
+            $r->print(<<"ACT");
 
         <td valign="middle"><span class="LC_nobreak"><label>
         <input type="radio" name="action_$parmcount" value="modify" />$lt{'modi'}
@@ -1017,13 +1079,16 @@ END
         </label></span>
         </td>
 ACT
+        }
         my ($start,$end,$startform,$endform); 
         if ($record =~ /^(\d+)____(\d+)$/) {
             ($start,$end) = split(/____/,$record);
             $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.
-                                                             $parmcount,$start,$onchange);
+                                                             $parmcount,$start,$onchange,
+                                                             undef,$state);
             $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.
-                                                           $parmcount,$end,$onchange);
+                                                           $parmcount,$end,$onchange,
+                                                           undef,$state);
             $r->print('<td><fieldset><legend>'.$ltext->{'defs'}.'</legend>'.
                       $ltext->{'star'}.':&nbsp;'.$startform.'<br />'.
                       $ltext->{'endd'}.':&nbsp;&nbsp;'.$endform.'</fieldset></td>');
@@ -1047,16 +1112,26 @@ ACT
                 if (&Apache::lonnet::is_on_map($url)) { 
                     if ($type eq 'map') {
                         if (ref($navmap)) {
-                            my $res = $navmap->getResourceByUrl($item);
-                            my $title = $res->compTitle();
+                            my $title;
+                            my $resobj = $navmap->getResourceByUrl($item);
+                            if (ref($resobj)) { 
+                                $title = $resobj->compTitle();
+                            } else {
+                                $title = &Apache::lonnet::gettitle($item);
+                            }
                             $itemname = &mt('Timer for all items in folder: [_1]',
                                             '<span style="font-style:italic">'.
                                             $title.'</span>');
                         }
                     } else {
                         if (ref($navmap)) {
-                            my $res = $navmap->getBySymb($item);
-                            my $title = $res->compTitle();
+                            my $title;
+                            my $resobj = $navmap->getBySymb($item);
+                            if (ref($resobj)) {
+                                $title = $resobj->compTitle();
+                            } else {
+                                $title = &Apache::lonnet::gettitle($item);
+                            }
                             $itemname = &mt('Timer for resource: [_1]',
                                              '<span style="font-style:italic">'.
                                              $title.'</span>');
@@ -1143,18 +1218,18 @@ ACT
                 }
             }
             $r->print(&create_interval_form($intervals,$parmcount,$navmap,$item,$jschg,
-                                            $itemname,$iteminfo).'</fieldset></td>');
+                                            $itemname,$iteminfo,$disabled).'</fieldset></td>');
         }
         $r->print(<<"END");
         <td>
-         <input type="text" name="title_$parmcount" size="15" value="$title" onfocus="$jschg" />
+         <input type="text" name="title_$parmcount" size="15" value="$title" onfocus="$jschg" $disabled />
          <input type="hidden" name="key_$parmcount" value="$blockid" />
          <br />
          <br />
          $ltext->{'setb'}: $settername
         </td>
 END
-        $r->print('<td>'.&blocker_checkboxes($parmcount,$blocks,$jschg,\%lookups).'</td>'.
+        $r->print('<td>'.&blocker_checkboxes($parmcount,$blocks,$jschg,\%lookups,$disabled).'</td>'.
                   &Apache::loncommon::end_data_table_row());
         $parmcount++;
     }
@@ -1244,7 +1319,7 @@ END
 }
 
 sub blocker_checkboxes {
-    my ($parmcount,$blocks,$jschg,$lookups) = @_;
+    my ($parmcount,$blocks,$jschg,$lookups,$disabled) = @_;
     my ($typeorder,$types) = &blocktype_text();
     my $numinrow = 2;
     my %currdocs;
@@ -1311,7 +1386,7 @@ sub blocker_checkboxes {
         } 
         $output .= '<span class="LC_nobreak"><label>'."\n".
                    '<input type="checkbox" id="'.$item.'" name="'.$item.'"'.
-                   $blockstatus.$clickaction.' value="1" />'.
+                   $blockstatus.$clickaction.' value="1"'.$disabled.' />'.
                    $types->{$block}.'</label></span>'."\n";
         if ($block eq 'docs') {
             if ($blockstatus ne '') {
@@ -1330,7 +1405,7 @@ sub blocker_checkboxes {
 }
 
 sub create_interval_form {
-    my ($intervals,$parmcount,$navmap,$currkey,$jschg,$itemname,$iteminfo) = @_;
+    my ($intervals,$parmcount,$navmap,$currkey,$jschg,$itemname,$iteminfo,$disabled) = @_;
     return unless ((ref($intervals) eq 'HASH') && (ref($navmap)));
     my $intervalform;
     if (keys(%{$intervals}) > 0) {
@@ -1343,7 +1418,7 @@ sub create_interval_form {
                     $clickaction = ' onclick="'.$jschg.'"';
                 }
                 $intervalform .= '<label><input type="radio" name="firstaccess_'.$parmcount.
-                                 '" value="course"'.$checked.$clickaction.' />';
+                                 '" value="course"'.$checked.$clickaction.$disabled.' />';
                 if ($currkey eq 'course') {
                     $intervalform .= $itemname;
                 } else {
@@ -1358,6 +1433,8 @@ sub create_interval_form {
                 if (ref($intervals->{$type}) eq 'HASH') {
                     if (ref($navmap)) {
                         foreach my $map (sort(keys(%{$intervals->{$type}}))) {
+                            next if ((!&Apache::lonnet::is_on_map($map)) &&
+                                     ($currkey ne $map));
                             my ($checked,$clickaction);
                             if ($currkey eq $map) {
                                 $checked = ' checked="checked"';
@@ -1366,14 +1443,18 @@ sub create_interval_form {
                             }
                             $intervalform .= '<label><input type="radio" name="firstaccess_'.$parmcount.
                                              '" value="'.&HTML::Entities::encode($map,'"<>&').'"'.
-                                             $checked.$clickaction.' />';
+                                             $checked.$clickaction.$disabled.' />';
                             if ($currkey eq $map) {
-                                $intervalform .= $itemname.'</label>';
+                                $intervalform .= $itemname.'</label>'.$iteminfo;
                             } else {
-                                my $res = $navmap->getResourceByUrl($map);
-                                my $title = $res->compTitle();
-                                my $path;
-                                my $hierarchy = &show_timer_path($type,$map,$navmap);
+                                my ($resobj,$title,$path,$hierarchy);
+                                $resobj = $navmap->getResourceByUrl($map);
+                                if (ref($resobj)) {
+                                    $title = $resobj->compTitle();
+                                } else {
+                                    $title = &Apache::lonnet::gettitle($map);
+                                }
+                                $hierarchy = &show_timer_path($type,$map,$navmap);
                                 if ($hierarchy) {
                                     $path = ' <span style="font-size:90%;">'.
                                             &mt('(in: [_1])',$hierarchy).
@@ -1383,9 +1464,6 @@ sub create_interval_form {
                                                      '<i>'.$title.'</i>').
                                                  '</label>'.$path;
                             }
-                            if ($currkey eq $map) {
-                                $intervalform .= $iteminfo;
-                            }
                             $intervalform .= '<br />';
                         }
                     }
@@ -1394,22 +1472,29 @@ sub create_interval_form {
                 if (ref($intervals->{$type}) eq 'HASH') {
                     if (ref($navmap)) {
                         foreach my $resource (sort(keys(%{$intervals->{$type}}))) {
-                            my ($checked,$clickaction);
+                            my ($checked,$clickaction,$resobj);
                             if ($currkey eq $resource) {
                                 $checked = ' checked="checked"';
-                            } elsif ($jschg) {
-                                $clickaction = ' onclick="'.$jschg.'"';
+                            } else {
+                                $resobj = $navmap->getBySymb($resource);
+                                next unless(ref($resobj));
+                                if ($jschg) {
+                                    $clickaction = ' onclick="'.$jschg.'"';
+                                }
                             }
                             $intervalform .= '<label><input type="radio" name="firstaccess_'.$parmcount.
                                              '" value="'.&HTML::Entities::encode($resource,'"<>&').'"'.
-                                             $checked.$clickaction.' />';
+                                             $checked.$clickaction.$disabled.' />';
                             if ($currkey eq $resource) {
-                                $intervalform .= $itemname.'</label>';
+                                $intervalform .= $itemname.'</label>'.$iteminfo;
                             } else {
-                                my $res = $navmap->getBySymb($resource);
-                                my $title = $res->compTitle();
-                                my $path;
-                                my $hierarchy = &show_timer_path($type,$resource,$navmap);
+                                my ($title,$path,$hierarchy);
+                                if (ref($resobj)) {
+                                    $title = $resobj->compTitle();
+                                } else {
+                                    $title = &Apache::lonnet::gettitle($resource);
+                                }
+                                $hierarchy = &show_timer_path($type,$resource,$navmap);
                                 if ($hierarchy) {
                                     $path = ' <span style="font-size:90%;">'.
                                             &mt('(in: [_1])',$hierarchy).
@@ -1419,9 +1504,6 @@ sub create_interval_form {
                                                  '</label>'.
                                                  $path;
                             }
-                            if ($currkey eq $resource) {
-                                $intervalform .= $iteminfo;
-                            }
                             $intervalform .= '<br />';
                         }
                     }
@@ -1432,7 +1514,7 @@ sub create_interval_form {
         if ($currkey ne '') {
             $intervalform = '<input type="radio" name="firstaccess_'.$parmcount.
                             '" checked="checked" value="'.
-                            &HTML::Entities::encode($currkey,'"<>&').' />'.
+                            &HTML::Entities::encode($currkey,'"<>&').'"'.$disabled.' />'.
                             $itemname.'<br />';
         } else {
             $intervalform = &mt('No timed items defined.').' '.
@@ -1478,8 +1560,9 @@ sub blocktype_text {
         'blogs' => 'Blogs',
         'docs' => 'Content',
         'printout' => 'Printouts',
+        'passwd' => 'Change Password',
     );
-    my $typeorder = ['com','chat','boards','port','groups','blogs','printout','docs'];
+    my $typeorder = ['com','chat','boards','port','groups','blogs','printout','docs','passwd'];
     return ($typeorder,\%types);
 }