--- loncom/interface/lonblockingmenu.pm 2015/04/15 03:28:19 1.14 +++ loncom/interface/lonblockingmenu.pm 2021/01/02 21:07:36 1.29 @@ -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.29 2021/01/02 21:07:36 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 <script></s =item * for action to take -- add or modify block -=item * for display of detailed information about intervals - =back -=back +=item &details_javascript() + +Create Javascript to toggle visibility of unordered list item +containing details about item with timed interval parameter. + +Inputs: none + +Output: 1 Javascript (with <script></script> 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,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). @@ -519,6 +578,7 @@ sub handler { my %lt=&Apache::lonlocal::texthash ( 'cbds' => 'Blocking communication and/or content access during exams', 'prev' => "For the duration of an exam, or a timed quiz, students in this course can be prevented from:", + 'flow' => "For the duration of an exam, or a timed quiz, event-driven interruptions to a student's workflow can be suppressed:", 'blca' => "Blocks can potentially interrupt legitimate communication between $usertype who are also both enrolled in a different LON-CAPA $lctype.", 'pobl' => "Portfolio blocking can impact a student's ability to complete assignments in courses besides your own. Please use this feature wisely.", 'actt' => "Action to take:", @@ -558,9 +618,17 @@ sub handler { '<ul>'."\n". '<li>'.&mt("displaying LON-CAPA messages sent by other $usertype in the $lctype").'</li>'."\n". '<li>'.&mt("displaying or posting to LON-CAPA discussion boards or live chat in the $lctype").'</li>'."\n". - '<li>'.&mt('accessing content in LON-CAPA portfolios or blogs').'</li>'."\n". + '<li>'.&mt('accessing content in LON-CAPA portfolios, blogs, or user information pages').'</li>'."\n". '<li>'.&mt("generating printouts of $lctype content").'</li>'. + '<li>'.&mt("displaying the LON-CAPA gradebook in the $lctype").'</li>'. + '<li>'.&mt("searching $lctype content by keyword").'</li>'. '<li>'.&mt("accessing $lctype content in specified folders or resources").'</li>'. + '<li>'.&mt("changing user's own password").'</li>'. + '</ul>'. + $lt{'flow'}. + '<ul>'."\n". + '<li>'.&mt("re-initialization of cached course structure, when a change has been made to $lctype content by a Coordinator").'</li>'. + '<li>'.&mt('display of Critical Messages when navigation arrows used to move to the adjacent resource').'</li>'. '</ul>'. '<p class="LC_warning">'.$lt{'blca'}.'<br />'.$lt{'pobl'}.'</p>' ); @@ -568,8 +636,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 +656,61 @@ 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); - -# ------------------------------------------------- Interface for existig blocks - if ($blockcount > 0) { - $r->print('</div>'); + unless ($readonly) { + &display_addblocker_table($r,$blockcount,\%ltext,\%intervals, + $navmap,$errormsg); + if ($blockcount > 0) { + $r->print('</div>'); + } + } +# ------------------------------------------------ Interface for existing blocks + if (!$blockcount) { + if ($readonly) { + $r->print($lt{'ncbc'}.'<br />'); + } + } else { &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); @@ -629,7 +727,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}; @@ -787,6 +885,24 @@ sub blockstore { &escape($env{'form.title_'.$key})).'<br />'; } } + if ($blocktypes->{'alert'} eq 'on') { + ($status,$needsrelease) = &check_release_required('alert',$chomemajor,$chomeminor); + if ($status eq 'fail') { + $blocktypes->{'alert'} = 'off'; + $output .= '<p class="LC_warning">'. + &mt('Message Alert blocking not allowed for [_1]', + &escape($env{'form.title_'.$key})).'<br />'; + } + } + if ($blocktypes->{'reinit'} eq 'on') { + ($status,$needsrelease) = &check_release_required('reinit',$chomemajor,$chomeminor); + if ($status eq 'fail') { + $blocktypes->{'reinit'} = 'off'; + $output .= '<p class="LC_warning">'. + &mt('Course Re-initialization blocking not allowed for [_1]', + &escape($env{'form.title_'.$key})).'<br />'; + } + } } if ($blockdocs) { ($status,$needsrelease) = &check_release_required('docs',$chomemajor,$chomeminor); @@ -974,9 +1090,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 +1102,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> @@ -1008,8 +1127,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'} @@ -1023,19 +1146,21 @@ 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'}.': '.$startform.'<br />'. $ltext->{'endd'}.': '.$endform.'</fieldset></td>'); } elsif ($record =~ /^firstaccess____(.+)$/) { my $item = $1; - my ($itemname,$iteminfo,$skipdetails); my $type = 'map'; my $url; if ($item eq 'course') { @@ -1047,130 +1172,20 @@ ACT $url = $item; } $r->print('<td><fieldset><legend>'.$ltext->{'trig'}.'</legend>'); - 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]', - '<span style="font-style:italic">'. - $title.'</span>'); - } - } 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]', - '<span style="font-style:italic">'. - $title.'</span>'); - } - } - if (ref($navmap)) { - my $path = &show_timer_path($type,$item); - if ($path) { - $iteminfo = ' <span style="font-size:90%;">'. - &mt('(in: [_1])',$path). - '</span>'; - } - } - } else { - $skipdetails = 1; - $itemname = '<span style="LC_warning">'. - &mt('Timer folder/resource not in course'). - '</span>'; - } - } - if ((!$skipdetails) && (ref($intervals) eq 'HASH')) { - if (ref($intervals->{$type}) eq 'HASH') { - $iteminfo .= &trigger_details_toggle($parmcount). - '<ul id="trigdetails_'.$parmcount.'" style="display:none">'; - if ($type eq 'course') { - foreach my $scope (keys(%{$intervals->{$type}})) { - if ($scope eq 'all') { - $iteminfo .= '<li>'.&mt('All users -- time limit: [_1]', - &convlim($intervals->{$type}->{$scope})).'</li>'; - } elsif ($scope eq 'secgrp') { - if (ref($intervals->{$type}->{$scope}) eq 'HASH') { - $iteminfo .= '<li>'.&mt('Sections/groups').'<ul>'; - foreach my $item (sort(keys(%{$intervals->{$type}->{$scope}}))) { - $iteminfo .= '<li>'.&mt('[_1] -- time limit: [_2]',$item, - &convlim($intervals->{$type}->{$scope}->{$item})). - '</li>'; - } - $iteminfo .= '</ul></li>'; - } - } elsif ($scope eq 'users') { - if (ref($intervals->{$type}->{$scope}) eq 'HASH') { - $iteminfo .= '<li>'.&mt('Users').'<ul>'; - foreach my $item (sort(keys(%{$intervals->{$type}->{$scope}}))) { - $iteminfo .= '<li>'.&mt('[_1] -- time limit: [_2]', - &convlim($item,$intervals->{$type}->{$scope}->{$item})). - '</li>'; - } - $iteminfo .= '</ul></li>'; - } - } - } - } elsif (($type eq 'map') || ($type eq 'resource')) { - if (ref($intervals->{$type}->{$item}) eq 'HASH') { - foreach my $scope (keys(%{$intervals->{$type}->{$item}})) { - if ($scope eq 'all') { - $iteminfo .= '<li>'.&mt('All users -- time limit: [_1]', - &convlim($intervals->{$type}->{$item}->{$scope})). - '</li>'; - } elsif ($scope eq 'secgrp') { - if (ref($intervals->{$type}->{$item}->{$scope}) eq 'HASH') { - $iteminfo .= '<li>'.&mt('Sections/groups').'<ul>'; - foreach my $sec (sort(keys(%{$intervals->{$type}->{$item}->{$scope}}))) { - $iteminfo .= '<li>'.&mt('[_1] -- time limit: [_2]',$sec, - &convlim($intervals->{$type}->{$item}->{$scope}->{$sec})). - '</li>'; - } - $iteminfo .= '</ul></li>'; - } - } elsif ($scope eq 'users') { - if (ref($intervals->{$type}->{$item}->{$scope}) eq 'HASH') { - $iteminfo .= '<li>'.&mt('Users').'<ul>'; - foreach my $user (sort(keys(%{$intervals->{$type}->{$item}->{$scope}}))) { - $iteminfo .= '<li>'.&mt('[_1] -- time limit: [_2]',$user, - &convlim($intervals->{$type}->{$item}->{$scope}->{$user})). - '</li>'; - } - $iteminfo .= '</ul></li>'; - } - } - } - } - } - $iteminfo .= '</ul>'; - } - } - $r->print(&create_interval_form($intervals,$parmcount,$navmap,$item,$jschg, - $itemname,$iteminfo).'</fieldset></td>'); + 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).'</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++; } @@ -1222,7 +1237,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 = '<fieldset>'. '<legend>'.$ltext->{'chtr'}.'</legend>'. @@ -1260,7 +1275,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 +1342,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 '') { @@ -1346,9 +1361,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 +1375,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 { @@ -1368,8 +1384,14 @@ sub create_interval_form { $intervalform .= '</label>'; if ($currkey eq 'course') { $intervalform .= $iteminfo; + } elsif ($context eq 'accesstimes') { + (undef,$iteminfo) = &interval_details('course',$type,'',$navmap,$intervals,$counter); + if ($iteminfo) { + $intervalform .= ' '.$iteminfo; + } } $intervalform .= '<br />'; + $counter ++; } elsif ($type eq 'map') { if (ref($intervals->{$type}) eq 'HASH') { if (ref($navmap)) { @@ -1384,7 +1406,7 @@ 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>'.$iteminfo; } else { @@ -1404,8 +1426,15 @@ sub create_interval_form { $intervalform .= &mt('Timer for all items in folder: [_1]', '<i>'.$title.'</i>'). '</label>'.$path; + if ($context eq 'accesstimes') { + (undef,$iteminfo) = &interval_details($map,$type,$map,$navmap,$intervals,$counter); + if ($iteminfo) { + $intervalform .= ' '.$iteminfo; + } + } } $intervalform .= '<br />'; + $counter ++; } } } @@ -1425,14 +1454,15 @@ sub create_interval_form { } $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>'.$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 +1474,19 @@ sub create_interval_form { $intervalform .= &mt('Timer for resource: [_1]','<i>'.$title.'</i>'). '</label>'. $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 .= '<br />'; + $counter ++; } } } @@ -1455,7 +1496,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.').' '. @@ -1473,6 +1514,121 @@ sub trigger_details_toggle { 'style="text-decoration: none;"><b>'.&mt('(More ...)').'</b></a></span>'; } +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]', + '<span style="font-style:italic">'. + $title.'</span>'); + } + } 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]', + '<span style="font-style:italic">'. + $title.'</span>'); + } + } + if (ref($navmap)) { + my $path = &show_timer_path($type,$item); + if ($path) { + $iteminfo = ' <span style="font-size:90%;">'. + &mt('(in: [_1])',$path). + '</span>'; + } + } + } else { + $skipdetails = 1; + $itemname = '<span style="LC_warning">'. + &mt('Timer folder/resource not in course'). + '</span>'; + } + } + if ((!$skipdetails) && (ref($intervals) eq 'HASH') && (ref($intervals->{$type}) eq 'HASH')) { + $iteminfo = &trigger_details_toggle($parmcount). + '<ul id="trigdetails_'.$parmcount.'" style="display:none">'; + if ($type eq 'course') { + foreach my $scope (keys(%{$intervals->{$type}})) { + if ($scope eq 'all') { + $iteminfo .= '<li>'.&mt('All users -- time limit: [_1]', + &convlim($intervals->{$type}->{$scope})).'</li>'; + } elsif ($scope eq 'secgrp') { + if (ref($intervals->{$type}->{$scope}) eq 'HASH') { + $iteminfo .= '<li>'.&mt('Sections/groups').'<ul>'; + foreach my $item (sort(keys(%{$intervals->{$type}->{$scope}}))) { + $iteminfo .= '<li>'.&mt('[_1] -- time limit: [_2]',$item, + &convlim($intervals->{$type}->{$scope}->{$item})). + '</li>'; + } + $iteminfo .= '</ul></li>'; + } + } elsif ($scope eq 'users') { + if (ref($intervals->{$type}->{$scope}) eq 'HASH') { + $iteminfo .= '<li>'.&mt('Users').'<ul>'; + foreach my $item (sort(keys(%{$intervals->{$type}->{$scope}}))) { + $iteminfo .= '<li>'.&mt('[_1] -- time limit: [_2]', + &convlim($item,$intervals->{$type}->{$scope}->{$item})). + '</li>'; + } + $iteminfo .= '</ul></li>'; + } + } + } + } elsif (($type eq 'map') || ($type eq 'resource')) { + if (ref($intervals->{$type}->{$item}) eq 'HASH') { + foreach my $scope (keys(%{$intervals->{$type}->{$item}})) { + if ($scope eq 'all') { + $iteminfo .= '<li>'.&mt('All users -- time limit: [_1]', + &convlim($intervals->{$type}->{$item}->{$scope})). + '</li>'; + } elsif ($scope eq 'secgrp') { + if (ref($intervals->{$type}->{$item}->{$scope}) eq 'HASH') { + $iteminfo .= '<li>'.&mt('Sections/groups').'<ul>'; + foreach my $sec (sort(keys(%{$intervals->{$type}->{$item}->{$scope}}))) { + $iteminfo .= '<li>'.&mt('[_1] -- time limit: [_2]',$sec, + &convlim($intervals->{$type}->{$item}->{$scope}->{$sec})). + '</li>'; + } + $iteminfo .= '</ul></li>'; + } + } elsif ($scope eq 'users') { + if (ref($intervals->{$type}->{$item}->{$scope}) eq 'HASH') { + $iteminfo .= '<li>'.&mt('Users').'<ul>'; + foreach my $user (sort(keys(%{$intervals->{$type}->{$item}->{$scope}}))) { + $iteminfo .= '<li>'.&mt('[_1] -- time limit: [_2]',$user, + &convlim($intervals->{$type}->{$item}->{$scope}->{$user})). + '</li>'; + } + $iteminfo .= '</ul></li>'; + } + } + } + } + } + $iteminfo .= '</ul>'; + } + return ($itemname,$iteminfo); +} + sub show_timer_path { my ($type,$item,$navmap) = @_; return unless(ref($navmap)); @@ -1499,19 +1655,21 @@ sub blocktype_text { 'port' => 'Portfolio', 'groups' => 'Groups', 'blogs' => 'Blogs', + 'about' => 'User Information', 'docs' => 'Content', 'printout' => 'Printouts', + 'passwd' => 'Change Password', + 'grades' => 'Gradebook', + 'search' => 'Content Search', + 'alert' => 'Critical Alert', + 'reinit' => 'Course Re-init', ); - my $typeorder = ['com','chat','boards','port','groups','blogs','printout','docs']; + my $typeorder = ['com','chat','boards','port','groups','blogs','about','printout','docs','grades','search','alert','reinit','passwd']; return ($typeorder,\%types); } sub blockingmenu_javascript { my ($blockcount) = @_; - my %lt = &Apache::lonlocal::texthash ( - more => 'More ...', - less => 'Less ...', - ); return <<ENDSCRIPT; <script type="text/javascript"> // <![CDATA[ @@ -1567,6 +1725,22 @@ function toggleAddModify() { return; } +// ]]> +</script> +ENDSCRIPT + +} + +sub details_javascript { + my %lt = &Apache::lonlocal::texthash ( + more => 'More ...', + less => 'Less ...', + ); + return <<ENDSCRIPT; + +<script type="text/javascript"> +// <![CDATA[ + function showTriggerDetails(item) { document.getElementById('trigdetails_'+item).style.display='block'; document.getElementById('trigdetails_'+item).style.textAlign='left';