--- loncom/interface/lonblockingmenu.pm 2015/04/15 03:28:19 1.14 +++ loncom/interface/lonblockingmenu.pm 2016/10/23 17:06:49 1.14.2.3 @@ -2,7 +2,7 @@ # Routines for configuring blocking of access to collaborative functions, # and specific resources during an exam # -# $Id: lonblockingmenu.pm,v 1.14 2015/04/15 03:28:19 raeburn Exp $ +# $Id: lonblockingmenu.pm,v 1.14.2.3 2016/10/23 17:06:49 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. @@ -302,13 +318,16 @@ Creates web form elements used to select items in the course for use in an exam block of type: "Triggered by Activating Timer". -Inputs: 7 (three required, last four optional) +Inputs: 8 (four required, last four optional) - $intervals - Reference to hash of parameters for timed intervals - $parmcount - numeric ID of current block - $navmap - navmaps object + - $context - this will be "accesstimes" if called by lonaccesstimes.pm, + or "blocking" if called internally by lonblockingmenu.pm + - $currkey - current interval (where this is a block already using an interval-based trigger). @@ -323,6 +342,34 @@ Inputs: 7 (three required, last four opt Outputs: 1 - $intervalform - web form elements used to select a time interval +=item &interval_details() + +Creates name/scope of current interval and expandable/collapsible +showing which interval parameters apply to the current folder/resource + +Inputs: 6 + + - $item - course, map url, or resource symb + + - $type - course, map, or resource + + - $url - url of item (null if item is course). + + - $navmap - navmaps object + + - $intervals - Reference to hash of parameters for timed intervals + + - $parmcount - unique ID for current element. + + +Outputs: 2 + + - $itemname - name/scope of interval (timer) parameter + + - $iteminfo - Expandable/collapsible block showing which interval + (timer) parameters affect the current folder or resource. + + =item &trigger_details_toggle() Creates link used to expand item showing information about timer for current @@ -332,6 +379,7 @@ Inputs: 1 - $parmcount - numericID of ex Outputs: 1 - returns HTML for link to display contents of information item + =item &show_timer_path() Display hierarchy of names of folders/sub-folders containing the current @@ -376,12 +424,21 @@ Output: 1 - Javascript (with tags) for functions used to: + toggle visibility of unordered list for display of detailed + information about intervals. + +=back =cut @@ -422,11 +479,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 +527,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 +536,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); + } } } @@ -503,7 +561,8 @@ sub handler { ({href=>'/adm/setblock', text=>'Blocking communication/content access'}); - my $js = &blockingmenu_javascript($blockcount); + my $js = &blockingmenu_javascript($blockcount). + &details_javascript(); $r->print( &Apache::loncommon::start_page('Blocking communication/content access',$js). @@ -561,6 +620,7 @@ sub handler { '
  • '.&mt('accessing content in LON-CAPA portfolios or blogs').'
  • '."\n". '
  • '.&mt("generating printouts of $lctype content").'
  • '. '
  • '.&mt("accessing $lctype content in specified folders or resources").'
  • '. + '
  • '.&mt("changing user's own password").'
  • '. ''. '

    '.$lt{'blca'}.'
    '.$lt{'pobl'}.'

    ' ); @@ -568,8 +628,10 @@ sub handler { # ------------------------ Choose between modifying existing block or adding new $r->print('
    '); - if ($blockcount > 0) { - $r->print(<<"END"); + + unless ($readonly) { + if ($blockcount > 0) { + $r->print(<<"END");
    $lt{'actt'} @@ -586,33 +648,61 @@ onclick="toggleAddModify();" />$lt{'addn
    '); + unless ($readonly) { + &display_addblocker_table($r,$blockcount,\%ltext,\%intervals, + $navmap,$errormsg); + if ($blockcount > 0) { + $r->print('
    '); + } + } +# ------------------------------------------------ Interface for existing blocks + if (!$blockcount) { + if ($readonly) { + $r->print($lt{'ncbc'}.'
    '); + } + } else { &display_blocker_status($r,\%records,\%ltext,\%intervals, - $navmap,$errormsg,$blockcount); + $navmap,$errormsg,$blockcount,$readonly); } - $r->print(<<"END"); + unless ($readonly) { + $r->print(<<"END");
    -
    END - $r->print(&Apache::loncommon::end_page()); + } + $r->print(''. + &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); @@ -629,7 +719,7 @@ sub get_timed_items { my $resourcedata=&Apache::lonparmset::readdata($cnum,$cdom); if (ref($resourcedata) eq 'HASH') { foreach my $key (keys(%{$resourcedata})) { - if ($key =~ /^\Q$cid\E(.+)\.0\.interval$/) { + if ($key =~ /^\Q$cid\E(.*)\.0\.interval$/) { my $middle = $1; if ($middle eq '') { $intervals{'course'}{'all'} = $resourcedata->{$key}; @@ -974,9 +1064,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); @@ -986,10 +1076,13 @@ sub display_blocker_status { 'noch' => 'No change', ); $r->print('
    '. - &Apache::loncommon::start_data_table()); + &Apache::loncommon::start_data_table().''); + if ($readonly) { + $disabled = ' disabled="disabled"'; + } else { + $r->print(''); + } $r->print(<<"END"); - - $ltext->{'type'} $ltext->{'even'} $ltext->{'blck'} @@ -1008,8 +1101,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"); 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('
    '.$ltext->{'defs'}.''. $ltext->{'star'}.': '.$startform.'
    '. $ltext->{'endd'}.':  '.$endform.'
    '); } elsif ($record =~ /^firstaccess____(.+)$/) { my $item = $1; - my ($itemname,$iteminfo,$skipdetails); my $type = 'map'; my $url; if ($item eq 'course') { @@ -1047,130 +1146,20 @@ ACT $url = $item; } $r->print('
    '.$ltext->{'trig'}.''); - if ($type eq 'course') { - $itemname = &mt('Timer for all items in course.'); - } else { - if (&Apache::lonnet::is_on_map($url)) { - if ($type eq 'map') { - if (ref($navmap)) { - 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]', - ''. - $title.''); - } - } else { - if (ref($navmap)) { - 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]', - ''. - $title.''); - } - } - if (ref($navmap)) { - my $path = &show_timer_path($type,$item); - if ($path) { - $iteminfo = ' '. - &mt('(in: [_1])',$path). - ''; - } - } - } else { - $skipdetails = 1; - $itemname = ''. - &mt('Timer folder/resource not in course'). - ''; - } - } - if ((!$skipdetails) && (ref($intervals) eq 'HASH')) { - if (ref($intervals->{$type}) eq 'HASH') { - $iteminfo .= &trigger_details_toggle($parmcount). - ''; - } - } - $r->print(&create_interval_form($intervals,$parmcount,$navmap,$item,$jschg, - $itemname,$iteminfo).'
    '); + my ($itemname,$iteminfo) = &interval_details($item,$type,$url,$navmap,$intervals,$parmcount); + $r->print(&create_interval_form($intervals,$parmcount,$navmap,'blocking',$item,$jschg, + $itemname,$iteminfo,$disabled).''); } $r->print(<<"END"); - +

    $ltext->{'setb'}: $settername END - $r->print(''.&blocker_checkboxes($parmcount,$blocks,$jschg,\%lookups).''. + $r->print(''.&blocker_checkboxes($parmcount,$blocks,$jschg,\%lookups,$disabled).''. &Apache::loncommon::end_data_table_row()); $parmcount++; } @@ -1222,7 +1211,7 @@ sub display_addblocker_table { my %lt = &Apache::lonlocal::texthash( 'exam' => 'e.g., Exam 1', ); - my $intervalform = &create_interval_form($intervals,$parmcount,$navmap); + my $intervalform = &create_interval_form($intervals,$parmcount,$navmap,'blocking'); if ($intervalform ne '') { $intervalform = '
    '. ''.$ltext->{'chtr'}.''. @@ -1260,7 +1249,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; @@ -1327,7 +1316,7 @@ sub blocker_checkboxes { } $output .= ''."\n"; if ($block eq 'docs') { if ($blockstatus ne '') { @@ -1346,9 +1335,10 @@ sub blocker_checkboxes { } sub create_interval_form { - my ($intervals,$parmcount,$navmap,$currkey,$jschg,$itemname,$iteminfo) = @_; + my ($intervals,$parmcount,$navmap,$context,$currkey,$jschg,$itemname,$iteminfo,$disabled) = @_; return unless ((ref($intervals) eq 'HASH') && (ref($navmap))); my $intervalform; + my $counter = 0; if (keys(%{$intervals}) > 0) { foreach my $type (sort(keys(%{$intervals}))) { if ($type eq 'course') { @@ -1359,7 +1349,7 @@ sub create_interval_form { $clickaction = ' onclick="'.$jschg.'"'; } $intervalform .= ''; if ($currkey eq 'course') { $intervalform .= $iteminfo; + } elsif ($context eq 'accesstimes') { + (undef,$iteminfo) = &interval_details('course',$type,'',$navmap,$intervals,$counter); + if ($iteminfo) { + $intervalform .= ' '.$iteminfo; + } } $intervalform .= '
    '; + $counter ++; } elsif ($type eq 'map') { if (ref($intervals->{$type}) eq 'HASH') { if (ref($navmap)) { @@ -1384,7 +1380,7 @@ sub create_interval_form { } $intervalform .= ''.$iteminfo; } else { @@ -1404,8 +1400,15 @@ sub create_interval_form { $intervalform .= &mt('Timer for all items in folder: [_1]', ''.$title.''). ''.$path; + if ($context eq 'accesstimes') { + (undef,$iteminfo) = &interval_details($map,$type,$map,$navmap,$intervals,$counter); + if ($iteminfo) { + $intervalform .= ' '.$iteminfo; + } + } } $intervalform .= '
    '; + $counter ++; } } } @@ -1425,14 +1428,15 @@ sub create_interval_form { } $intervalform .= ''.$iteminfo; } else { my ($title,$path,$hierarchy); if (ref($resobj)) { $title = $resobj->compTitle(); - } else { + } + if ($title eq '') { $title = &Apache::lonnet::gettitle($resource); } $hierarchy = &show_timer_path($type,$resource,$navmap); @@ -1444,8 +1448,19 @@ sub create_interval_form { $intervalform .= &mt('Timer for resource: [_1]',''.$title.''). ''. $path; + if ($context eq 'accesstimes') { + if (ref($resobj)) { + my $url = $resobj->src(); + if ($url eq '') { + (my $map, my $resid, $url) = &Apache::lonnet::decode_symb($resource); + } + ($itemname,$iteminfo) = &interval_details($resource,$type,$url,$navmap,$intervals,$counter); + $intervalform .= ' '.$iteminfo; + } + } } $intervalform .= '
    '; + $counter ++; } } } @@ -1455,7 +1470,7 @@ sub create_interval_form { if ($currkey ne '') { $intervalform = '&').' />'. + &HTML::Entities::encode($currkey,'"<>&').'"'.$disabled.' />'. $itemname.'
    '; } else { $intervalform = &mt('No timed items defined.').' '. @@ -1473,6 +1488,121 @@ sub trigger_details_toggle { 'style="text-decoration: none;">'.&mt('(More ...)').''; } +sub interval_details { + my ($item,$type,$url,$navmap,$intervals,$parmcount) = @_; + my ($itemname,$iteminfo,$skipdetails); + if ($type eq 'course') { + $itemname = &mt('Timer for all items in course.'); + } else { + if (&Apache::lonnet::is_on_map($url)) { + if ($type eq 'map') { + if (ref($navmap)) { + 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]', + ''. + $title.''); + } + } else { + if (ref($navmap)) { + 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]', + ''. + $title.''); + } + } + if (ref($navmap)) { + my $path = &show_timer_path($type,$item); + if ($path) { + $iteminfo = ' '. + &mt('(in: [_1])',$path). + ''; + } + } + } else { + $skipdetails = 1; + $itemname = ''. + &mt('Timer folder/resource not in course'). + ''; + } + } + if ((!$skipdetails) && (ref($intervals) eq 'HASH') && (ref($intervals->{$type}) eq 'HASH')) { + $iteminfo = &trigger_details_toggle($parmcount). + ''; + } + return ($itemname,$iteminfo); +} + sub show_timer_path { my ($type,$item,$navmap) = @_; return unless(ref($navmap)); @@ -1501,17 +1631,14 @@ 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); } sub blockingmenu_javascript { my ($blockcount) = @_; - my %lt = &Apache::lonlocal::texthash ( - more => 'More ...', - less => 'Less ...', - ); return < // + +ENDSCRIPT + +} + +sub details_javascript { + my %lt = &Apache::lonlocal::texthash ( + more => 'More ...', + less => 'Less ...', + ); + return < +//